blob: fed7b4868832758b8ac23517dd8922a60afadc3c [file] [log] [blame]
Jason Samsddceab92013-08-07 13:02:32 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jason Samsddceab92013-08-07 13:02:32 -070017#include "rsAllocation.h"
Miao Wangf750c532017-03-03 16:03:44 -080018#include "rsContext.h"
Jason Samsddceab92013-08-07 13:02:32 -070019#include "rsGrallocConsumer.h"
Miao Wangf750c532017-03-03 16:03:44 -080020#include "rs_hal.h"
Jason Samsddceab92013-08-07 13:02:32 -070021
22namespace android {
23namespace renderscript {
24
Miao Wangf750c532017-03-03 16:03:44 -080025GrallocConsumer::GrallocConsumer (const Context *rsc, Allocation *a, uint32_t numAlloc)
Jason Samsddceab92013-08-07 13:02:32 -070026{
Miao Wangf750c532017-03-03 16:03:44 -080027 mCtx = rsc;
Miao Wang75474682015-10-26 16:50:13 -070028 mAlloc = new Allocation *[numAlloc];
29 mAcquiredBuffer = new AcquiredBuffer[numAlloc];
30 isIdxUsed = new bool[numAlloc];
31
32 mAlloc[0] = a;
33 isIdxUsed[0] = true;
34 mNumAlloc = numAlloc;
Jason Samsddceab92013-08-07 13:02:32 -070035
Miao Wangf750c532017-03-03 16:03:44 -080036 uint32_t width = a->mHal.drvState.lod[0].dimX;
37 uint32_t height = a->mHal.drvState.lod[0].dimY;
38 if (height < 1) height = 1;
Jason Samsddceab92013-08-07 13:02:32 -070039
Miao Wangf750c532017-03-03 16:03:44 -080040 int32_t format = AIMAGE_FORMAT_RGBA_8888;
Jason Sams61656a72013-09-03 16:21:18 -070041 if (a->mHal.state.yuv) {
Miao Wangf750c532017-03-03 16:03:44 -080042 format = AIMAGE_FORMAT_YUV_420_888;
Jason Sams61656a72013-09-03 16:21:18 -070043 }
Miao Wangf750c532017-03-03 16:03:44 -080044
45 media_status_t ret = AImageReader_new(
46 width, height, format,
47 mNumAlloc, &mImgReader);
48 if (ret != AMEDIA_OK || mImgReader == nullptr) {
49 ALOGE("Error creating image reader. ret %d", ret);
50 }
51
52 ret = AImageReader_getWindow(mImgReader, &mNativeWindow);
53 if (ret != AMEDIA_OK || mNativeWindow == nullptr) {
54 ALOGE("Error creating native window. ret %d", ret);
55 }
56
57 mReaderCb = {this, GrallocConsumer::onFrameAvailable};
58 ret = AImageReader_setImageListener(mImgReader, &mReaderCb);
59
Miao Wang75474682015-10-26 16:50:13 -070060 for (uint32_t i = 1; i < numAlloc; i++) {
61 isIdxUsed[i] = false;
62 }
Jason Samsddceab92013-08-07 13:02:32 -070063}
64
65GrallocConsumer::~GrallocConsumer() {
Miao Wangf750c532017-03-03 16:03:44 -080066 AImageReader_delete(mImgReader);
Miao Wang75474682015-10-26 16:50:13 -070067 delete[] mAlloc;
68 delete[] mAcquiredBuffer;
69 delete[] isIdxUsed;
Jason Samsddceab92013-08-07 13:02:32 -070070}
71
Miao Wangf750c532017-03-03 16:03:44 -080072void GrallocConsumer::onFrameAvailable(void* obj, AImageReader* reader) {
73 GrallocConsumer* consumer = (GrallocConsumer *) obj;
74 for (uint32_t i = 0; i < consumer->mNumAlloc; i++) {
75 if (consumer->mAlloc[i] != nullptr) {
76 intptr_t ip = (intptr_t)(consumer->mAlloc[i]);
77 consumer->mCtx->sendMessageToClient(&ip,
78 RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true);
79 }
80 }
81}
Jason Samsddceab92013-08-07 13:02:32 -070082
Miao Wangf750c532017-03-03 16:03:44 -080083ANativeWindow* GrallocConsumer::getNativeWindow() {
84 return mNativeWindow;
85}
Jason Samsddceab92013-08-07 13:02:32 -070086
Miao Wangf750c532017-03-03 16:03:44 -080087media_status_t GrallocConsumer::lockNextBuffer(uint32_t idx) {
88 media_status_t ret;
Jason Samsddceab92013-08-07 13:02:32 -070089
Miao Wang75474682015-10-26 16:50:13 -070090 if (idx >= mNumAlloc) {
91 ALOGE("Invalid buffer index: %d", idx);
Miao Wangf750c532017-03-03 16:03:44 -080092 return AMEDIA_ERROR_INVALID_PARAMETER;
Miao Wang75474682015-10-26 16:50:13 -070093 }
94
Miao Wangf750c532017-03-03 16:03:44 -080095 if (mAcquiredBuffer[idx].mImg != nullptr) {
96 ret = unlockBuffer(idx);
97 if (ret != AMEDIA_OK) {
98 return ret;
Jason Samsddceab92013-08-07 13:02:32 -070099 }
100 }
101
Miao Wangf750c532017-03-03 16:03:44 -0800102 ret = AImageReader_acquireNextImage(mImgReader, &(mAcquiredBuffer[idx].mImg));
103 if (ret != AMEDIA_OK || mAcquiredBuffer[idx].mImg == nullptr) {
104 ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
105 __FUNCTION__, mImgReader, ret, mAcquiredBuffer[idx].mImg);
106 return ret;
Jason Samsddceab92013-08-07 13:02:32 -0700107 }
108
Miao Wangf750c532017-03-03 16:03:44 -0800109 AImage *img = mAcquiredBuffer[idx].mImg;
110 int32_t format = -1;
111 ret = AImage_getFormat(img, &format);
112 if (ret != AMEDIA_OK || format == -1) {
113 ALOGE("%s: get format for image %p failed! ret: %d, format %d",
114 __FUNCTION__, img, ret, format);
115 return ret;
Jason Samsddceab92013-08-07 13:02:32 -0700116 }
117
Miao Wangf750c532017-03-03 16:03:44 -0800118 if (format != AIMAGE_FORMAT_YUV_420_888 && format != AIMAGE_FORMAT_RGBA_8888) {
119 ALOGE("Format %d not supported", format);
120 return AMEDIA_ERROR_INVALID_OBJECT;
Jason Samsddceab92013-08-07 13:02:32 -0700121 }
122
Miao Wangf750c532017-03-03 16:03:44 -0800123 uint8_t *data = nullptr;
124 int dataLength = 0;
125 ret = AImage_getPlaneData(img, 0, &data, &dataLength);
126 if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
127 ALOGE("%s: get data for image %p failed! ret: %d, data %p, len %d",
128 __FUNCTION__, img, ret, data, dataLength);
129 return ret;
130 }
Jason Samsddceab92013-08-07 13:02:32 -0700131
Miao Wangf750c532017-03-03 16:03:44 -0800132 int64_t timestamp = -1;
133 ret = AImage_getTimestamp(img, &timestamp);
134 if (ret != AMEDIA_OK || timestamp == -1) {
135 ALOGE("%s: get timestamp for image %p failed! ret: %d",
136 __FUNCTION__, img, ret);
137 return ret;
138 }
Jason Samsddceab92013-08-07 13:02:32 -0700139
Miao Wangf750c532017-03-03 16:03:44 -0800140 int32_t rowstride = -1;
141 ret = AImage_getPlaneRowStride(img, 0, &rowstride);
142 if (ret != AMEDIA_OK || rowstride == -1) {
143 ALOGE("%s: get row stride for image %p failed! ret: %d, rowstride %d",
144 __FUNCTION__, img, ret, rowstride);
145 return ret;
146 }
Jason Samsddceab92013-08-07 13:02:32 -0700147
Miao Wangc3e57652017-03-24 11:45:47 -0700148 AHardwareBuffer *hardwareBuffer = nullptr;
149 ret = AImage_getHardwareBuffer(img, &hardwareBuffer);
150 if (ret != AMEDIA_OK || hardwareBuffer == nullptr) {
151 ALOGE("%s: get hardware buffer for image %p failed! ret: %d",
152 __FUNCTION__, img, ret);
153 return ret;
154 }
155
Miao Wangf750c532017-03-03 16:03:44 -0800156 mAcquiredBuffer[idx].mBufferPointer = data;
Jason Samsddceab92013-08-07 13:02:32 -0700157
Miao Wangf750c532017-03-03 16:03:44 -0800158 mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = data;
159 mAlloc[idx]->mHal.drvState.lod[0].stride = rowstride;
Miao Wangc3e57652017-03-24 11:45:47 -0700160 mAlloc[idx]->mHal.state.nativeBuffer = hardwareBuffer;
Miao Wangf750c532017-03-03 16:03:44 -0800161 mAlloc[idx]->mHal.state.timestamp = timestamp;
Jason Samsddceab92013-08-07 13:02:32 -0700162
Miao Wangf750c532017-03-03 16:03:44 -0800163 if (format == AIMAGE_FORMAT_YUV_420_888) {
Miao Wang1aaf4fa2015-12-21 17:34:46 +0800164 const int yWidth = mAlloc[idx]->mHal.drvState.lod[0].dimX;
165 const int yHeight = mAlloc[idx]->mHal.drvState.lod[0].dimY;
Jason Samsddceab92013-08-07 13:02:32 -0700166
Miao Wangf750c532017-03-03 16:03:44 -0800167 const int cWidth = yWidth / 2;
168 const int cHeight = yHeight / 2;
Jason Sams61656a72013-09-03 16:21:18 -0700169
Miao Wangf750c532017-03-03 16:03:44 -0800170 uint8_t *uData = nullptr;
171 int uDataLength = 0;
172 ret = AImage_getPlaneData(img, 1, &uData, &uDataLength);
173 if (ret != AMEDIA_OK || uData == nullptr || uDataLength <= 0) {
174 ALOGE("%s: get U data for image %p failed! ret: %d, data %p, len %d",
175 __FUNCTION__, img, ret, uData, uDataLength);
176 return ret;
Miao Wang1aaf4fa2015-12-21 17:34:46 +0800177 }
Miao Wangf750c532017-03-03 16:03:44 -0800178
179 uint8_t *vData = nullptr;
180 int vDataLength = 0;
181 ret = AImage_getPlaneData(img, 2, &vData, &vDataLength);
182 if (ret != AMEDIA_OK || vData == nullptr || vDataLength <= 0) {
183 ALOGE("%s: get V data for image %p failed! ret: %d, data %p, len %d",
184 __FUNCTION__, img, ret, vData, vDataLength);
185 return ret;
186 }
187
188 int32_t uRowStride = -1;
189 ret = AImage_getPlaneRowStride(img, 1, &uRowStride);
190 if (ret != AMEDIA_OK || uRowStride == -1) {
191 ALOGE("%s: get U row stride for image %p failed! ret: %d, uRowStride %d",
192 __FUNCTION__, img, ret, uRowStride);
193 return ret;
194 }
195
196 int32_t vRowStride = -1;
197 ret = AImage_getPlaneRowStride(img, 2, &vRowStride);
198 if (ret != AMEDIA_OK || vRowStride == -1) {
199 ALOGE("%s: get V row stride for image %p failed! ret: %d, vRowStride %d",
200 __FUNCTION__, img, ret, vRowStride);
201 return ret;
202 }
203
204 int32_t uPixStride = -1;
205 ret = AImage_getPlanePixelStride(img, 1, &uPixStride);
206 if (ret != AMEDIA_OK || uPixStride == -1) {
207 ALOGE("%s: get U pixel stride for image %p failed! ret: %d, uPixStride %d",
208 __FUNCTION__, img, ret, uPixStride);
209 return ret;
210 }
211
212 mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
213 mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
214 mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
215 mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
216
217 mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = uData;
218 mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = vData;
219
220 mAlloc[idx]->mHal.drvState.lod[1].stride = uRowStride;
221 mAlloc[idx]->mHal.drvState.lod[2].stride = vRowStride;
222
223 mAlloc[idx]->mHal.drvState.yuv.shift = 1;
224 mAlloc[idx]->mHal.drvState.yuv.step = uPixStride;
225 mAlloc[idx]->mHal.drvState.lodCount = 3;
Jason Samsddceab92013-08-07 13:02:32 -0700226 }
227
Miao Wangf750c532017-03-03 16:03:44 -0800228 return AMEDIA_OK;
Jason Samsddceab92013-08-07 13:02:32 -0700229}
230
Miao Wangf750c532017-03-03 16:03:44 -0800231media_status_t GrallocConsumer::unlockBuffer(uint32_t idx) {
232 media_status_t ret;
Jason Samsddceab92013-08-07 13:02:32 -0700233
Miao Wang75474682015-10-26 16:50:13 -0700234 if (idx >= mNumAlloc) {
235 ALOGE("Invalid buffer index: %d", idx);
Miao Wangf750c532017-03-03 16:03:44 -0800236 return AMEDIA_ERROR_INVALID_PARAMETER;
Miao Wang75474682015-10-26 16:50:13 -0700237 }
Miao Wangf750c532017-03-03 16:03:44 -0800238 if (mAcquiredBuffer[idx].mImg == nullptr) {
239 return AMEDIA_OK;
Miao Wang75474682015-10-26 16:50:13 -0700240 }
241
Miao Wangf750c532017-03-03 16:03:44 -0800242 AImage_delete(mAcquiredBuffer[idx].mImg);
243 mAcquiredBuffer[idx].mImg = nullptr;
244 return AMEDIA_OK;
Jason Samsddceab92013-08-07 13:02:32 -0700245}
246
Miao Wang75474682015-10-26 16:50:13 -0700247uint32_t GrallocConsumer::getNextAvailableIdx(Allocation *a) {
248 for (uint32_t i = 0; i < mNumAlloc; i++) {
249 if (isIdxUsed[i] == false) {
250 mAlloc[i] = a;
251 isIdxUsed[i] = true;
252 return i;
253 }
254 }
255 return mNumAlloc;
256}
257
258bool GrallocConsumer::releaseIdx(uint32_t idx) {
259 if (idx >= mNumAlloc) {
260 ALOGE("Invalid buffer index: %d", idx);
261 return false;
262 }
263 if (isIdxUsed[idx] == false) {
264 ALOGV("Buffer index already released: %d", idx);
265 return true;
266 }
Miao Wangf750c532017-03-03 16:03:44 -0800267 media_status_t ret;
268 ret = unlockBuffer(idx);
269 if (ret != OK) {
Miao Wang75474682015-10-26 16:50:13 -0700270 ALOGE("Unable to unlock graphic buffer");
271 return false;
272 }
273 mAlloc[idx] = nullptr;
274 isIdxUsed[idx] = false;
275 return true;
276}
277
Miao Wangf750c532017-03-03 16:03:44 -0800278bool GrallocConsumer::isActive() {
279 for (uint32_t i = 0; i < mNumAlloc; i++) {
280 if (isIdxUsed[i]) {
281 return true;
282 }
283 }
284 return false;
285}
286
Jason Samsddceab92013-08-07 13:02:32 -0700287} // namespace renderscript
288} // namespace android