diff options
-rw-r--r-- | include/gui/SurfaceTexture.h | 9 | ||||
-rw-r--r-- | libs/gui/SurfaceTexture.cpp | 17 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 2 |
3 files changed, 24 insertions, 4 deletions
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h index 6e5a478..37e7eb1 100644 --- a/include/gui/SurfaceTexture.h +++ b/include/gui/SurfaceTexture.h @@ -246,7 +246,7 @@ private: virtual ~BufferRejecter() { } }; friend class Layer; - status_t updateTexImage(BufferRejecter* rejecter); + status_t updateTexImage(BufferRejecter* rejecter, bool skipSync); // createImage creates a new EGLImage from a GraphicBuffer. EGLImageKHR createImage(EGLDisplay dpy, @@ -264,6 +264,13 @@ private: // to compute this matrix and stores it in mCurrentTransformMatrix. void computeCurrentTransformMatrix(); + // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command + // stream to ensure that it is safe for future OpenGL ES commands to + // access the current texture buffer. This must be called each time + // updateTexImage is called before issuing OpenGL ES commands that access + // the texture. + status_t doGLFenceWaitLocked() const; + // syncForReleaseLocked performs the synchronization needed to release the // current slot from an OpenGL ES context. If needed it will set the // current slot's fence to guard against a producer accessing the buffer diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 36a2af7..f2e9077 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -164,7 +164,7 @@ status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) } status_t SurfaceTexture::updateTexImage() { - return SurfaceTexture::updateTexImage(NULL); + return SurfaceTexture::updateTexImage(NULL, false); } status_t SurfaceTexture::acquireBufferLocked(BufferQueue::BufferItem *item) { @@ -205,7 +205,7 @@ status_t SurfaceTexture::releaseBufferLocked(int buf, EGLDisplay display, return err; } -status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { +status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter, bool skipSync) { ATRACE_CALL(); ST_LOGV("updateTexImage"); Mutex::Autolock lock(mMutex); @@ -308,6 +308,15 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { mCurrentScalingMode = item.mScalingMode; mCurrentTimestamp = item.mTimestamp; mCurrentFence = item.mFence; + if (!skipSync) { + // SurfaceFlinger needs to lazily perform GLES synchronization + // only when it's actually going to use GLES for compositing. + // Eventually SurfaceFlinger should have its own consumer class, + // but for now we'll just hack it in to SurfaceTexture. + // SurfaceFlinger is responsible for calling doGLFenceWait before + // texturing from this SurfaceTexture. + doGLFenceWaitLocked(); + } computeCurrentTransformMatrix(); } else { if (err < 0) { @@ -738,6 +747,10 @@ sp<Fence> SurfaceTexture::getCurrentFence() const { status_t SurfaceTexture::doGLFenceWait() const { Mutex::Autolock lock(mMutex); + return doGLFenceWaitLocked(); +} + +status_t SurfaceTexture::doGLFenceWaitLocked() const { EGLDisplay dpy = eglGetCurrentDisplay(); EGLContext ctx = eglGetCurrentContext(); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 569f6bb..3d79baf 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -637,7 +637,7 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) Reject r(mDrawingState, currentState(), recomputeVisibleRegions); - if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) { + if (mSurfaceTexture->updateTexImage(&r, true) < NO_ERROR) { // something happened! recomputeVisibleRegions = true; return outDirtyRegion; |