Loading libs/gui/SurfaceTexture.cpp +64 −26 Original line number Diff line number Diff line Loading @@ -39,6 +39,20 @@ #include <utils/String8.h> #include <utils/Trace.h> // This compile option makes SurfaceTexture use the // EGL_ANDROID_native_fence_sync extension to create Android native fences to // signal when all GLES reads for a given buffer have completed. It is not // compatible with using the EGL_KHR_fence_sync extension for the same // purpose. #ifdef USE_NATIVE_FENCE_SYNC #ifdef USE_FENCE_SYNC #error "USE_NATIVE_FENCE_SYNC and USE_FENCE_SYNC are incompatible" #endif const bool useNativeFenceSync = true; #else const bool useNativeFenceSync = false; #endif // This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension // to synchronize access to the buffers. It will cause dequeueBuffer to stall, // waiting for the GL reads for the buffer being dequeued to complete before Loading Loading @@ -443,13 +457,36 @@ status_t SurfaceTexture::attachToContext(GLuint tex) { status_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { ST_LOGV("syncForReleaseLocked"); if (mUseFenceSync && mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (useNativeFenceSync) { EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); if (sync == EGL_NO_SYNC_KHR) { ST_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", eglGetError()); return UNKNOWN_ERROR; } glFlush(); int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { ST_LOGE("syncForReleaseLocked: error dup'ing native fence " "fd: %#x", eglGetError()); return UNKNOWN_ERROR; } sp<Fence> fence(new Fence(fenceFd)); status_t err = addReleaseFence(mCurrentTexture, fence); if (err != OK) { ST_LOGE("syncForReleaseLocked: error adding release fence: " "%s (%d)", strerror(-err), err); return err; } } else if (mUseFenceSync) { EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; if (fence != EGL_NO_SYNC_KHR) { // There is already a fence for the current slot. We need to wait // on that before replacing it with another fence to ensure that all // outstanding buffer accesses have completed before the producer // accesses it. // There is already a fence for the current slot. We need to // wait on that before replacing it with another fence to // ensure that all outstanding buffer accesses have completed // before the producer accesses it. EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); if (result == EGL_FALSE) { ST_LOGE("syncForReleaseLocked: error waiting for previous " Loading @@ -463,8 +500,8 @@ status_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { eglDestroySyncKHR(dpy, fence); } // Create a fence for the outstanding accesses in the current OpenGL ES // context. // Create a fence for the outstanding accesses in the current // OpenGL ES context. fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); if (fence == EGL_NO_SYNC_KHR) { ST_LOGE("syncForReleaseLocked: error creating fence: %#x", Loading @@ -474,6 +511,7 @@ status_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { glFlush(); mEglSlots[mCurrentTexture].mEglFence = fence; } } return OK; } Loading Loading
libs/gui/SurfaceTexture.cpp +64 −26 Original line number Diff line number Diff line Loading @@ -39,6 +39,20 @@ #include <utils/String8.h> #include <utils/Trace.h> // This compile option makes SurfaceTexture use the // EGL_ANDROID_native_fence_sync extension to create Android native fences to // signal when all GLES reads for a given buffer have completed. It is not // compatible with using the EGL_KHR_fence_sync extension for the same // purpose. #ifdef USE_NATIVE_FENCE_SYNC #ifdef USE_FENCE_SYNC #error "USE_NATIVE_FENCE_SYNC and USE_FENCE_SYNC are incompatible" #endif const bool useNativeFenceSync = true; #else const bool useNativeFenceSync = false; #endif // This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension // to synchronize access to the buffers. It will cause dequeueBuffer to stall, // waiting for the GL reads for the buffer being dequeued to complete before Loading Loading @@ -443,13 +457,36 @@ status_t SurfaceTexture::attachToContext(GLuint tex) { status_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { ST_LOGV("syncForReleaseLocked"); if (mUseFenceSync && mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (useNativeFenceSync) { EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); if (sync == EGL_NO_SYNC_KHR) { ST_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", eglGetError()); return UNKNOWN_ERROR; } glFlush(); int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { ST_LOGE("syncForReleaseLocked: error dup'ing native fence " "fd: %#x", eglGetError()); return UNKNOWN_ERROR; } sp<Fence> fence(new Fence(fenceFd)); status_t err = addReleaseFence(mCurrentTexture, fence); if (err != OK) { ST_LOGE("syncForReleaseLocked: error adding release fence: " "%s (%d)", strerror(-err), err); return err; } } else if (mUseFenceSync) { EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; if (fence != EGL_NO_SYNC_KHR) { // There is already a fence for the current slot. We need to wait // on that before replacing it with another fence to ensure that all // outstanding buffer accesses have completed before the producer // accesses it. // There is already a fence for the current slot. We need to // wait on that before replacing it with another fence to // ensure that all outstanding buffer accesses have completed // before the producer accesses it. EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); if (result == EGL_FALSE) { ST_LOGE("syncForReleaseLocked: error waiting for previous " Loading @@ -463,8 +500,8 @@ status_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { eglDestroySyncKHR(dpy, fence); } // Create a fence for the outstanding accesses in the current OpenGL ES // context. // Create a fence for the outstanding accesses in the current // OpenGL ES context. fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); if (fence == EGL_NO_SYNC_KHR) { ST_LOGE("syncForReleaseLocked: error creating fence: %#x", Loading @@ -474,6 +511,7 @@ status_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { glFlush(); mEglSlots[mCurrentTexture].mEglFence = fence; } } return OK; } Loading