Merge "Check that HWC exists before trying to use it" into jb-mr1-dev
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 @@
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 @@
// 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::updateTexImage() {
- return SurfaceTexture::updateTexImage(NULL);
+ return SurfaceTexture::updateTexImage(NULL, false);
}
status_t SurfaceTexture::acquireBufferLocked(BufferQueue::BufferItem *item) {
@@ -205,7 +205,7 @@
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 @@
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 @@
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 @@
Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
- if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
+ if (mSurfaceTexture->updateTexImage(&r, true) < NO_ERROR) {
// something happened!
recomputeVisibleRegions = true;
return outDirtyRegion;