rsGrallocConsumer.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  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. #include "rsAllocation.h"
  17. #include "rsContext.h"
  18. #include "rsGrallocConsumer.h"
  19. #include "rs_hal.h"
  20. namespace android {
  21. namespace renderscript {
  22. GrallocConsumer::GrallocConsumer (const Context *rsc, Allocation *a, uint32_t numAlloc)
  23. {
  24. mCtx = rsc;
  25. mAlloc = new Allocation *[numAlloc];
  26. mAcquiredBuffer = new AcquiredBuffer[numAlloc];
  27. isIdxUsed = new bool[numAlloc];
  28. mAlloc[0] = a;
  29. isIdxUsed[0] = true;
  30. mNumAlloc = numAlloc;
  31. uint32_t width = a->mHal.drvState.lod[0].dimX;
  32. uint32_t height = a->mHal.drvState.lod[0].dimY;
  33. if (height < 1) height = 1;
  34. int32_t format = AIMAGE_FORMAT_RGBA_8888;
  35. if (a->mHal.state.yuv) {
  36. format = AIMAGE_FORMAT_YUV_420_888;
  37. }
  38. // GRALLOC_USAGE_RENDERSCRIPT
  39. const uint64_t USAGE_RENDERSCRIPT = 0x00100000U;
  40. uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | USAGE_RENDERSCRIPT;
  41. media_status_t ret = AImageReader_newWithUsage(
  42. width, height, format, usage,
  43. mNumAlloc, &mImgReader);
  44. if (ret != AMEDIA_OK || mImgReader == nullptr) {
  45. ALOGE("Error creating image reader. ret %d", ret);
  46. }
  47. ret = AImageReader_getWindow(mImgReader, &mNativeWindow);
  48. if (ret != AMEDIA_OK || mNativeWindow == nullptr) {
  49. ALOGE("Error creating native window. ret %d", ret);
  50. }
  51. mReaderCb = {this, GrallocConsumer::onFrameAvailable};
  52. ret = AImageReader_setImageListener(mImgReader, &mReaderCb);
  53. for (uint32_t i = 1; i < numAlloc; i++) {
  54. isIdxUsed[i] = false;
  55. }
  56. }
  57. GrallocConsumer::~GrallocConsumer() {
  58. AImageReader_delete(mImgReader);
  59. delete[] mAlloc;
  60. delete[] mAcquiredBuffer;
  61. delete[] isIdxUsed;
  62. }
  63. void GrallocConsumer::onFrameAvailable(void* obj, AImageReader* reader) {
  64. GrallocConsumer* consumer = (GrallocConsumer *) obj;
  65. for (uint32_t i = 0; i < consumer->mNumAlloc; i++) {
  66. if (consumer->mAlloc[i] != nullptr) {
  67. intptr_t ip = (intptr_t)(consumer->mAlloc[i]);
  68. consumer->mCtx->sendMessageToClient(&ip,
  69. RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true);
  70. }
  71. }
  72. }
  73. ANativeWindow* GrallocConsumer::getNativeWindow() {
  74. return mNativeWindow;
  75. }
  76. media_status_t GrallocConsumer::lockNextBuffer(uint32_t idx) {
  77. media_status_t ret;
  78. if (idx >= mNumAlloc) {
  79. ALOGE("Invalid buffer index: %d", idx);
  80. return AMEDIA_ERROR_INVALID_PARAMETER;
  81. }
  82. if (mAcquiredBuffer[idx].mImg != nullptr) {
  83. ret = unlockBuffer(idx);
  84. if (ret != AMEDIA_OK) {
  85. return ret;
  86. }
  87. }
  88. ret = AImageReader_acquireNextImage(mImgReader, &(mAcquiredBuffer[idx].mImg));
  89. if (ret != AMEDIA_OK || mAcquiredBuffer[idx].mImg == nullptr) {
  90. ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
  91. __FUNCTION__, mImgReader, ret, mAcquiredBuffer[idx].mImg);
  92. return ret;
  93. }
  94. AImage *img = mAcquiredBuffer[idx].mImg;
  95. int32_t format = -1;
  96. ret = AImage_getFormat(img, &format);
  97. if (ret != AMEDIA_OK || format == -1) {
  98. ALOGE("%s: get format for image %p failed! ret: %d, format %d",
  99. __FUNCTION__, img, ret, format);
  100. return ret;
  101. }
  102. if (format != AIMAGE_FORMAT_YUV_420_888 && format != AIMAGE_FORMAT_RGBA_8888) {
  103. ALOGE("Format %d not supported", format);
  104. return AMEDIA_ERROR_INVALID_OBJECT;
  105. }
  106. uint8_t *data = nullptr;
  107. int dataLength = 0;
  108. ret = AImage_getPlaneData(img, 0, &data, &dataLength);
  109. if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
  110. ALOGE("%s: get data for image %p failed! ret: %d, data %p, len %d",
  111. __FUNCTION__, img, ret, data, dataLength);
  112. return ret;
  113. }
  114. int64_t timestamp = -1;
  115. ret = AImage_getTimestamp(img, &timestamp);
  116. if (ret != AMEDIA_OK || timestamp == -1) {
  117. ALOGE("%s: get timestamp for image %p failed! ret: %d",
  118. __FUNCTION__, img, ret);
  119. return ret;
  120. }
  121. int32_t rowstride = -1;
  122. ret = AImage_getPlaneRowStride(img, 0, &rowstride);
  123. if (ret != AMEDIA_OK || rowstride == -1) {
  124. ALOGE("%s: get row stride for image %p failed! ret: %d, rowstride %d",
  125. __FUNCTION__, img, ret, rowstride);
  126. return ret;
  127. }
  128. AHardwareBuffer *hardwareBuffer = nullptr;
  129. ret = AImage_getHardwareBuffer(img, &hardwareBuffer);
  130. if (ret != AMEDIA_OK || hardwareBuffer == nullptr) {
  131. ALOGE("%s: get hardware buffer for image %p failed! ret: %d",
  132. __FUNCTION__, img, ret);
  133. return ret;
  134. }
  135. mAcquiredBuffer[idx].mBufferPointer = data;
  136. mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = data;
  137. mAlloc[idx]->mHal.drvState.lod[0].stride = rowstride;
  138. mAlloc[idx]->mHal.state.nativeBuffer = hardwareBuffer;
  139. mAlloc[idx]->mHal.state.timestamp = timestamp;
  140. if (format == AIMAGE_FORMAT_YUV_420_888) {
  141. const int yWidth = mAlloc[idx]->mHal.drvState.lod[0].dimX;
  142. const int yHeight = mAlloc[idx]->mHal.drvState.lod[0].dimY;
  143. const int cWidth = yWidth / 2;
  144. const int cHeight = yHeight / 2;
  145. uint8_t *uData = nullptr;
  146. int uDataLength = 0;
  147. ret = AImage_getPlaneData(img, 1, &uData, &uDataLength);
  148. if (ret != AMEDIA_OK || uData == nullptr || uDataLength <= 0) {
  149. ALOGE("%s: get U data for image %p failed! ret: %d, data %p, len %d",
  150. __FUNCTION__, img, ret, uData, uDataLength);
  151. return ret;
  152. }
  153. uint8_t *vData = nullptr;
  154. int vDataLength = 0;
  155. ret = AImage_getPlaneData(img, 2, &vData, &vDataLength);
  156. if (ret != AMEDIA_OK || vData == nullptr || vDataLength <= 0) {
  157. ALOGE("%s: get V data for image %p failed! ret: %d, data %p, len %d",
  158. __FUNCTION__, img, ret, vData, vDataLength);
  159. return ret;
  160. }
  161. int32_t uRowStride = -1;
  162. ret = AImage_getPlaneRowStride(img, 1, &uRowStride);
  163. if (ret != AMEDIA_OK || uRowStride == -1) {
  164. ALOGE("%s: get U row stride for image %p failed! ret: %d, uRowStride %d",
  165. __FUNCTION__, img, ret, uRowStride);
  166. return ret;
  167. }
  168. int32_t vRowStride = -1;
  169. ret = AImage_getPlaneRowStride(img, 2, &vRowStride);
  170. if (ret != AMEDIA_OK || vRowStride == -1) {
  171. ALOGE("%s: get V row stride for image %p failed! ret: %d, vRowStride %d",
  172. __FUNCTION__, img, ret, vRowStride);
  173. return ret;
  174. }
  175. int32_t uPixStride = -1;
  176. ret = AImage_getPlanePixelStride(img, 1, &uPixStride);
  177. if (ret != AMEDIA_OK || uPixStride == -1) {
  178. ALOGE("%s: get U pixel stride for image %p failed! ret: %d, uPixStride %d",
  179. __FUNCTION__, img, ret, uPixStride);
  180. return ret;
  181. }
  182. mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
  183. mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
  184. mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
  185. mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
  186. mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = uData;
  187. mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = vData;
  188. mAlloc[idx]->mHal.drvState.lod[1].stride = uRowStride;
  189. mAlloc[idx]->mHal.drvState.lod[2].stride = vRowStride;
  190. mAlloc[idx]->mHal.drvState.yuv.shift = 1;
  191. mAlloc[idx]->mHal.drvState.yuv.step = uPixStride;
  192. mAlloc[idx]->mHal.drvState.lodCount = 3;
  193. }
  194. return AMEDIA_OK;
  195. }
  196. media_status_t GrallocConsumer::unlockBuffer(uint32_t idx) {
  197. media_status_t ret;
  198. if (idx >= mNumAlloc) {
  199. ALOGE("Invalid buffer index: %d", idx);
  200. return AMEDIA_ERROR_INVALID_PARAMETER;
  201. }
  202. if (mAcquiredBuffer[idx].mImg == nullptr) {
  203. return AMEDIA_OK;
  204. }
  205. AImage_delete(mAcquiredBuffer[idx].mImg);
  206. mAcquiredBuffer[idx].mImg = nullptr;
  207. return AMEDIA_OK;
  208. }
  209. uint32_t GrallocConsumer::getNextAvailableIdx(Allocation *a) {
  210. for (uint32_t i = 0; i < mNumAlloc; i++) {
  211. if (isIdxUsed[i] == false) {
  212. mAlloc[i] = a;
  213. isIdxUsed[i] = true;
  214. return i;
  215. }
  216. }
  217. return mNumAlloc;
  218. }
  219. bool GrallocConsumer::releaseIdx(uint32_t idx) {
  220. if (idx >= mNumAlloc) {
  221. ALOGE("Invalid buffer index: %d", idx);
  222. return false;
  223. }
  224. if (isIdxUsed[idx] == false) {
  225. ALOGV("Buffer index already released: %d", idx);
  226. return true;
  227. }
  228. media_status_t ret;
  229. ret = unlockBuffer(idx);
  230. if (ret != OK) {
  231. ALOGE("Unable to unlock graphic buffer");
  232. return false;
  233. }
  234. mAlloc[idx] = nullptr;
  235. isIdxUsed[idx] = false;
  236. return true;
  237. }
  238. bool GrallocConsumer::isActive() {
  239. for (uint32_t i = 0; i < mNumAlloc; i++) {
  240. if (isIdxUsed[i]) {
  241. return true;
  242. }
  243. }
  244. return false;
  245. }
  246. } // namespace renderscript
  247. } // namespace android