surfaceflinger: pass RenderEngine into BufferLayerConsumer

Add RenderEngine::isCurrent to replace
BufferLayerConsumer::checkAndUpdateEglStateLocked.  Remove a
duplicated check in updateAndReleaseLocked.  Use
RenderEngine::checkErrors.

Test: SurfaceFlinger_test
Change-Id: I6b97534a41a855d101965b498cb1afa72404227e
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index b52bef3..1cc37c7 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -660,7 +660,8 @@
     sp<IGraphicBufferConsumer> consumer;
     BufferQueue::createBufferQueue(&producer, &consumer, true);
     mProducer = new MonitoredProducer(producer, mFlinger, this);
-    mSurfaceFlingerConsumer = new BufferLayerConsumer(consumer, mTextureName, this);
+    mSurfaceFlingerConsumer = new BufferLayerConsumer(consumer,
+            mFlinger->getRenderEngine(), mTextureName, this);
     mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
     mSurfaceFlingerConsumer->setContentsChangedListener(this);
     mSurfaceFlingerConsumer->setName(mName);
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 5569dfa..b86e542 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -23,6 +23,7 @@
 
 #include "DispSync.h"
 #include "Layer.h"
+#include "RenderEngine/RenderEngine.h"
 
 #include <inttypes.h>
 
@@ -108,8 +109,8 @@
     return hasEglAndroidImageCrop() && (crop.left == 0 && crop.top == 0);
 }
 
-BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
-                                         Layer* layer)
+BufferLayerConsumer::BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RenderEngine& engine,
+                                         uint32_t tex, Layer* layer)
       : ConsumerBase(bq, false),
         mCurrentCrop(Rect::EMPTY_RECT),
         mCurrentTransform(0),
@@ -123,10 +124,10 @@
         mDefaultWidth(1),
         mDefaultHeight(1),
         mFilteringEnabled(true),
+        mRE(engine),
+        mEglDisplay(mRE.getEGLDisplay()),
         mTexName(tex),
         mLayer(layer),
-        mEglDisplay(EGL_NO_DISPLAY),
-        mEglContext(EGL_NO_CONTEXT),
         mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT) {
     BLC_LOGV("BufferLayerConsumer");
 
@@ -211,10 +212,10 @@
         return NO_INIT;
     }
 
-    // Make sure the EGL state is the same as in previous calls.
-    status_t err = checkAndUpdateEglStateLocked();
-    if (err != NO_ERROR) {
-        return err;
+    // Make sure RenderEngine is current
+    if (!mRE.isCurrent()) {
+        BLC_LOGE("updateTexImage: RenderEngine is not current");
+        return INVALID_OPERATION;
     }
 
     BufferItem item;
@@ -222,7 +223,7 @@
     // Acquire the next buffer.
     // In asynchronous mode the list is guaranteed to be one buffer
     // deep, while in synchronous mode we use the oldest buffer.
-    err = acquireBufferLocked(&item, computeExpectedPresent(dispSync), maxFrameNumber);
+    status_t err = acquireBufferLocked(&item, computeExpectedPresent(dispSync), maxFrameNumber);
     if (err != NO_ERROR) {
         if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
             err = NO_ERROR;
@@ -338,13 +339,6 @@
 
     int slot = item.mSlot;
 
-    // Confirm state.
-    err = checkAndUpdateEglStateLocked();
-    if (err != NO_ERROR) {
-        releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer);
-        return err;
-    }
-
     // Ensure we have a valid EglImageKHR for the slot, creating an EglImage
     // if nessessary, for the gralloc buffer currently in the slot in
     // ConsumerBase.
@@ -418,15 +412,7 @@
 }
 
 status_t BufferLayerConsumer::bindTextureImageLocked() {
-    if (mEglDisplay == EGL_NO_DISPLAY) {
-        ALOGE("bindTextureImage: invalid display");
-        return INVALID_OPERATION;
-    }
-
-    GLenum error;
-    while ((error = glGetError()) != GL_NO_ERROR) {
-        BLC_LOGW("bindTextureImage: clearing GL error: %#04x", error);
-    }
+    mRE.checkErrors();
 
     glBindTexture(sTexTarget, mTexName);
     if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == NULL) {
@@ -446,32 +432,6 @@
     return doGLFenceWaitLocked();
 }
 
-status_t BufferLayerConsumer::checkAndUpdateEglStateLocked() {
-    EGLDisplay dpy = eglGetCurrentDisplay();
-    EGLContext ctx = eglGetCurrentContext();
-
-    // if this is the first time we're called, mEglDisplay/mEglContext have
-    // never been set, so don't error out (below).
-    if (mEglDisplay == EGL_NO_DISPLAY) {
-        mEglDisplay = dpy;
-    }
-    if (mEglContext == EGL_NO_CONTEXT) {
-        mEglContext = ctx;
-    }
-
-    if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) {
-        BLC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay");
-        return INVALID_OPERATION;
-    }
-
-    if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) {
-        BLC_LOGE("checkAndUpdateEglState: invalid current EGLContext");
-        return INVALID_OPERATION;
-    }
-
-    return NO_ERROR;
-}
-
 status_t BufferLayerConsumer::syncForReleaseLocked(EGLDisplay dpy) {
     BLC_LOGV("syncForReleaseLocked");
 
@@ -608,16 +568,8 @@
 }
 
 status_t BufferLayerConsumer::doGLFenceWaitLocked() const {
-    EGLDisplay dpy = eglGetCurrentDisplay();
-    EGLContext ctx = eglGetCurrentContext();
-
-    if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) {
-        BLC_LOGE("doGLFenceWait: invalid current EGLDisplay");
-        return INVALID_OPERATION;
-    }
-
-    if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) {
-        BLC_LOGE("doGLFenceWait: invalid current EGLContext");
+    if (!mRE.isCurrent()) {
+        BLC_LOGE("doGLFenceWait: RenderEngine is not current");
         return INVALID_OPERATION;
     }
 
@@ -630,7 +582,7 @@
                 return -errno;
             }
             EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, EGL_NONE};
-            EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
+            EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
             if (sync == EGL_NO_SYNC_KHR) {
                 close(fenceFd);
                 BLC_LOGE("doGLFenceWait: error creating EGL fence: %#x", eglGetError());
@@ -640,9 +592,9 @@
             // XXX: The spec draft is inconsistent as to whether this should
             // return an EGLint or void.  Ignore the return value for now, as
             // it's not strictly needed.
-            eglWaitSyncKHR(dpy, sync, 0);
+            eglWaitSyncKHR(mEglDisplay, sync, 0);
             EGLint eglErr = eglGetError();
-            eglDestroySyncKHR(dpy, sync);
+            eglDestroySyncKHR(mEglDisplay, sync);
             if (eglErr != EGL_SUCCESS) {
                 BLC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", eglErr);
                 return UNKNOWN_ERROR;
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index cc35a66..a08f15b 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -36,6 +36,7 @@
 
 class DispSync;
 class Layer;
+class RenderEngine;
 class String8;
 
 /*
@@ -73,7 +74,8 @@
     // BufferLayerConsumer constructs a new BufferLayerConsumer object.
     // The tex parameter indicates the name of the OpenGL ES
     // texture to which images are to be streamed.
-    BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, Layer* layer);
+    BufferLayerConsumer(const sp<IGraphicBufferConsumer>& bq, RenderEngine& engine, uint32_t tex,
+                        Layer* layer);
 
     // Sets the contents changed listener. This should be used instead of
     // ConsumerBase::setFrameAvailableListener().
@@ -230,12 +232,6 @@
     // bind succeeds, this calls doGLFenceWait.
     status_t bindTextureImageLocked();
 
-    // Gets the current EGLDisplay and EGLContext values, and compares them
-    // to mEglDisplay and mEglContext.  If the fields have been previously
-    // set, the values must match; if not, the fields are set to the current
-    // values.
-    status_t checkAndUpdateEglStateLocked();
-
 private:
     // EglImage is a utility class for tracking and creating EGLImageKHRs. There
     // is primarily just one image per slot, but there is also special cases:
@@ -381,6 +377,11 @@
     // setFilteringEnabled().
     bool mFilteringEnabled;
 
+    RenderEngine& mRE;
+
+    // mEglDisplay is initialized to RenderEngine's EGLDisplay.
+    const EGLDisplay mEglDisplay;
+
     // mTexName is the name of the OpenGL texture to which streamed images will
     // be bound when updateTexImage is called. It is set at construction time.
     const uint32_t mTexName;
@@ -397,17 +398,6 @@
         sp<EglImage> mEglImage;
     };
 
-    // mEglDisplay is the EGLDisplay with which this BufferLayerConsumer is currently
-    // associated.  It is intialized to EGL_NO_DISPLAY and gets set to the
-    // current display when updateTexImage is called for the first time.
-    EGLDisplay mEglDisplay;
-
-    // mEglContext is the OpenGL ES context with which this BufferLayerConsumer is
-    // currently associated.  It is initialized to EGL_NO_CONTEXT and gets set
-    // to the current GL context when updateTexImage is called for the first
-    // time.
-    EGLContext mEglContext;
-
     // mEGLSlots stores the buffers that have been allocated by the BufferQueue
     // for each buffer slot.  It is initialized to null pointers, and gets
     // filled in with the result of BufferQueue::acquire when the
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index f1415c9..314333f 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -157,6 +157,10 @@
     return GLExtensions::getInstance().hasImageCrop();
 }
 
+bool RenderEngine::isCurrent() const {
+    return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext();
+}
+
 bool RenderEngine::setCurrentSurface(const RE::Surface& surface) {
     bool success = true;
     EGLSurface eglSurface = surface.getEGLSurface();
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 57662a4..f886919 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -86,6 +86,10 @@
 
     bool supportsImageCrop() const;
 
+    bool isCurrent() const;
+    bool setCurrentSurface(const RE::Surface& surface);
+    void resetCurrentSurface();
+
     // synchronization
 
     // flush submits RenderEngine command stream for execution and returns a
@@ -124,9 +128,6 @@
         int getStatus() const;
     };
 
-    bool setCurrentSurface(const RE::Surface& surface);
-    void resetCurrentSurface();
-
     // set-up
     virtual void checkErrors() const;
     virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop, size_t hwh,