GLConsumer.cpp 34 KB

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