Merge "[RenderEngine] Make BindNativeBufferAsFramebuffer more generic."
diff --git a/services/surfaceflinger/RenderEngine/Android.bp b/services/surfaceflinger/RenderEngine/Android.bp
index add1b7b..064eb17 100644
--- a/services/surfaceflinger/RenderEngine/Android.bp
+++ b/services/surfaceflinger/RenderEngine/Android.bp
@@ -52,6 +52,7 @@
     srcs: [
         "gl/GLES20RenderEngine.cpp",
         "gl/GLExtensions.cpp",
+        "gl/GLFramebuffer.cpp",
         "gl/GLImage.cpp",
         "gl/GLSurface.cpp",
         "gl/Program.cpp",
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index ce977b7..2712b1c 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -354,45 +354,6 @@
     result.appendFormat("%s\n", extensions.getExtensions());
 }
 
-void RenderEngine::bindNativeBufferAsFrameBuffer(
-        ANativeWindowBuffer* buffer,
-        renderengine::BindNativeBufferAsFramebuffer* bindHelper) {
-    bindHelper->mImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-                                           buffer, nullptr);
-    if (bindHelper->mImage == EGL_NO_IMAGE_KHR) {
-        bindHelper->mStatus = NO_MEMORY;
-        return;
-    }
-
-    uint32_t glStatus;
-    bindImageAsFramebuffer(bindHelper->mImage, &bindHelper->mTexName, &bindHelper->mFbName,
-                           &glStatus);
-
-    ALOGE_IF(glStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d",
-             glStatus);
-
-    bindHelper->mStatus = glStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
-}
-
-void RenderEngine::unbindNativeBufferAsFrameBuffer(
-        renderengine::BindNativeBufferAsFramebuffer* bindHelper) {
-    if (bindHelper->mImage == EGL_NO_IMAGE_KHR) {
-        return;
-    }
-
-    // back to main framebuffer
-    unbindFramebuffer(bindHelper->mTexName, bindHelper->mFbName);
-    eglDestroyImageKHR(mEGLDisplay, bindHelper->mImage);
-
-    // Workaround for b/77935566 to force the EGL driver to release the
-    // screenshot buffer
-    setScissor(0, 0, 0, 0);
-    clearWithColor(0.0, 0.0, 0.0, 0.0);
-    disableScissor();
-}
-
-// ---------------------------------------------------------------------------
-
 static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs, EGLint attribute,
                                          EGLint wanted, EGLConfig* outConfig) {
     EGLint numConfigs = -1, n = 0;
diff --git a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
index def3abb..bfabf4d 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.cpp
@@ -37,6 +37,7 @@
 #include <utils/String8.h>
 #include <utils/Trace.h>
 #include "GLExtensions.h"
+#include "GLFramebuffer.h"
 #include "GLImage.h"
 #include "GLSurface.h"
 #include "Program.h"
@@ -154,6 +155,10 @@
 
 GLES20RenderEngine::~GLES20RenderEngine() {}
 
+std::unique_ptr<Framebuffer> GLES20RenderEngine::createFramebuffer() {
+    return std::make_unique<GLFramebuffer>(*this);
+}
+
 std::unique_ptr<Surface> GLES20RenderEngine::createSurface() {
     return std::make_unique<GLSurface>(*this);
 }
@@ -197,10 +202,49 @@
 
     glBindTexture(target, texName);
     if (glImage.getEGLImage() != EGL_NO_IMAGE_KHR) {
-        glEGLImageTargetTexture2DOES(target, static_cast<GLeglImageOES>(glImage.getEGLImage()));
+        glEGLImageTargetTexture2DOES(target,
+                                     static_cast<GLeglImageOES>(glImage.getEGLImage()));
     }
 }
 
+status_t GLES20RenderEngine::bindFrameBuffer(Framebuffer* framebuffer) {
+    GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer);
+    EGLImageKHR eglImage = glFramebuffer->getEGLImage();
+    uint32_t textureName = glFramebuffer->getTextureName();
+    uint32_t framebufferName = glFramebuffer->getFramebufferName();
+
+    // Bind the texture and turn our EGLImage into a texture
+    glBindTexture(GL_TEXTURE_2D, textureName);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)eglImage);
+
+    // Bind the Framebuffer to render into
+    glBindFramebuffer(GL_FRAMEBUFFER, framebufferName);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                           GL_TEXTURE_2D, textureName, 0);
+
+    mRenderToFbo = true;
+
+    uint32_t glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+    ALOGE_IF(glStatus != GL_FRAMEBUFFER_COMPLETE_OES,
+             "glCheckFramebufferStatusOES error %d", glStatus);
+
+    return glStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
+}
+
+void GLES20RenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) {
+    mRenderToFbo = false;
+
+    // back to main framebuffer
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    // Workaround for b/77935566 to force the EGL driver to release the
+    // screenshot buffer
+    setScissor(0, 0, 0, 0);
+    clearWithColor(0.0, 0.0, 0.0, 0.0);
+    disableScissor();
+}
+
 void GLES20RenderEngine::setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
                                                   ui::Transform::orientation_flags rotation) {
     int32_t l = sourceCrop.left;
@@ -304,34 +348,6 @@
     glDisable(GL_BLEND);
 }
 
-void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName,
-                                                uint32_t* fbName, uint32_t* status) {
-    GLuint tname, name;
-    // turn our EGLImage into a texture
-    glGenTextures(1, &tname);
-    glBindTexture(GL_TEXTURE_2D, tname);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
-
-    // create a Framebuffer Object to render into
-    glGenFramebuffers(1, &name);
-    glBindFramebuffer(GL_FRAMEBUFFER, name);
-    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
-
-    *status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-    *texName = tname;
-    *fbName = name;
-
-    mRenderToFbo = true;
-}
-
-void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
-    mRenderToFbo = false;
-
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
-    glDeleteFramebuffers(1, &fbName);
-    glDeleteTextures(1, &texName);
-}
-
 void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
     mState.setPremultipliedAlpha(true);
     mState.setOpaque(false);
diff --git a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
index a6fc03d..3113e53 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/gl/GLES20RenderEngine.h
@@ -39,32 +39,13 @@
 class GLSurface;
 
 class GLES20RenderEngine : public impl::RenderEngine {
-    GLuint mProtectedTexName;
-    GLint mMaxViewportDims[2];
-    GLint mMaxTextureSize;
-    GLuint mVpWidth;
-    GLuint mVpHeight;
-
-    struct Group {
-        GLuint texture;
-        GLuint fbo;
-        GLuint width;
-        GLuint height;
-        mat4 colorTransform;
-    };
-
-    Description mState;
-
-    virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName,
-                                        uint32_t* status);
-    virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
-
 public:
     GLES20RenderEngine(uint32_t featureFlags); // See RenderEngine::FeatureFlag
-    virtual ~GLES20RenderEngine();
+    ~GLES20RenderEngine() override;
 
-    std::unique_ptr<renderengine::Surface> createSurface() override;
-    std::unique_ptr<renderengine::Image> createImage() override;
+    std::unique_ptr<Framebuffer> createFramebuffer() override;
+    std::unique_ptr<Surface> createSurface() override;
+    std::unique_ptr<Image> createImage() override;
 
     void primeCache() const override;
 
@@ -72,15 +53,16 @@
     bool setCurrentSurface(const Surface& surface) override;
     void resetCurrentSurface() override;
 
-    void bindExternalTextureImage(uint32_t texName, const renderengine::Image& image) override;
-
+    void bindExternalTextureImage(uint32_t texName, const Image& image) override;
+    status_t bindFrameBuffer(Framebuffer* framebuffer) override;
+    void unbindFrameBuffer(Framebuffer* framebuffer) override;
 
 protected:
-    virtual void dump(String8& result);
-    virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
-                                          ui::Transform::orientation_flags rotation);
-    virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
-                                    const half4& color) override;
+    void dump(String8& result) override;
+    void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
+                                  ui::Transform::orientation_flags rotation) override;
+    void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
+                            const half4& color) override;
 
     // Color management related functions and state
     void setSourceY410BT2020(bool enable) override;
@@ -88,17 +70,41 @@
     void setOutputDataSpace(ui::Dataspace dataspace) override;
     void setDisplayMaxLuminance(const float maxLuminance) override;
 
-    virtual void setupLayerTexturing(const Texture& texture);
-    virtual void setupLayerBlackedOut();
-    virtual void setupFillWithColor(float r, float g, float b, float a);
-    virtual void setupColorTransform(const mat4& colorTransform);
-    virtual void disableTexturing();
-    virtual void disableBlending();
+    void setupLayerTexturing(const Texture& texture) override;
+    void setupLayerBlackedOut() override;
+    void setupFillWithColor(float r, float g, float b, float a) override;
+    void setupColorTransform(const mat4& colorTransform) override;
+    void disableTexturing() override;
+    void disableBlending() override;
 
-    virtual void drawMesh(const Mesh& mesh);
+    void drawMesh(const Mesh& mesh) override;
 
-    virtual size_t getMaxTextureSize() const;
-    virtual size_t getMaxViewportDims() const;
+    size_t getMaxTextureSize() const override;
+    size_t getMaxViewportDims() const override;
+
+private:
+    // A data space is considered HDR data space if it has BT2020 color space
+    // with PQ or HLG transfer function.
+    bool isHdrDataSpace(const ui::Dataspace dataSpace) const;
+    bool needsXYZTransformMatrix() const;
+
+    GLuint mProtectedTexName;
+    GLint mMaxViewportDims[2];
+    GLint mMaxTextureSize;
+    GLuint mVpWidth;
+    GLuint mVpHeight;
+    Description mState;
+
+    mat4 mSrgbToDisplayP3;
+    mat4 mDisplayP3ToSrgb;
+    mat3 mSrgbToXyz;
+    mat3 mBt2020ToXyz;
+    mat3 mDisplayP3ToXyz;
+    mat4 mXyzToSrgb;
+    mat4 mXyzToDisplayP3;
+    mat4 mXyzToBt2020;
+
+    bool mRenderToFbo = false;
 
     // Current dataspace of layer being rendered
     ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN;
@@ -109,22 +115,6 @@
     // Whether device supports color management, currently color management
     // supports sRGB, DisplayP3 color spaces.
     const bool mUseColorManagement = false;
-    mat4 mSrgbToDisplayP3;
-    mat4 mDisplayP3ToSrgb;
-    mat3 mSrgbToXyz;
-    mat3 mBt2020ToXyz;
-    mat3 mDisplayP3ToXyz;
-    mat4 mXyzToSrgb;
-    mat4 mXyzToDisplayP3;
-    mat4 mXyzToBt2020;
-
-private:
-    // A data space is considered HDR data space if it has BT2020 color space
-    // with PQ or HLG transfer function.
-    bool isHdrDataSpace(const ui::Dataspace dataSpace) const;
-    bool needsXYZTransformMatrix() const;
-
-    bool mRenderToFbo = false;
 };
 
 }  // namespace gl
diff --git a/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.cpp b/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.cpp
new file mode 100644
index 0000000..6aca1c8
--- /dev/null
+++ b/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GLFramebuffer.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include "GLES20RenderEngine.h"
+
+namespace android {
+namespace renderengine {
+namespace gl {
+
+GLFramebuffer::GLFramebuffer(const GLES20RenderEngine& engine)
+        : mEGLDisplay(engine.getEGLDisplay()),
+          mEGLImage(EGL_NO_IMAGE_KHR) {
+    glGenTextures(1, &mTextureName);
+    glGenFramebuffers(1, &mFramebufferName);
+}
+
+GLFramebuffer::~GLFramebuffer() {
+    glDeleteFramebuffers(1, &mFramebufferName);
+    glDeleteTextures(1, &mTextureName);
+    eglDestroyImageKHR(mEGLDisplay, mEGLImage);
+}
+
+bool GLFramebuffer::setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer) {
+    if (mEGLImage != EGL_NO_IMAGE_KHR) {
+        eglDestroyImageKHR(mEGLDisplay, mEGLImage);
+        mEGLImage = EGL_NO_IMAGE_KHR;
+    }
+
+    if (nativeBuffer) {
+        mEGLImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
+                                      EGL_NATIVE_BUFFER_ANDROID,
+                                      nativeBuffer, nullptr);
+        if (mEGLImage == EGL_NO_IMAGE_KHR) {
+            return false;
+        }
+    }
+    return true;
+}
+
+}  // namespace gl
+}  // namespace renderengine
+}  // namespace android
diff --git a/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.h b/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.h
new file mode 100644
index 0000000..90b2248
--- /dev/null
+++ b/services/surfaceflinger/RenderEngine/gl/GLFramebuffer.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <renderengine/Framebuffer.h>
+
+struct ANativeWindowBuffer;
+
+namespace android {
+namespace renderengine {
+namespace gl {
+
+class GLES20RenderEngine;
+
+class GLFramebuffer : public renderengine::Framebuffer {
+public:
+    explicit GLFramebuffer(const GLES20RenderEngine& engine);
+    ~GLFramebuffer() override;
+
+    bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer) override;
+    EGLImageKHR getEGLImage() const { return mEGLImage; }
+    uint32_t getTextureName() const { return mTextureName; }
+    uint32_t getFramebufferName() const { return mFramebufferName; }
+
+private:
+    EGLDisplay mEGLDisplay;
+    EGLImageKHR mEGLImage;
+    uint32_t mTextureName, mFramebufferName;
+};
+
+}  // namespace gl
+}  // namespace renderengine
+}  // namespace android
diff --git a/services/surfaceflinger/RenderEngine/gl/GLImage.h b/services/surfaceflinger/RenderEngine/gl/GLImage.h
index a0f2358..f670783 100644
--- a/services/surfaceflinger/RenderEngine/gl/GLImage.h
+++ b/services/surfaceflinger/RenderEngine/gl/GLImage.h
@@ -38,7 +38,7 @@
 
     bool setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected) override;
 
-    EGLSurface getEGLImage() const { return mEGLImage; }
+    EGLImageKHR getEGLImage() const { return mEGLImage; }
 
 private:
     EGLDisplay mEGLDisplay;
@@ -47,6 +47,6 @@
     DISALLOW_COPY_AND_ASSIGN(GLImage);
 };
 
-} // namespace gl
-} // namespace renderengine
-} // namespace android
+}  // namespace gl
+}  // namespace renderengine
+}  // namespace android
diff --git a/services/surfaceflinger/RenderEngine/include/renderengine/Framebuffer.h b/services/surfaceflinger/RenderEngine/include/renderengine/Framebuffer.h
new file mode 100644
index 0000000..6595466
--- /dev/null
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/Framebuffer.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+struct ANativeWindowBuffer;
+
+namespace android {
+namespace renderengine {
+
+class Framebuffer {
+public:
+    virtual ~Framebuffer() = default;
+
+    virtual bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer) = 0;
+};
+
+}   // namespace renderengine
+}   // namespace android
diff --git a/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h b/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
index 60194d5..7777202 100644
--- a/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
@@ -25,6 +25,8 @@
 #include <EGL/eglext.h>
 #include <android-base/unique_fd.h>
 #include <math/mat4.h>
+#include <renderengine/Image.h>
+#include <renderengine/Framebuffer.h>
 #include <ui/GraphicTypes.h>
 #include <ui/Transform.h>
 
@@ -41,8 +43,8 @@
 namespace renderengine {
 
 class BindNativeBufferAsFramebuffer;
-class Mesh;
 class Image;
+class Mesh;
 class Surface;
 class Texture;
 
@@ -58,6 +60,7 @@
 
     virtual ~RenderEngine() = 0;
 
+    virtual std::unique_ptr<Framebuffer> createFramebuffer() = 0;
     virtual std::unique_ptr<Surface> createSurface() = 0;
     virtual std::unique_ptr<Image> createImage() = 0;
 
@@ -94,12 +97,12 @@
     virtual void disableScissor() = 0;
     virtual void genTextures(size_t count, uint32_t* names) = 0;
     virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
-    virtual void bindExternalTextureImage(uint32_t texName, const renderengine::Image& image) = 0;
+    virtual void bindExternalTextureImage(uint32_t texName, const Image& image) = 0;
     virtual void readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels) = 0;
     // When binding a native buffer, it must be done before setViewportAndProjection
-    virtual void bindNativeBufferAsFrameBuffer(ANativeWindowBuffer* buffer,
-                                               BindNativeBufferAsFramebuffer* bindHelper) = 0;
-    virtual void unbindNativeBufferAsFrameBuffer(BindNativeBufferAsFramebuffer* bindHelper) = 0;
+    // Returns NO_ERROR when binds successfully, NO_MEMORY when there's no memory for allocation.
+    virtual status_t bindFrameBuffer(Framebuffer* framebuffer) = 0;
+    virtual void unbindFrameBuffer(Framebuffer* framebuffer) = 0;
 
     // set-up
     virtual void checkErrors() const;
@@ -110,13 +113,11 @@
     virtual void setupLayerTexturing(const Texture& texture) = 0;
     virtual void setupLayerBlackedOut() = 0;
     virtual void setupFillWithColor(float r, float g, float b, float a) = 0;
-
     virtual void setupColorTransform(const mat4& /* colorTransform */) = 0;
-
     virtual void disableTexturing() = 0;
     virtual void disableBlending() = 0;
 
-    // HDR and wide color gamut support
+    // HDR and color management support
     virtual void setSourceY410BT2020(bool enable) = 0;
     virtual void setSourceDataSpace(ui::Dataspace source) = 0;
     virtual void setOutputDataSpace(ui::Dataspace dataspace) = 0;
@@ -133,18 +134,21 @@
 class BindNativeBufferAsFramebuffer {
 public:
     BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer)
-          : mEngine(engine) {
-        mEngine.bindNativeBufferAsFrameBuffer(buffer, this);
+          : mEngine(engine),
+            mFramebuffer(mEngine.createFramebuffer()),
+            mStatus(NO_ERROR) {
+        mStatus = mFramebuffer->setNativeWindowBuffer(buffer) ?
+                  mEngine.bindFrameBuffer(mFramebuffer.get()) : NO_MEMORY;
     }
-    ~BindNativeBufferAsFramebuffer() { mEngine.unbindNativeBufferAsFrameBuffer(this); }
+    ~BindNativeBufferAsFramebuffer() {
+        mFramebuffer->setNativeWindowBuffer(nullptr);
+        mEngine.unbindFrameBuffer(mFramebuffer.get());
+    }
     status_t getStatus() const { return mStatus; }
 
-protected:
-    friend impl::RenderEngine;
-
+private:
     RenderEngine& mEngine;
-    EGLImageKHR mImage;
-    uint32_t mTexName, mFbName;
+    std::unique_ptr<Framebuffer> mFramebuffer;
     status_t mStatus;
 };
 
@@ -216,18 +220,6 @@
     // internal to RenderEngine
     EGLDisplay getEGLDisplay() const;
     EGLConfig getEGLConfig() const;
-
-    // Common implementation
-    void bindNativeBufferAsFrameBuffer(
-            ANativeWindowBuffer* buffer,
-            renderengine::BindNativeBufferAsFramebuffer* bindHelper) override;
-    void unbindNativeBufferAsFrameBuffer(
-            renderengine::BindNativeBufferAsFramebuffer* bindHelper) override;
-
-    // Overriden by each specialization
-    virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName,
-                                        uint32_t* status) = 0;
-    virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0;
 };
 
 }  // namespace impl
diff --git a/services/surfaceflinger/RenderEngine/include/renderengine/Texture.h b/services/surfaceflinger/RenderEngine/include/renderengine/Texture.h
index 130037c..fb3e0cc 100644
--- a/services/surfaceflinger/RenderEngine/include/renderengine/Texture.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/Texture.h
@@ -25,13 +25,6 @@
 namespace renderengine {
 
 class Texture {
-    uint32_t mTextureName;
-    uint32_t mTextureTarget;
-    size_t mWidth;
-    size_t mHeight;
-    bool mFiltering;
-    mat4 mTextureMatrix;
-
 public:
     enum Target { TEXTURE_2D = 0x0DE1, TEXTURE_EXTERNAL = 0x8D65 };
 
@@ -52,6 +45,14 @@
     bool getFiltering() const;
     size_t getWidth() const;
     size_t getHeight() const;
+
+private:
+    uint32_t mTextureName;
+    uint32_t mTextureTarget;
+    size_t mWidth;
+    size_t mHeight;
+    bool mFiltering;
+    mat4 mTextureMatrix;
 };
 
 }  // namespace renderengine
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index 7d504c5..1c5135b 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -33,6 +33,7 @@
     RenderEngine();
     ~RenderEngine() override;
 
+    MOCK_METHOD0(createFramebuffer, std::unique_ptr<Framebuffer>());
     MOCK_METHOD0(createSurface, std::unique_ptr<renderengine::Surface>());
     MOCK_METHOD0(createImage, std::unique_ptr<renderengine::Image>());
     MOCK_CONST_METHOD0(primeCache, void());
@@ -69,11 +70,8 @@
     MOCK_METHOD1(setSourceDataSpace, void(ui::Dataspace));
     MOCK_METHOD1(setOutputDataSpace, void(ui::Dataspace));
     MOCK_METHOD1(setDisplayMaxLuminance, void(const float));
-    MOCK_METHOD2(bindNativeBufferAsFrameBuffer,
-                 void(ANativeWindowBuffer*,
-                      renderengine::BindNativeBufferAsFramebuffer*));
-    MOCK_METHOD1(unbindNativeBufferAsFrameBuffer,
-                 void(renderengine::BindNativeBufferAsFramebuffer*));
+    MOCK_METHOD1(bindFrameBuffer, status_t(Framebuffer*));
+    MOCK_METHOD1(unbindFrameBuffer, void(Framebuffer*));
     MOCK_METHOD1(drawMesh, void(const Mesh&));
     MOCK_CONST_METHOD0(getMaxTextureSize, size_t());
     MOCK_CONST_METHOD0(getMaxViewportDims, size_t());