GLConsumer.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. /*
  2. * Copyright (C) 2010 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. #define LOG_TAG "GLConsumer"
  17. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  18. //#define LOG_NDEBUG 0
  19. #define GL_GLEXT_PROTOTYPES
  20. #define EGL_EGLEXT_PROTOTYPES
  21. #include <EGL/egl.h>
  22. #include <EGL/eglext.h>
  23. #include <GLES2/gl2.h>
  24. #include <GLES2/gl2ext.h>
  25. #include <cutils/compiler.h>
  26. #include <hardware/hardware.h>
  27. #include <gui/BufferItem.h>
  28. #include <gui/GLConsumer.h>
  29. #include <gui/IGraphicBufferAlloc.h>
  30. #include <gui/ISurfaceComposer.h>
  31. #include <gui/SurfaceComposerClient.h>
  32. #include <private/gui/ComposerService.h>
  33. #include <private/gui/SyncFeatures.h>
  34. #include <utils/Log.h>
  35. #include <utils/String8.h>
  36. #include <utils/Trace.h>
  37. EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
  38. #define CROP_EXT_STR "EGL_ANDROID_image_crop"
  39. namespace android {
  40. // Macros for including the GLConsumer name in log messages
  41. #define GLC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
  42. #define GLC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
  43. //#define GLC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
  44. #define GLC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
  45. #define GLC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
  46. static const struct {
  47. uint32_t width, height;
  48. char const* bits;
  49. } kDebugData = { 15, 12,
  50. "_______________"
  51. "_______________"
  52. "_____XX_XX_____"
  53. "__X_X_____X_X__"
  54. "__X_XXXXXXX_X__"
  55. "__XXXXXXXXXXX__"
  56. "___XX_XXX_XX___"
  57. "____XXXXXXX____"
  58. "_____X___X_____"
  59. "____X_____X____"
  60. "_______________"
  61. "_______________"
  62. };
  63. // Transform matrices
  64. static float mtxIdentity[16] = {
  65. 1, 0, 0, 0,
  66. 0, 1, 0, 0,
  67. 0, 0, 1, 0,
  68. 0, 0, 0, 1,
  69. };
  70. static float mtxFlipH[16] = {
  71. -1, 0, 0, 0,
  72. 0, 1, 0, 0,
  73. 0, 0, 1, 0,
  74. 1, 0, 0, 1,
  75. };
  76. static float mtxFlipV[16] = {
  77. 1, 0, 0, 0,
  78. 0, -1, 0, 0,
  79. 0, 0, 1, 0,
  80. 0, 1, 0, 1,
  81. };
  82. static float mtxRot90[16] = {
  83. 0, 1, 0, 0,
  84. -1, 0, 0, 0,
  85. 0, 0, 1, 0,
  86. 1, 0, 0, 1,
  87. };
  88. static void mtxMul(float out[16], const float a[16], const float b[16]);
  89. Mutex GLConsumer::sStaticInitLock;
  90. sp<GraphicBuffer> GLConsumer::sReleasedTexImageBuffer;
  91. static bool hasEglAndroidImageCropImpl() {
  92. EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  93. const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS);
  94. size_t cropExtLen = strlen(CROP_EXT_STR);
  95. size_t extsLen = strlen(exts);
  96. bool equal = !strcmp(CROP_EXT_STR, exts);
  97. bool atStart = !strncmp(CROP_EXT_STR " ", exts, cropExtLen+1);
  98. bool atEnd = (cropExtLen+1) < extsLen &&
  99. !strcmp(" " CROP_EXT_STR, exts + extsLen - (cropExtLen+1));
  100. bool inMiddle = strstr(exts, " " CROP_EXT_STR " ");
  101. return equal || atStart || atEnd || inMiddle;
  102. }
  103. static bool hasEglAndroidImageCrop() {
  104. // Only compute whether the extension is present once the first time this
  105. // function is called.
  106. static bool hasIt = hasEglAndroidImageCropImpl();
  107. return hasIt;
  108. }
  109. static bool isEglImageCroppable(const Rect& crop) {
  110. return hasEglAndroidImageCrop() && (crop.left == 0 && crop.top == 0);
  111. }
  112. GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
  113. uint32_t texTarget, bool useFenceSync, bool isControlledByApp) :
  114. ConsumerBase(bq, isControlledByApp),
  115. mCurrentTransform(0),
  116. mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
  117. mCurrentFence(Fence::NO_FENCE),
  118. mCurrentTimestamp(0),
  119. mCurrentFrameNumber(0),
  120. mDefaultWidth(1),
  121. mDefaultHeight(1),
  122. mFilteringEnabled(true),
  123. mTexName(tex),
  124. mUseFenceSync(useFenceSync),
  125. mTexTarget(texTarget),
  126. mEglDisplay(EGL_NO_DISPLAY),
  127. mEglContext(EGL_NO_CONTEXT),
  128. mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
  129. mAttached(true)
  130. {
  131. GLC_LOGV("GLConsumer");
  132. memcpy(mCurrentTransformMatrix, mtxIdentity,
  133. sizeof(mCurrentTransformMatrix));
  134. mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
  135. }
  136. GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget,
  137. bool useFenceSync, bool isControlledByApp) :
  138. ConsumerBase(bq, isControlledByApp),
  139. mCurrentTransform(0),
  140. mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
  141. mCurrentFence(Fence::NO_FENCE),
  142. mCurrentTimestamp(0),
  143. mCurrentFrameNumber(0),
  144. mDefaultWidth(1),
  145. mDefaultHeight(1),
  146. mFilteringEnabled(true),
  147. mTexName(0),
  148. mUseFenceSync(useFenceSync),
  149. mTexTarget(texTarget),
  150. mEglDisplay(EGL_NO_DISPLAY),
  151. mEglContext(EGL_NO_CONTEXT),
  152. mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
  153. mAttached(false)
  154. {
  155. GLC_LOGV("GLConsumer");
  156. memcpy(mCurrentTransformMatrix, mtxIdentity,
  157. sizeof(mCurrentTransformMatrix));
  158. mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
  159. }
  160. status_t GLConsumer::setDefaultMaxBufferCount(int bufferCount) {
  161. Mutex::Autolock lock(mMutex);
  162. return mConsumer->setDefaultMaxBufferCount(bufferCount);
  163. }
  164. status_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h)
  165. {
  166. Mutex::Autolock lock(mMutex);
  167. mDefaultWidth = w;
  168. mDefaultHeight = h;
  169. return mConsumer->setDefaultBufferSize(w, h);
  170. }
  171. status_t GLConsumer::updateTexImage() {
  172. ATRACE_CALL();
  173. GLC_LOGV("updateTexImage");
  174. Mutex::Autolock lock(mMutex);
  175. if (mAbandoned) {
  176. GLC_LOGE("updateTexImage: GLConsumer is abandoned!");
  177. return NO_INIT;
  178. }
  179. // Make sure the EGL state is the same as in previous calls.
  180. status_t err = checkAndUpdateEglStateLocked();
  181. if (err != NO_ERROR) {
  182. return err;
  183. }
  184. BufferItem item;
  185. // Acquire the next buffer.
  186. // In asynchronous mode the list is guaranteed to be one buffer
  187. // deep, while in synchronous mode we use the oldest buffer.
  188. err = acquireBufferLocked(&item, 0);
  189. if (err != NO_ERROR) {
  190. if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
  191. // We always bind the texture even if we don't update its contents.
  192. GLC_LOGV("updateTexImage: no buffers were available");
  193. glBindTexture(mTexTarget, mTexName);
  194. err = NO_ERROR;
  195. } else {
  196. GLC_LOGE("updateTexImage: acquire failed: %s (%d)",
  197. strerror(-err), err);
  198. }
  199. return err;
  200. }
  201. // Release the previous buffer.
  202. err = updateAndReleaseLocked(item);
  203. if (err != NO_ERROR) {
  204. // We always bind the texture.
  205. glBindTexture(mTexTarget, mTexName);
  206. return err;
  207. }
  208. // Bind the new buffer to the GL texture, and wait until it's ready.
  209. return bindTextureImageLocked();
  210. }
  211. status_t GLConsumer::releaseTexImage() {
  212. ATRACE_CALL();
  213. GLC_LOGV("releaseTexImage");
  214. Mutex::Autolock lock(mMutex);
  215. if (mAbandoned) {
  216. GLC_LOGE("releaseTexImage: GLConsumer is abandoned!");
  217. return NO_INIT;
  218. }
  219. // Make sure the EGL state is the same as in previous calls.
  220. status_t err = NO_ERROR;
  221. if (mAttached) {
  222. err = checkAndUpdateEglStateLocked(true);
  223. if (err != NO_ERROR) {
  224. return err;
  225. }
  226. } else {
  227. // if we're detached, no need to validate EGL's state -- we won't use it.
  228. }
  229. // Update the GLConsumer state.
  230. int buf = mCurrentTexture;
  231. if (buf != BufferQueue::INVALID_BUFFER_SLOT) {
  232. GLC_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached);
  233. if (mAttached) {
  234. // Do whatever sync ops we need to do before releasing the slot.
  235. err = syncForReleaseLocked(mEglDisplay);
  236. if (err != NO_ERROR) {
  237. GLC_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err);
  238. return err;
  239. }
  240. } else {
  241. // if we're detached, we just use the fence that was created in detachFromContext()
  242. // so... basically, nothing more to do here.
  243. }
  244. err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR);
  245. if (err < NO_ERROR) {
  246. GLC_LOGE("releaseTexImage: failed to release buffer: %s (%d)",
  247. strerror(-err), err);
  248. return err;
  249. }
  250. if (mReleasedTexImage == NULL) {
  251. mReleasedTexImage = new EglImage(getDebugTexImageBuffer());
  252. }
  253. mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT;
  254. mCurrentTextureImage = mReleasedTexImage;
  255. mCurrentCrop.makeInvalid();
  256. mCurrentTransform = 0;
  257. mCurrentScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
  258. mCurrentTimestamp = 0;
  259. mCurrentFence = Fence::NO_FENCE;
  260. if (mAttached) {
  261. // This binds a dummy buffer (mReleasedTexImage).
  262. status_t result = bindTextureImageLocked();
  263. if (result != NO_ERROR) {
  264. return result;
  265. }
  266. } else {
  267. // detached, don't touch the texture (and we may not even have an
  268. // EGLDisplay here.
  269. }
  270. }
  271. return NO_ERROR;
  272. }
  273. sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() {
  274. Mutex::Autolock _l(sStaticInitLock);
  275. if (CC_UNLIKELY(sReleasedTexImageBuffer == NULL)) {
  276. // The first time, create the debug texture in case the application
  277. // continues to use it.
  278. sp<GraphicBuffer> buffer = new GraphicBuffer(
  279. kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
  280. GraphicBuffer::USAGE_SW_WRITE_RARELY);
  281. uint32_t* bits;
  282. buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
  283. uint32_t stride = buffer->getStride();
  284. uint32_t height = buffer->getHeight();
  285. memset(bits, 0, stride * height * 4);
  286. for (uint32_t y = 0; y < kDebugData.height; y++) {
  287. for (uint32_t x = 0; x < kDebugData.width; x++) {
  288. bits[x] = (kDebugData.bits[y + kDebugData.width + x] == 'X') ?
  289. 0xFF000000 : 0xFFFFFFFF;
  290. }
  291. bits += stride;
  292. }
  293. buffer->unlock();
  294. sReleasedTexImageBuffer = buffer;
  295. }
  296. return sReleasedTexImageBuffer;
  297. }
  298. status_t GLConsumer::acquireBufferLocked(BufferItem *item,
  299. nsecs_t presentWhen, uint64_t maxFrameNumber) {
  300. status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen,
  301. maxFrameNumber);
  302. if (err != NO_ERROR) {
  303. return err;
  304. }
  305. // If item->mGraphicBuffer is not null, this buffer has not been acquired
  306. // before, so any prior EglImage created is using a stale buffer. This
  307. // replaces any old EglImage with a new one (using the new buffer).
  308. if (item->mGraphicBuffer != NULL) {
  309. int slot = item->mBuf;
  310. mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer);
  311. }
  312. return NO_ERROR;
  313. }
  314. status_t GLConsumer::releaseBufferLocked(int buf,
  315. sp<GraphicBuffer> graphicBuffer,
  316. EGLDisplay display, EGLSyncKHR eglFence) {
  317. // release the buffer if it hasn't already been discarded by the
  318. // BufferQueue. This can happen, for example, when the producer of this
  319. // buffer has reallocated the original buffer slot after this buffer
  320. // was acquired.
  321. status_t err = ConsumerBase::releaseBufferLocked(
  322. buf, graphicBuffer, display, eglFence);
  323. mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
  324. return err;
  325. }
  326. status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item)
  327. {
  328. status_t err = NO_ERROR;
  329. int buf = item.mBuf;
  330. if (!mAttached) {
  331. GLC_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL "
  332. "ES context");
  333. releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
  334. mEglDisplay, EGL_NO_SYNC_KHR);
  335. return INVALID_OPERATION;
  336. }
  337. // Confirm state.
  338. err = checkAndUpdateEglStateLocked();
  339. if (err != NO_ERROR) {
  340. releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
  341. mEglDisplay, EGL_NO_SYNC_KHR);
  342. return err;
  343. }
  344. // Ensure we have a valid EglImageKHR for the slot, creating an EglImage
  345. // if nessessary, for the gralloc buffer currently in the slot in
  346. // ConsumerBase.
  347. // We may have to do this even when item.mGraphicBuffer == NULL (which
  348. // means the buffer was previously acquired).
  349. err = mEglSlots[buf].mEglImage->createIfNeeded(mEglDisplay, item.mCrop);
  350. if (err != NO_ERROR) {
  351. GLC_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d",
  352. mEglDisplay, buf);
  353. releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
  354. mEglDisplay, EGL_NO_SYNC_KHR);
  355. return UNKNOWN_ERROR;
  356. }
  357. // Do whatever sync ops we need to do before releasing the old slot.
  358. err = syncForReleaseLocked(mEglDisplay);
  359. if (err != NO_ERROR) {
  360. // Release the buffer we just acquired. It's not safe to
  361. // release the old buffer, so instead we just drop the new frame.
  362. // As we are still under lock since acquireBuffer, it is safe to
  363. // release by slot.
  364. releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
  365. mEglDisplay, EGL_NO_SYNC_KHR);
  366. return err;
  367. }
  368. GLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)",
  369. mCurrentTexture, mCurrentTextureImage != NULL ?
  370. mCurrentTextureImage->graphicBufferHandle() : 0,
  371. buf, mSlots[buf].mGraphicBuffer->handle);
  372. // release old buffer
  373. if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
  374. status_t status = releaseBufferLocked(
  375. mCurrentTexture, mCurrentTextureImage->graphicBuffer(),
  376. mEglDisplay, mEglSlots[mCurrentTexture].mEglFence);
  377. if (status < NO_ERROR) {
  378. GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)",
  379. strerror(-status), status);
  380. err = status;
  381. // keep going, with error raised [?]
  382. }
  383. }
  384. // Update the GLConsumer state.
  385. mCurrentTexture = buf;
  386. mCurrentTextureImage = mEglSlots[buf].mEglImage;
  387. mCurrentCrop = item.mCrop;
  388. mCurrentTransform = item.mTransform;
  389. mCurrentScalingMode = item.mScalingMode;
  390. mCurrentTimestamp = item.mTimestamp;
  391. mCurrentFence = item.mFence;
  392. mCurrentFrameNumber = item.mFrameNumber;
  393. computeCurrentTransformMatrixLocked();
  394. return err;
  395. }
  396. status_t GLConsumer::bindTextureImageLocked() {
  397. if (mEglDisplay == EGL_NO_DISPLAY) {
  398. ALOGE("bindTextureImage: invalid display");
  399. return INVALID_OPERATION;
  400. }
  401. GLenum error;
  402. while ((error = glGetError()) != GL_NO_ERROR) {
  403. GLC_LOGW("bindTextureImage: clearing GL error: %#04x", error);
  404. }
  405. glBindTexture(mTexTarget, mTexName);
  406. if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT &&
  407. mCurrentTextureImage == NULL) {
  408. GLC_LOGE("bindTextureImage: no currently-bound texture");
  409. return NO_INIT;
  410. }
  411. status_t err = mCurrentTextureImage->createIfNeeded(mEglDisplay,
  412. mCurrentCrop);
  413. if (err != NO_ERROR) {
  414. GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d",
  415. mEglDisplay, mCurrentTexture);
  416. return UNKNOWN_ERROR;
  417. }
  418. mCurrentTextureImage->bindToTextureTarget(mTexTarget);
  419. // In the rare case that the display is terminated and then initialized
  420. // again, we can't detect that the display changed (it didn't), but the
  421. // image is invalid. In this case, repeat the exact same steps while
  422. // forcing the creation of a new image.
  423. if ((error = glGetError()) != GL_NO_ERROR) {
  424. glBindTexture(mTexTarget, mTexName);
  425. status_t result = mCurrentTextureImage->createIfNeeded(mEglDisplay,
  426. mCurrentCrop,
  427. true);
  428. if (result != NO_ERROR) {
  429. GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d",
  430. mEglDisplay, mCurrentTexture);
  431. return UNKNOWN_ERROR;
  432. }
  433. mCurrentTextureImage->bindToTextureTarget(mTexTarget);
  434. if ((error = glGetError()) != GL_NO_ERROR) {
  435. GLC_LOGE("bindTextureImage: error binding external image: %#04x", error);
  436. return UNKNOWN_ERROR;
  437. }
  438. }
  439. // Wait for the new buffer to be ready.
  440. return doGLFenceWaitLocked();
  441. }
  442. status_t GLConsumer::checkAndUpdateEglStateLocked(bool contextCheck) {
  443. EGLDisplay dpy = eglGetCurrentDisplay();
  444. EGLContext ctx = eglGetCurrentContext();
  445. if (!contextCheck) {
  446. // if this is the first time we're called, mEglDisplay/mEglContext have
  447. // never been set, so don't error out (below).
  448. if (mEglDisplay == EGL_NO_DISPLAY) {
  449. mEglDisplay = dpy;
  450. }
  451. if (mEglContext == EGL_NO_CONTEXT) {
  452. mEglContext = ctx;
  453. }
  454. }
  455. if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) {
  456. GLC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay");
  457. return INVALID_OPERATION;
  458. }
  459. if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) {
  460. GLC_LOGE("checkAndUpdateEglState: invalid current EGLContext");
  461. return INVALID_OPERATION;
  462. }
  463. mEglDisplay = dpy;
  464. mEglContext = ctx;
  465. return NO_ERROR;
  466. }
  467. void GLConsumer::setReleaseFence(const sp<Fence>& fence) {
  468. if (fence->isValid() &&
  469. mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
  470. status_t err = addReleaseFence(mCurrentTexture,
  471. mCurrentTextureImage->graphicBuffer(), fence);
  472. if (err != OK) {
  473. GLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)",
  474. strerror(-err), err);
  475. }
  476. }
  477. }
  478. status_t GLConsumer::detachFromContext() {
  479. ATRACE_CALL();
  480. GLC_LOGV("detachFromContext");
  481. Mutex::Autolock lock(mMutex);
  482. if (mAbandoned) {
  483. GLC_LOGE("detachFromContext: abandoned GLConsumer");
  484. return NO_INIT;
  485. }
  486. if (!mAttached) {
  487. GLC_LOGE("detachFromContext: GLConsumer is not attached to a "
  488. "context");
  489. return INVALID_OPERATION;
  490. }
  491. EGLDisplay dpy = eglGetCurrentDisplay();
  492. EGLContext ctx = eglGetCurrentContext();
  493. if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) {
  494. GLC_LOGE("detachFromContext: invalid current EGLDisplay");
  495. return INVALID_OPERATION;
  496. }
  497. if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) {
  498. GLC_LOGE("detachFromContext: invalid current EGLContext");
  499. return INVALID_OPERATION;
  500. }
  501. if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) {
  502. status_t err = syncForReleaseLocked(dpy);
  503. if (err != OK) {
  504. return err;
  505. }
  506. glDeleteTextures(1, &mTexName);
  507. }
  508. mEglDisplay = EGL_NO_DISPLAY;
  509. mEglContext = EGL_NO_CONTEXT;
  510. mAttached = false;
  511. return OK;
  512. }
  513. status_t GLConsumer::attachToContext(uint32_t tex) {
  514. ATRACE_CALL();
  515. GLC_LOGV("attachToContext");
  516. Mutex::Autolock lock(mMutex);
  517. if (mAbandoned) {
  518. GLC_LOGE("attachToContext: abandoned GLConsumer");
  519. return NO_INIT;
  520. }
  521. if (mAttached) {
  522. GLC_LOGE("attachToContext: GLConsumer is already attached to a "
  523. "context");
  524. return INVALID_OPERATION;
  525. }
  526. EGLDisplay dpy = eglGetCurrentDisplay();
  527. EGLContext ctx = eglGetCurrentContext();
  528. if (dpy == EGL_NO_DISPLAY) {
  529. GLC_LOGE("attachToContext: invalid current EGLDisplay");
  530. return INVALID_OPERATION;
  531. }
  532. if (ctx == EGL_NO_CONTEXT) {
  533. GLC_LOGE("attachToContext: invalid current EGLContext");
  534. return INVALID_OPERATION;
  535. }
  536. // We need to bind the texture regardless of whether there's a current
  537. // buffer.
  538. glBindTexture(mTexTarget, GLuint(tex));
  539. mEglDisplay = dpy;
  540. mEglContext = ctx;
  541. mTexName = tex;
  542. mAttached = true;
  543. if (mCurrentTextureImage != NULL) {
  544. // This may wait for a buffer a second time. This is likely required if
  545. // this is a different context, since otherwise the wait could be skipped
  546. // by bouncing through another context. For the same context the extra
  547. // wait is redundant.
  548. status_t err = bindTextureImageLocked();
  549. if (err != NO_ERROR) {
  550. return err;
  551. }
  552. }
  553. return OK;
  554. }
  555. status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) {
  556. GLC_LOGV("syncForReleaseLocked");
  557. if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
  558. if (SyncFeatures::getInstance().useNativeFenceSync()) {
  559. EGLSyncKHR sync = eglCreateSyncKHR(dpy,
  560. EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
  561. if (sync == EGL_NO_SYNC_KHR) {
  562. GLC_LOGE("syncForReleaseLocked: error creating EGL fence: %#x",
  563. eglGetError());
  564. return UNKNOWN_ERROR;
  565. }
  566. glFlush();
  567. int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync);
  568. eglDestroySyncKHR(dpy, sync);
  569. if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
  570. GLC_LOGE("syncForReleaseLocked: error dup'ing native fence "
  571. "fd: %#x", eglGetError());
  572. return UNKNOWN_ERROR;
  573. }
  574. sp<Fence> fence(new Fence(fenceFd));
  575. status_t err = addReleaseFenceLocked(mCurrentTexture,
  576. mCurrentTextureImage->graphicBuffer(), fence);
  577. if (err != OK) {
  578. GLC_LOGE("syncForReleaseLocked: error adding release fence: "
  579. "%s (%d)", strerror(-err), err);
  580. return err;
  581. }
  582. } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) {
  583. EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence;
  584. if (fence != EGL_NO_SYNC_KHR) {
  585. // There is already a fence for the current slot. We need to
  586. // wait on that before replacing it with another fence to
  587. // ensure that all outstanding buffer accesses have completed
  588. // before the producer accesses it.
  589. EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
  590. if (result == EGL_FALSE) {
  591. GLC_LOGE("syncForReleaseLocked: error waiting for previous "
  592. "fence: %#x", eglGetError());
  593. return UNKNOWN_ERROR;
  594. } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
  595. GLC_LOGE("syncForReleaseLocked: timeout waiting for previous "
  596. "fence");
  597. return TIMED_OUT;
  598. }
  599. eglDestroySyncKHR(dpy, fence);
  600. }
  601. // Create a fence for the outstanding accesses in the current
  602. // OpenGL ES context.
  603. fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
  604. if (fence == EGL_NO_SYNC_KHR) {
  605. GLC_LOGE("syncForReleaseLocked: error creating fence: %#x",
  606. eglGetError());
  607. return UNKNOWN_ERROR;
  608. }
  609. glFlush();
  610. mEglSlots[mCurrentTexture].mEglFence = fence;
  611. }
  612. }
  613. return OK;
  614. }
  615. bool GLConsumer::isExternalFormat(PixelFormat format)
  616. {
  617. switch (format) {
  618. // supported YUV formats
  619. case HAL_PIXEL_FORMAT_YV12:
  620. // Legacy/deprecated YUV formats
  621. case HAL_PIXEL_FORMAT_YCbCr_422_SP:
  622. case HAL_PIXEL_FORMAT_YCrCb_420_SP:
  623. case HAL_PIXEL_FORMAT_YCbCr_422_I:
  624. return true;
  625. }
  626. // Any OEM format needs to be considered
  627. if (format>=0x100 && format<=0x1FF)
  628. return true;
  629. return false;
  630. }
  631. uint32_t GLConsumer::getCurrentTextureTarget() const {
  632. return mTexTarget;
  633. }
  634. void GLConsumer::getTransformMatrix(float mtx[16]) {
  635. Mutex::Autolock lock(mMutex);
  636. memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
  637. }
  638. void GLConsumer::setFilteringEnabled(bool enabled) {
  639. Mutex::Autolock lock(mMutex);
  640. if (mAbandoned) {
  641. GLC_LOGE("setFilteringEnabled: GLConsumer is abandoned!");
  642. return;
  643. }
  644. bool needsRecompute = mFilteringEnabled != enabled;
  645. mFilteringEnabled = enabled;
  646. if (needsRecompute && mCurrentTextureImage==NULL) {
  647. GLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL");
  648. }
  649. if (needsRecompute && mCurrentTextureImage != NULL) {
  650. computeCurrentTransformMatrixLocked();
  651. }
  652. }
  653. void GLConsumer::computeCurrentTransformMatrixLocked() {
  654. GLC_LOGV("computeCurrentTransformMatrixLocked");
  655. float xform[16];
  656. for (int i = 0; i < 16; i++) {
  657. xform[i] = mtxIdentity[i];
  658. }
  659. if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
  660. float result[16];
  661. mtxMul(result, xform, mtxFlipH);
  662. for (int i = 0; i < 16; i++) {
  663. xform[i] = result[i];
  664. }
  665. }
  666. if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
  667. float result[16];
  668. mtxMul(result, xform, mtxFlipV);
  669. for (int i = 0; i < 16; i++) {
  670. xform[i] = result[i];
  671. }
  672. }
  673. if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
  674. float result[16];
  675. mtxMul(result, xform, mtxRot90);
  676. for (int i = 0; i < 16; i++) {
  677. xform[i] = result[i];
  678. }
  679. }
  680. sp<GraphicBuffer> buf = (mCurrentTextureImage == NULL) ?
  681. NULL : mCurrentTextureImage->graphicBuffer();
  682. if (buf == NULL) {
  683. GLC_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureImage is NULL");
  684. }
  685. float mtxBeforeFlipV[16];
  686. if (!isEglImageCroppable(mCurrentCrop)) {
  687. Rect cropRect = mCurrentCrop;
  688. float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f;
  689. float bufferWidth = buf->getWidth();
  690. float bufferHeight = buf->getHeight();
  691. if (!cropRect.isEmpty()) {
  692. float shrinkAmount = 0.0f;
  693. if (mFilteringEnabled) {
  694. // In order to prevent bilinear sampling beyond the edge of the
  695. // crop rectangle we may need to shrink it by 2 texels in each
  696. // dimension. Normally this would just need to take 1/2 a texel
  697. // off each end, but because the chroma channels of YUV420 images
  698. // are subsampled we may need to shrink the crop region by a whole
  699. // texel on each side.
  700. switch (buf->getPixelFormat()) {
  701. case PIXEL_FORMAT_RGBA_8888:
  702. case PIXEL_FORMAT_RGBX_8888:
  703. case PIXEL_FORMAT_RGB_888:
  704. case PIXEL_FORMAT_RGB_565:
  705. case PIXEL_FORMAT_BGRA_8888:
  706. // We know there's no subsampling of any channels, so we
  707. // only need to shrink by a half a pixel.
  708. shrinkAmount = 0.5;
  709. break;
  710. default:
  711. // If we don't recognize the format, we must assume the
  712. // worst case (that we care about), which is YUV420.
  713. shrinkAmount = 1.0;
  714. break;
  715. }
  716. }
  717. // Only shrink the dimensions that are not the size of the buffer.
  718. if (cropRect.width() < bufferWidth) {
  719. tx = (float(cropRect.left) + shrinkAmount) / bufferWidth;
  720. sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) /
  721. bufferWidth;
  722. }
  723. if (cropRect.height() < bufferHeight) {
  724. ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) /
  725. bufferHeight;
  726. sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) /
  727. bufferHeight;
  728. }
  729. }
  730. float crop[16] = {
  731. sx, 0, 0, 0,
  732. 0, sy, 0, 0,
  733. 0, 0, 1, 0,
  734. tx, ty, 0, 1,
  735. };
  736. mtxMul(mtxBeforeFlipV, crop, xform);
  737. } else {
  738. for (int i = 0; i < 16; i++) {
  739. mtxBeforeFlipV[i] = xform[i];
  740. }
  741. }
  742. // SurfaceFlinger expects the top of its window textures to be at a Y
  743. // coordinate of 0, so GLConsumer must behave the same way. We don't
  744. // want to expose this to applications, however, so we must add an
  745. // additional vertical flip to the transform after all the other transforms.
  746. mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV);
  747. }
  748. nsecs_t GLConsumer::getTimestamp() {
  749. GLC_LOGV("getTimestamp");
  750. Mutex::Autolock lock(mMutex);
  751. return mCurrentTimestamp;
  752. }
  753. uint64_t GLConsumer::getFrameNumber() {
  754. GLC_LOGV("getFrameNumber");
  755. Mutex::Autolock lock(mMutex);
  756. return mCurrentFrameNumber;
  757. }
  758. sp<GraphicBuffer> GLConsumer::getCurrentBuffer() const {
  759. Mutex::Autolock lock(mMutex);
  760. return (mCurrentTextureImage == NULL) ?
  761. NULL : mCurrentTextureImage->graphicBuffer();
  762. }
  763. Rect GLConsumer::getCurrentCrop() const {
  764. Mutex::Autolock lock(mMutex);
  765. Rect outCrop = mCurrentCrop;
  766. if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) {
  767. uint32_t newWidth = static_cast<uint32_t>(mCurrentCrop.width());
  768. uint32_t newHeight = static_cast<uint32_t>(mCurrentCrop.height());
  769. if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) {
  770. newWidth = newHeight * mDefaultWidth / mDefaultHeight;
  771. GLC_LOGV("too wide: newWidth = %d", newWidth);
  772. } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) {
  773. newHeight = newWidth * mDefaultHeight / mDefaultWidth;
  774. GLC_LOGV("too tall: newHeight = %d", newHeight);
  775. }
  776. uint32_t currentWidth = static_cast<uint32_t>(mCurrentCrop.width());
  777. uint32_t currentHeight = static_cast<uint32_t>(mCurrentCrop.height());
  778. // The crop is too wide
  779. if (newWidth < currentWidth) {
  780. uint32_t dw = currentWidth - newWidth;
  781. auto halfdw = dw / 2;
  782. outCrop.left += halfdw;
  783. // Not halfdw because it would subtract 1 too few when dw is odd
  784. outCrop.right -= (dw - halfdw);
  785. // The crop is too tall
  786. } else if (newHeight < currentHeight) {
  787. uint32_t dh = currentHeight - newHeight;
  788. auto halfdh = dh / 2;
  789. outCrop.top += halfdh;
  790. // Not halfdh because it would subtract 1 too few when dh is odd
  791. outCrop.bottom -= (dh - halfdh);
  792. }
  793. GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]",
  794. outCrop.left, outCrop.top,
  795. outCrop.right,outCrop.bottom);
  796. }
  797. return outCrop;
  798. }
  799. uint32_t GLConsumer::getCurrentTransform() const {
  800. Mutex::Autolock lock(mMutex);
  801. return mCurrentTransform;
  802. }
  803. uint32_t GLConsumer::getCurrentScalingMode() const {
  804. Mutex::Autolock lock(mMutex);
  805. return mCurrentScalingMode;
  806. }
  807. sp<Fence> GLConsumer::getCurrentFence() const {
  808. Mutex::Autolock lock(mMutex);
  809. return mCurrentFence;
  810. }
  811. status_t GLConsumer::doGLFenceWait() const {
  812. Mutex::Autolock lock(mMutex);
  813. return doGLFenceWaitLocked();
  814. }
  815. status_t GLConsumer::doGLFenceWaitLocked() const {
  816. EGLDisplay dpy = eglGetCurrentDisplay();
  817. EGLContext ctx = eglGetCurrentContext();
  818. if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) {
  819. GLC_LOGE("doGLFenceWait: invalid current EGLDisplay");
  820. return INVALID_OPERATION;
  821. }
  822. if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) {
  823. GLC_LOGE("doGLFenceWait: invalid current EGLContext");
  824. return INVALID_OPERATION;
  825. }
  826. if (mCurrentFence->isValid()) {
  827. if (SyncFeatures::getInstance().useWaitSync()) {
  828. // Create an EGLSyncKHR from the current fence.
  829. int fenceFd = mCurrentFence->dup();
  830. if (fenceFd == -1) {
  831. GLC_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno);
  832. return -errno;
  833. }
  834. EGLint attribs[] = {
  835. EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd,
  836. EGL_NONE
  837. };
  838. EGLSyncKHR sync = eglCreateSyncKHR(dpy,
  839. EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
  840. if (sync == EGL_NO_SYNC_KHR) {
  841. close(fenceFd);
  842. GLC_LOGE("doGLFenceWait: error creating EGL fence: %#x",
  843. eglGetError());
  844. return UNKNOWN_ERROR;
  845. }
  846. // XXX: The spec draft is inconsistent as to whether this should
  847. // return an EGLint or void. Ignore the return value for now, as
  848. // it's not strictly needed.
  849. eglWaitSyncKHR(dpy, sync, 0);
  850. EGLint eglErr = eglGetError();
  851. eglDestroySyncKHR(dpy, sync);
  852. if (eglErr != EGL_SUCCESS) {
  853. GLC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x",
  854. eglErr);
  855. return UNKNOWN_ERROR;
  856. }
  857. } else {
  858. status_t err = mCurrentFence->waitForever(
  859. "GLConsumer::doGLFenceWaitLocked");
  860. if (err != NO_ERROR) {
  861. GLC_LOGE("doGLFenceWait: error waiting for fence: %d", err);
  862. return err;
  863. }
  864. }
  865. }
  866. return NO_ERROR;
  867. }
  868. void GLConsumer::freeBufferLocked(int slotIndex) {
  869. GLC_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
  870. if (slotIndex == mCurrentTexture) {
  871. mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT;
  872. }
  873. mEglSlots[slotIndex].mEglImage.clear();
  874. ConsumerBase::freeBufferLocked(slotIndex);
  875. }
  876. void GLConsumer::abandonLocked() {
  877. GLC_LOGV("abandonLocked");
  878. mCurrentTextureImage.clear();
  879. ConsumerBase::abandonLocked();
  880. }
  881. void GLConsumer::setName(const String8& name) {
  882. Mutex::Autolock _l(mMutex);
  883. mName = name;
  884. mConsumer->setConsumerName(name);
  885. }
  886. status_t GLConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
  887. Mutex::Autolock lock(mMutex);
  888. return mConsumer->setDefaultBufferFormat(defaultFormat);
  889. }
  890. status_t GLConsumer::setDefaultBufferDataSpace(
  891. android_dataspace defaultDataSpace) {
  892. Mutex::Autolock lock(mMutex);
  893. return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
  894. }
  895. status_t GLConsumer::setConsumerUsageBits(uint32_t usage) {
  896. Mutex::Autolock lock(mMutex);
  897. usage |= DEFAULT_USAGE_FLAGS;
  898. return mConsumer->setConsumerUsageBits(usage);
  899. }
  900. status_t GLConsumer::setTransformHint(uint32_t hint) {
  901. Mutex::Autolock lock(mMutex);
  902. return mConsumer->setTransformHint(hint);
  903. }
  904. void GLConsumer::dumpLocked(String8& result, const char* prefix) const
  905. {
  906. result.appendFormat(
  907. "%smTexName=%d mCurrentTexture=%d\n"
  908. "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n",
  909. prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left,
  910. mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
  911. mCurrentTransform);
  912. ConsumerBase::dumpLocked(result, prefix);
  913. }
  914. static void mtxMul(float out[16], const float a[16], const float b[16]) {
  915. out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
  916. out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
  917. out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
  918. out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];
  919. out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
  920. out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
  921. out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
  922. out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];
  923. out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
  924. out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
  925. out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
  926. out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];
  927. out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
  928. out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
  929. out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
  930. out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
  931. }
  932. GLConsumer::EglImage::EglImage(sp<GraphicBuffer> graphicBuffer) :
  933. mGraphicBuffer(graphicBuffer),
  934. mEglImage(EGL_NO_IMAGE_KHR),
  935. mEglDisplay(EGL_NO_DISPLAY) {
  936. }
  937. GLConsumer::EglImage::~EglImage() {
  938. if (mEglImage != EGL_NO_IMAGE_KHR) {
  939. if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
  940. ALOGE("~EglImage: eglDestroyImageKHR failed");
  941. }
  942. eglTerminate(mEglDisplay);
  943. }
  944. }
  945. status_t GLConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay,
  946. const Rect& cropRect,
  947. bool forceCreation) {
  948. // If there's an image and it's no longer valid, destroy it.
  949. bool haveImage = mEglImage != EGL_NO_IMAGE_KHR;
  950. bool displayInvalid = mEglDisplay != eglDisplay;
  951. bool cropInvalid = hasEglAndroidImageCrop() && mCropRect != cropRect;
  952. if (haveImage && (displayInvalid || cropInvalid || forceCreation)) {
  953. if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
  954. ALOGE("createIfNeeded: eglDestroyImageKHR failed");
  955. }
  956. eglTerminate(mEglDisplay);
  957. mEglImage = EGL_NO_IMAGE_KHR;
  958. mEglDisplay = EGL_NO_DISPLAY;
  959. }
  960. // If there's no image, create one.
  961. if (mEglImage == EGL_NO_IMAGE_KHR) {
  962. mEglDisplay = eglDisplay;
  963. mCropRect = cropRect;
  964. mEglImage = createImage(mEglDisplay, mGraphicBuffer, mCropRect);
  965. }
  966. // Fail if we can't create a valid image.
  967. if (mEglImage == EGL_NO_IMAGE_KHR) {
  968. mEglDisplay = EGL_NO_DISPLAY;
  969. mCropRect.makeInvalid();
  970. const sp<GraphicBuffer>& buffer = mGraphicBuffer;
  971. ALOGE("Failed to create image. size=%ux%u st=%u usage=0x%x fmt=%d",
  972. buffer->getWidth(), buffer->getHeight(), buffer->getStride(),
  973. buffer->getUsage(), buffer->getPixelFormat());
  974. return UNKNOWN_ERROR;
  975. }
  976. return OK;
  977. }
  978. void GLConsumer::EglImage::bindToTextureTarget(uint32_t texTarget) {
  979. glEGLImageTargetTexture2DOES(texTarget,
  980. static_cast<GLeglImageOES>(mEglImage));
  981. }
  982. EGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy,
  983. const sp<GraphicBuffer>& graphicBuffer, const Rect& crop) {
  984. EGLClientBuffer cbuf =
  985. static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer());
  986. EGLint attrs[] = {
  987. EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
  988. EGL_IMAGE_CROP_LEFT_ANDROID, crop.left,
  989. EGL_IMAGE_CROP_TOP_ANDROID, crop.top,
  990. EGL_IMAGE_CROP_RIGHT_ANDROID, crop.right,
  991. EGL_IMAGE_CROP_BOTTOM_ANDROID, crop.bottom,
  992. EGL_NONE,
  993. };
  994. if (!crop.isValid()) {
  995. // No crop rect to set, so terminate the attrib array before the crop.
  996. attrs[2] = EGL_NONE;
  997. } else if (!isEglImageCroppable(crop)) {
  998. // The crop rect is not at the origin, so we can't set the crop on the
  999. // EGLImage because that's not allowed by the EGL_ANDROID_image_crop
  1000. // extension. In the future we can add a layered extension that
  1001. // removes this restriction if there is hardware that can support it.
  1002. attrs[2] = EGL_NONE;
  1003. }
  1004. eglInitialize(dpy, 0, 0);
  1005. EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
  1006. EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
  1007. if (image == EGL_NO_IMAGE_KHR) {
  1008. EGLint error = eglGetError();
  1009. ALOGE("error creating EGLImage: %#x", error);
  1010. eglTerminate(dpy);
  1011. }
  1012. return image;
  1013. }
  1014. }; // namespace android