blob: e03996ec4f89ebab6a592ad9c9715fcb8f5ffa2d [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
Miao Wang09f11442018-07-10 12:25:46 -070045 // GRALLOC_USAGE_RENDERSCRIPT
46 const uint64_t USAGE_RENDERSCRIPT = 0x00100000U;
47 uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | USAGE_RENDERSCRIPT;
48 media_status_t ret = AImageReader_newWithUsage(
49 width, height, format, usage,
Miao Wangf750c532017-03-03 16:03:44 -080050 mNumAlloc, &mImgReader);
51 if (ret != AMEDIA_OK || mImgReader == nullptr) {
52 ALOGE("Error creating image reader. ret %d", ret);
53 }
54
55 ret = AImageReader_getWindow(mImgReader, &mNativeWindow);
56 if (ret != AMEDIA_OK || mNativeWindow == nullptr) {
57 ALOGE("Error creating native window. ret %d", ret);
58 }
59
60 mReaderCb = {this, GrallocConsumer::onFrameAvailable};
61 ret = AImageReader_setImageListener(mImgReader, &mReaderCb);
62
Miao Wang75474682015-10-26 16:50:13 -070063 for (uint32_t i = 1; i < numAlloc; i++) {
64 isIdxUsed[i] = false;
65 }
Jason Samsddceab92013-08-07 13:02:32 -070066}
67
68GrallocConsumer::~GrallocConsumer() {
Miao Wangf750c532017-03-03 16:03:44 -080069 AImageReader_delete(mImgReader);
Miao Wang75474682015-10-26 16:50:13 -070070 delete[] mAlloc;
71 delete[] mAcquiredBuffer;
72 delete[] isIdxUsed;
Jason Samsddceab92013-08-07 13:02:32 -070073}
74
Miao Wangf750c532017-03-03 16:03:44 -080075void GrallocConsumer::onFrameAvailable(void* obj, AImageReader* reader) {
76 GrallocConsumer* consumer = (GrallocConsumer *) obj;
77 for (uint32_t i = 0; i < consumer->mNumAlloc; i++) {
78 if (consumer->mAlloc[i] != nullptr) {
79 intptr_t ip = (intptr_t)(consumer->mAlloc[i]);
80 consumer->mCtx->sendMessageToClient(&ip,
81 RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true);
82 }
83 }
84}
Jason Samsddceab92013-08-07 13:02:32 -070085
Miao Wangf750c532017-03-03 16:03:44 -080086ANativeWindow* GrallocConsumer::getNativeWindow() {
87 return mNativeWindow;
88}
Jason Samsddceab92013-08-07 13:02:32 -070089
Miao Wangf750c532017-03-03 16:03:44 -080090media_status_t GrallocConsumer::lockNextBuffer(uint32_t idx) {
91 media_status_t ret;
Jason Samsddceab92013-08-07 13:02:32 -070092
Miao Wang75474682015-10-26 16:50:13 -070093 if (idx >= mNumAlloc) {
94 ALOGE("Invalid buffer index: %d", idx);
Miao Wangf750c532017-03-03 16:03:44 -080095 return AMEDIA_ERROR_INVALID_PARAMETER;
Miao Wang75474682015-10-26 16:50:13 -070096 }
97
Miao Wangf750c532017-03-03 16:03:44 -080098 if (mAcquiredBuffer[idx].mImg != nullptr) {
99 ret = unlockBuffer(idx);
100 if (ret != AMEDIA_OK) {
101 return ret;
Jason Samsddceab92013-08-07 13:02:32 -0700102 }
103 }
104
Miao Wangf750c532017-03-03 16:03:44 -0800105 ret = AImageReader_acquireNextImage(mImgReader, &(mAcquiredBuffer[idx].mImg));
106 if (ret != AMEDIA_OK || mAcquiredBuffer[idx].mImg == nullptr) {
107 ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
108 __FUNCTION__, mImgReader, ret, mAcquiredBuffer[idx].mImg);
109 return ret;
Jason Samsddceab92013-08-07 13:02:32 -0700110 }
111
Miao Wangf750c532017-03-03 16:03:44 -0800112 AImage *img = mAcquiredBuffer[idx].mImg;
113 int32_t format = -1;
114 ret = AImage_getFormat(img, &format);
115 if (ret != AMEDIA_OK || format == -1) {
116 ALOGE("%s: get format for image %p failed! ret: %d, format %d",
117 __FUNCTION__, img, ret, format);
118 return ret;
Jason Samsddceab92013-08-07 13:02:32 -0700119 }
120
Miao Wangf750c532017-03-03 16:03:44 -0800121 if (format != AIMAGE_FORMAT_YUV_420_888 && format != AIMAGE_FORMAT_RGBA_8888) {
122 ALOGE("Format %d not supported", format);
123 return AMEDIA_ERROR_INVALID_OBJECT;
Jason Samsddceab92013-08-07 13:02:32 -0700124 }
125
Miao Wangf750c532017-03-03 16:03:44 -0800126 uint8_t *data = nullptr;
127 int dataLength = 0;
128 ret = AImage_getPlaneData(img, 0, &data, &dataLength);
129 if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
130 ALOGE("%s: get data for image %p failed! ret: %d, data %p, len %d",
131 __FUNCTION__, img, ret, data, dataLength);
132 return ret;
133 }
Jason Samsddceab92013-08-07 13:02:32 -0700134
Miao Wangf750c532017-03-03 16:03:44 -0800135 int64_t timestamp = -1;
136 ret = AImage_getTimestamp(img, &timestamp);
137 if (ret != AMEDIA_OK || timestamp == -1) {
138 ALOGE("%s: get timestamp for image %p failed! ret: %d",
139 __FUNCTION__, img, ret);
140 return ret;
141 }
Jason Samsddceab92013-08-07 13:02:32 -0700142
Miao Wangf750c532017-03-03 16:03:44 -0800143 int32_t rowstride = -1;
144 ret = AImage_getPlaneRowStride(img, 0, &rowstride);
145 if (ret != AMEDIA_OK || rowstride == -1) {
146 ALOGE("%s: get row stride for image %p failed! ret: %d, rowstride %d",
147 __FUNCTION__, img, ret, rowstride);
148 return ret;
149 }
Jason Samsddceab92013-08-07 13:02:32 -0700150
Miao Wangc3e57652017-03-24 11:45:47 -0700151 AHardwareBuffer *hardwareBuffer = nullptr;
152 ret = AImage_getHardwareBuffer(img, &hardwareBuffer);
153 if (ret != AMEDIA_OK || hardwareBuffer == nullptr) {
154 ALOGE("%s: get hardware buffer for image %p failed! ret: %d",
155 __FUNCTION__, img, ret);
156 return ret;
157 }
158
Miao Wangf750c532017-03-03 16:03:44 -0800159 mAcquiredBuffer[idx].mBufferPointer = data;
Jason Samsddceab92013-08-07 13:02:32 -0700160
Miao Wangf750c532017-03-03 16:03:44 -0800161 mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = data;
162 mAlloc[idx]->mHal.drvState.lod[0].stride = rowstride;
Miao Wangc3e57652017-03-24 11:45:47 -0700163 mAlloc[idx]->mHal.state.nativeBuffer = hardwareBuffer;
Miao Wangf750c532017-03-03 16:03:44 -0800164 mAlloc[idx]->mHal.state.timestamp = timestamp;
Jason Samsddceab92013-08-07 13:02:32 -0700165
Miao Wangf750c532017-03-03 16:03:44 -0800166 if (format == AIMAGE_FORMAT_YUV_420_888) {
Miao Wang1aaf4fa2015-12-21 17:34:46 +0800167 const int yWidth = mAlloc[idx]->mHal.drvState.lod[0].dimX;
168 const int yHeight = mAlloc[idx]->mHal.drvState.lod[0].dimY;
Jason Samsddceab92013-08-07 13:02:32 -0700169
Miao Wangf750c532017-03-03 16:03:44 -0800170 const int cWidth = yWidth / 2;
171 const int cHeight = yHeight / 2;
Jason Sams61656a72013-09-03 16:21:18 -0700172
Miao Wangf750c532017-03-03 16:03:44 -0800173 uint8_t *uData = nullptr;
174 int uDataLength = 0;
175 ret = AImage_getPlaneData(img, 1, &uData, &uDataLength);
176 if (ret != AMEDIA_OK || uData == nullptr || uDataLength <= 0) {
177 ALOGE("%s: get U data for image %p failed! ret: %d, data %p, len %d",
178 __FUNCTION__, img, ret, uData, uDataLength);
179 return ret;
Miao Wang1aaf4fa2015-12-21 17:34:46 +0800180 }
Miao Wangf750c532017-03-03 16:03:44 -0800181
182 uint8_t *vData = nullptr;
183 int vDataLength = 0;
184 ret = AImage_getPlaneData(img, 2, &vData, &vDataLength);
185 if (ret != AMEDIA_OK || vData == nullptr || vDataLength <= 0) {
186 ALOGE("%s: get V data for image %p failed! ret: %d, data %p, len %d",
187 __FUNCTION__, img, ret, vData, vDataLength);
188 return ret;
189 }
190
191 int32_t uRowStride = -1;
192 ret = AImage_getPlaneRowStride(img, 1, &uRowStride);
193 if (ret != AMEDIA_OK || uRowStride == -1) {
194 ALOGE("%s: get U row stride for image %p failed! ret: %d, uRowStride %d",
195 __FUNCTION__, img, ret, uRowStride);
196 return ret;
197 }
198
199 int32_t vRowStride = -1;
200 ret = AImage_getPlaneRowStride(img, 2, &vRowStride);
201 if (ret != AMEDIA_OK || vRowStride == -1) {
202 ALOGE("%s: get V row stride for image %p failed! ret: %d, vRowStride %d",
203 __FUNCTION__, img, ret, vRowStride);
204 return ret;
205 }
206
207 int32_t uPixStride = -1;
208 ret = AImage_getPlanePixelStride(img, 1, &uPixStride);
209 if (ret != AMEDIA_OK || uPixStride == -1) {
210 ALOGE("%s: get U pixel stride for image %p failed! ret: %d, uPixStride %d",
211 __FUNCTION__, img, ret, uPixStride);
212 return ret;
213 }
214
215 mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
216 mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
217 mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
218 mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
219
220 mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = uData;
221 mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = vData;
222
223 mAlloc[idx]->mHal.drvState.lod[1].stride = uRowStride;
224 mAlloc[idx]->mHal.drvState.lod[2].stride = vRowStride;
225
226 mAlloc[idx]->mHal.drvState.yuv.shift = 1;
227 mAlloc[idx]->mHal.drvState.yuv.step = uPixStride;
228 mAlloc[idx]->mHal.drvState.lodCount = 3;
Jason Samsddceab92013-08-07 13:02:32 -0700229 }
230
Miao Wangf750c532017-03-03 16:03:44 -0800231 return AMEDIA_OK;
Jason Samsddceab92013-08-07 13:02:32 -0700232}
233
Miao Wangf750c532017-03-03 16:03:44 -0800234media_status_t GrallocConsumer::unlockBuffer(uint32_t idx) {
235 media_status_t ret;
Jason Samsddceab92013-08-07 13:02:32 -0700236
Miao Wang75474682015-10-26 16:50:13 -0700237 if (idx >= mNumAlloc) {
238 ALOGE("Invalid buffer index: %d", idx);
Miao Wangf750c532017-03-03 16:03:44 -0800239 return AMEDIA_ERROR_INVALID_PARAMETER;
Miao Wang75474682015-10-26 16:50:13 -0700240 }
Miao Wangf750c532017-03-03 16:03:44 -0800241 if (mAcquiredBuffer[idx].mImg == nullptr) {
242 return AMEDIA_OK;
Miao Wang75474682015-10-26 16:50:13 -0700243 }
244
Miao Wangf750c532017-03-03 16:03:44 -0800245 AImage_delete(mAcquiredBuffer[idx].mImg);
246 mAcquiredBuffer[idx].mImg = nullptr;
247 return AMEDIA_OK;
Jason Samsddceab92013-08-07 13:02:32 -0700248}
249
Miao Wang75474682015-10-26 16:50:13 -0700250uint32_t GrallocConsumer::getNextAvailableIdx(Allocation *a) {
251 for (uint32_t i = 0; i < mNumAlloc; i++) {
252 if (isIdxUsed[i] == false) {
253 mAlloc[i] = a;
254 isIdxUsed[i] = true;
255 return i;
256 }
257 }
258 return mNumAlloc;
259}
260
261bool GrallocConsumer::releaseIdx(uint32_t idx) {
262 if (idx >= mNumAlloc) {
263 ALOGE("Invalid buffer index: %d", idx);
264 return false;
265 }
266 if (isIdxUsed[idx] == false) {
267 ALOGV("Buffer index already released: %d", idx);
268 return true;
269 }
Miao Wangf750c532017-03-03 16:03:44 -0800270 media_status_t ret;
271 ret = unlockBuffer(idx);
272 if (ret != OK) {
Miao Wang75474682015-10-26 16:50:13 -0700273 ALOGE("Unable to unlock graphic buffer");
274 return false;
275 }
276 mAlloc[idx] = nullptr;
277 isIdxUsed[idx] = false;
278 return true;
279}
280
Miao Wangf750c532017-03-03 16:03:44 -0800281bool GrallocConsumer::isActive() {
282 for (uint32_t i = 0; i < mNumAlloc; i++) {
283 if (isIdxUsed[i]) {
284 return true;
285 }
286 }
287 return false;
288}
289
Jason Samsddceab92013-08-07 13:02:32 -0700290} // namespace renderscript
291} // namespace android