So long OpenGLPipeline & OpenGLReadback (2/??)

Hello EglReadback

Test: hwuiunit & PixelCopyTests pass
Change-Id: I36a8cb45b11141b09e75a2e978ed13e336425625
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index a27d519..7319354 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -186,7 +186,6 @@
         "renderstate/TextureState.cpp",
         "renderthread/CacheManager.cpp",
         "renderthread/CanvasContext.cpp",
-        "renderthread/OpenGLPipeline.cpp",
         "renderthread/DrawFrameTask.cpp",
         "renderthread/EglManager.cpp",
         "renderthread/VulkanManager.cpp",
@@ -237,7 +236,7 @@
         "LayerUpdateQueue.cpp",
         "Matrix.cpp",
         "OpDumper.cpp",
-        "OpenGLReadback.cpp",
+        "EglReadback.cpp",
         "Patch.cpp",
         "PatchCache.cpp",
         "PathCache.cpp",
diff --git a/libs/hwui/EglReadback.cpp b/libs/hwui/EglReadback.cpp
new file mode 100644
index 0000000..a836afe
--- /dev/null
+++ b/libs/hwui/EglReadback.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 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 "EglReadback.h"
+
+#include "renderthread/EglManager.h"
+
+#include <gui/Surface.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+
+namespace android {
+namespace uirenderer {
+
+CopyResult EglReadback::copySurfaceInto(Surface& surface, const Rect& srcRect,
+                                           SkBitmap* bitmap) {
+    ATRACE_CALL();
+    // Setup the source
+    sp<GraphicBuffer> sourceBuffer;
+    sp<Fence> sourceFence;
+    Matrix4 texTransform;
+    status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence, texTransform.data);
+    texTransform.invalidateType();
+    if (err != NO_ERROR) {
+        ALOGW("Failed to get last queued buffer, error = %d", err);
+        return CopyResult::UnknownError;
+    }
+    if (!sourceBuffer.get()) {
+        ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
+        return CopyResult::SourceEmpty;
+    }
+    if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) {
+        ALOGW("Surface is protected, unable to copy from it");
+        return CopyResult::SourceInvalid;
+    }
+    err = sourceFence->wait(500 /* ms */);
+    if (err != NO_ERROR) {
+        ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
+        return CopyResult::Timeout;
+    }
+
+    return copyGraphicBufferInto(sourceBuffer.get(), texTransform, srcRect, bitmap);
+}
+
+CopyResult EglReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer,
+                                                 Matrix4& texTransform, const Rect& srcRect,
+                                                 SkBitmap* bitmap) {
+    mRenderThread.eglManager().initialize();
+    // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
+    // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES
+    // to be able to properly sample from the buffer.
+
+    // Create the EGLImage object that maps the GraphicBuffer
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    EGLClientBuffer clientBuffer = (EGLClientBuffer)graphicBuffer->getNativeBuffer();
+    EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
+
+    EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+                                                clientBuffer, attrs);
+
+    if (sourceImage == EGL_NO_IMAGE_KHR) {
+        ALOGW("eglCreateImageKHR failed (%#x)", eglGetError());
+        return CopyResult::UnknownError;
+    }
+
+    uint32_t width = graphicBuffer->getWidth();
+    uint32_t height = graphicBuffer->getHeight();
+    CopyResult copyResult =
+            copyImageInto(sourceImage, texTransform, width, height, srcRect, bitmap);
+
+    eglDestroyImageKHR(display, sourceImage);
+    return copyResult;
+}
+
+CopyResult EglReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) {
+    Rect srcRect;
+    Matrix4 transform;
+    transform.loadScale(1, -1, 1);
+    transform.translate(0, -1);
+    return copyGraphicBufferInto(graphicBuffer, transform, srcRect, bitmap);
+}
+
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/EglReadback.h
similarity index 65%
rename from libs/hwui/OpenGLReadback.h
rename to libs/hwui/EglReadback.h
index ca40738..e723169 100644
--- a/libs/hwui/OpenGLReadback.h
+++ b/libs/hwui/EglReadback.h
@@ -18,16 +18,15 @@
 
 #include "Readback.h"
 
+#include "Matrix.h"
+
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
 namespace android {
 namespace uirenderer {
 
-class Matrix4;
-class GlLayer;
-
-class OpenGLReadback : public Readback {
+class EglReadback : public Readback {
 public:
     virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect,
                                        SkBitmap* bitmap) override;
@@ -35,8 +34,8 @@
                                              SkBitmap* bitmap) override;
 
 protected:
-    explicit OpenGLReadback(renderthread::RenderThread& thread) : Readback(thread) {}
-    virtual ~OpenGLReadback() {}
+    explicit EglReadback(renderthread::RenderThread& thread) : Readback(thread) {}
+    virtual ~EglReadback() {}
 
     virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
                                      int imgWidth, int imgHeight, const Rect& srcRect,
@@ -47,21 +46,5 @@
                                      const Rect& srcRect, SkBitmap* bitmap);
 };
 
-class OpenGLReadbackImpl : public OpenGLReadback {
-public:
-    OpenGLReadbackImpl(renderthread::RenderThread& thread) : OpenGLReadback(thread) {}
-
-    /**
-     * Copies the layer's contents into the provided bitmap.
-     */
-    static bool copyLayerInto(renderthread::RenderThread& renderThread, GlLayer& layer,
-                              SkBitmap* bitmap);
-
-protected:
-    virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
-                                     int imgWidth, int imgHeight, const Rect& srcRect,
-                                     SkBitmap* bitmap) override;
-};
-
 }  // namespace uirenderer
 }  // namespace android
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
deleted file mode 100644
index 11432d6..0000000
--- a/libs/hwui/OpenGLReadback.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2016 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 "OpenGLReadback.h"
-
-#include "Caches.h"
-#include "GlLayer.h"
-#include "GlopBuilder.h"
-#include "Image.h"
-#include "renderstate/RenderState.h"
-#include "renderthread/EglManager.h"
-#include "utils/GLUtils.h"
-
-#include <GLES2/gl2.h>
-#include <gui/Surface.h>
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-
-namespace android {
-namespace uirenderer {
-
-CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect,
-                                           SkBitmap* bitmap) {
-    ATRACE_CALL();
-    // Setup the source
-    sp<GraphicBuffer> sourceBuffer;
-    sp<Fence> sourceFence;
-    Matrix4 texTransform;
-    status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence, texTransform.data);
-    texTransform.invalidateType();
-    if (err != NO_ERROR) {
-        ALOGW("Failed to get last queued buffer, error = %d", err);
-        return CopyResult::UnknownError;
-    }
-    if (!sourceBuffer.get()) {
-        ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
-        return CopyResult::SourceEmpty;
-    }
-    if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) {
-        ALOGW("Surface is protected, unable to copy from it");
-        return CopyResult::SourceInvalid;
-    }
-    err = sourceFence->wait(500 /* ms */);
-    if (err != NO_ERROR) {
-        ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
-        return CopyResult::Timeout;
-    }
-
-    return copyGraphicBufferInto(sourceBuffer.get(), texTransform, srcRect, bitmap);
-}
-
-CopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer,
-                                                 Matrix4& texTransform, const Rect& srcRect,
-                                                 SkBitmap* bitmap) {
-    mRenderThread.eglManager().initialize();
-    // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
-    // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES
-    // to be able to properly sample from the buffer.
-
-    // Create the EGLImage object that maps the GraphicBuffer
-    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    EGLClientBuffer clientBuffer = (EGLClientBuffer)graphicBuffer->getNativeBuffer();
-    EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
-
-    EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-                                                clientBuffer, attrs);
-
-    if (sourceImage == EGL_NO_IMAGE_KHR) {
-        ALOGW("eglCreateImageKHR failed (%#x)", eglGetError());
-        return CopyResult::UnknownError;
-    }
-
-    uint32_t width = graphicBuffer->getWidth();
-    uint32_t height = graphicBuffer->getHeight();
-    CopyResult copyResult =
-            copyImageInto(sourceImage, texTransform, width, height, srcRect, bitmap);
-
-    // All we're flushing & finishing is the deletion of the texture since
-    // copyImageInto already did a major flush & finish as an implicit
-    // part of glReadPixels, so this shouldn't pose any major stalls.
-    glFinish();
-    eglDestroyImageKHR(display, sourceImage);
-    return copyResult;
-}
-
-CopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) {
-    Rect srcRect;
-    Matrix4 transform;
-    transform.loadScale(1, -1, 1);
-    transform.translate(0, -1);
-    return copyGraphicBufferInto(graphicBuffer, transform, srcRect, bitmap);
-}
-
-static float sFlipVInit[16] = {
-        1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,
-};
-
-static const Matrix4 sFlipV(sFlipVInit);
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState, Texture& sourceTexture,
-                                  const Matrix4& texTransform, const Rect& srcRect,
-                                  SkBitmap* bitmap) {
-    int destWidth = bitmap->width();
-    int destHeight = bitmap->height();
-    if (destWidth > caches.maxTextureSize || destHeight > caches.maxTextureSize) {
-        ALOGW("Can't copy surface into bitmap, %dx%d exceeds max texture size %d", destWidth,
-              destHeight, caches.maxTextureSize);
-        return CopyResult::DestinationInvalid;
-    }
-
-    if (bitmap->colorType() == kRGBA_F16_SkColorType &&
-        !caches.extensions().hasRenderableFloatTextures()) {
-        ALOGW("Can't copy surface into bitmap, RGBA_F16 config is not supported");
-        return CopyResult::DestinationInvalid;
-    }
-
-    GLuint fbo = renderState.createFramebuffer();
-    if (!fbo) {
-        ALOGW("Could not obtain an FBO");
-        return CopyResult::UnknownError;
-    }
-
-    GLuint texture;
-
-    GLenum format;
-    GLenum internalFormat;
-    GLenum type;
-
-    switch (bitmap->colorType()) {
-        case kAlpha_8_SkColorType:
-            format = GL_ALPHA;
-            internalFormat = GL_ALPHA;
-            type = GL_UNSIGNED_BYTE;
-            break;
-        case kRGB_565_SkColorType:
-            format = GL_RGB;
-            internalFormat = GL_RGB;
-            type = GL_UNSIGNED_SHORT_5_6_5;
-            break;
-        case kARGB_4444_SkColorType:
-            format = GL_RGBA;
-            internalFormat = GL_RGBA;
-            type = GL_UNSIGNED_SHORT_4_4_4_4;
-            break;
-        case kRGBA_F16_SkColorType:
-            format = GL_RGBA;
-            internalFormat = GL_RGBA16F;
-            type = GL_HALF_FLOAT;
-            break;
-        case kN32_SkColorType:
-        default:
-            format = GL_RGBA;
-            internalFormat = GL_RGBA;
-            type = GL_UNSIGNED_BYTE;
-            break;
-    }
-
-    renderState.bindFramebuffer(fbo);
-
-    // TODO: Use layerPool or something to get this maybe? But since we
-    // need explicit format control we can't currently.
-
-    // Setup the rendertarget
-    glGenTextures(1, &texture);
-    caches.textureState().activateTexture(0);
-    caches.textureState().bindTexture(texture);
-    glPixelStorei(GL_PACK_ALIGNMENT, bitmap->bytesPerPixel());
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, destWidth, destHeight, 0, format, type, nullptr);
-    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
-
-    {
-        bool requiresFilter;
-        // Draw & readback
-        renderState.setViewport(destWidth, destHeight);
-        renderState.scissor().setEnabled(false);
-        renderState.blend().syncEnabled();
-        renderState.stencil().disable();
-
-        Matrix4 croppedTexTransform(texTransform);
-        if (!srcRect.isEmpty()) {
-            // We flipV to convert to 0,0 top-left for the srcRect
-            // coordinates then flip back to 0,0 bottom-left for
-            // GLES coordinates.
-            croppedTexTransform.multiply(sFlipV);
-            croppedTexTransform.translate(srcRect.left / sourceTexture.width(),
-                                          srcRect.top / sourceTexture.height(), 0);
-            croppedTexTransform.scale(srcRect.getWidth() / sourceTexture.width(),
-                                      srcRect.getHeight() / sourceTexture.height(), 1);
-            croppedTexTransform.multiply(sFlipV);
-            requiresFilter = srcRect.getWidth() != (float)destWidth ||
-                             srcRect.getHeight() != (float)destHeight;
-        } else {
-            requiresFilter = sourceTexture.width() != (uint32_t)destWidth ||
-                             sourceTexture.height() != (uint32_t)destHeight;
-        }
-        Glop glop;
-        GlopBuilder(renderState, caches, &glop)
-                .setRoundRectClipState(nullptr)
-                .setMeshTexturedUnitQuad(nullptr)
-                .setFillExternalTexture(sourceTexture, croppedTexTransform, requiresFilter)
-                .setTransform(Matrix4::identity(), TransformFlags::None)
-                .setModelViewMapUnitToRect(Rect(destWidth, destHeight))
-                .build();
-        Matrix4 ortho;
-        ortho.loadOrtho(destWidth, destHeight);
-        renderState.render(glop, ortho, false);
-
-        // TODO: We should convert to linear space when the target is RGBA16F
-        glReadPixels(0, 0, bitmap->width(), bitmap->height(), format, type, bitmap->getPixels());
-        bitmap->notifyPixelsChanged();
-    }
-
-    // Cleanup
-    caches.textureState().deleteTexture(texture);
-    renderState.deleteFramebuffer(fbo);
-
-    GL_CHECKPOINT(MODERATE);
-
-    return CopyResult::Success;
-}
-
-CopyResult OpenGLReadbackImpl::copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
-                                             int imgWidth, int imgHeight, const Rect& srcRect,
-                                             SkBitmap* bitmap) {
-    // If this is a 90 or 270 degree rotation we need to swap width/height
-    // This is a fuzzy way of checking that.
-    if (imgTransform[Matrix4::kSkewX] >= 0.5f || imgTransform[Matrix4::kSkewX] <= -0.5f) {
-        std::swap(imgWidth, imgHeight);
-    }
-
-    Caches& caches = Caches::getInstance();
-    GLuint sourceTexId;
-    // Create a 2D texture to sample from the EGLImage
-    glGenTextures(1, &sourceTexId);
-    caches.textureState().bindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage);
-
-    GLenum status = GL_NO_ERROR;
-    while ((status = glGetError()) != GL_NO_ERROR) {
-        ALOGW("glEGLImageTargetTexture2DOES failed (%#x)", status);
-        return CopyResult::UnknownError;
-    }
-
-    Texture sourceTexture(caches);
-    sourceTexture.wrap(sourceTexId, imgWidth, imgHeight, 0, 0 /* total lie */,
-                       GL_TEXTURE_EXTERNAL_OES);
-
-    CopyResult copyResult = copyTextureInto(caches, mRenderThread.renderState(), sourceTexture,
-                                            imgTransform, srcRect, bitmap);
-    sourceTexture.deleteTexture();
-    return copyResult;
-}
-
-bool OpenGLReadbackImpl::copyLayerInto(renderthread::RenderThread& renderThread, GlLayer& layer,
-                                       SkBitmap* bitmap) {
-    if (!layer.isRenderable()) {
-        // layer has never been updated by DeferredLayerUpdater, abort copy
-        return false;
-    }
-
-    return CopyResult::Success == copyTextureInto(Caches::getInstance(), renderThread.renderState(),
-                                                  layer.getTexture(), layer.getTexTransform(),
-                                                  Rect(), bitmap);
-}
-
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
index 4393f45..208910a 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -136,6 +136,8 @@
     // make sure that we have deleted the texture (in the SkImage) before we
     // destroy the EGLImage that it was created from
     image.reset();
+    glFinish();
+
     return copyResult;
 }
 
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h
index cc9fb3b..1ce4773 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h
@@ -16,15 +16,15 @@
 
 #pragma once
 
-#include "OpenGLReadback.h"
+#include "EglReadback.h"
 
 namespace android {
 namespace uirenderer {
 namespace skiapipeline {
 
-class SkiaOpenGLReadback : public OpenGLReadback {
+class SkiaOpenGLReadback : public EglReadback {
 public:
-    SkiaOpenGLReadback(renderthread::RenderThread& thread) : OpenGLReadback(thread) {}
+    SkiaOpenGLReadback(renderthread::RenderThread& thread) : EglReadback(thread) {}
 
 protected:
     virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index a0fc83e..3deed6e 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -23,7 +23,6 @@
 #include "EglManager.h"
 #include "Frame.h"
 #include "LayerUpdateQueue.h"
-#include "OpenGLPipeline.h"
 #include "Properties.h"
 #include "RenderThread.h"
 #include "hwui/Canvas.h"
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
deleted file mode 100644
index 1925808..0000000
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (C) 2016 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 "OpenGLPipeline.h"
-
-#include "DeferredLayerUpdater.h"
-#include "EglManager.h"
-#include "Frame.h"
-#include "GlLayer.h"
-#include "OpenGLReadback.h"
-#include "ProfileRenderer.h"
-#include "TreeInfo.h"
-#include "renderstate/RenderState.h"
-
-#include <cutils/properties.h>
-#include <strings.h>
-
-namespace android {
-namespace uirenderer {
-namespace renderthread {
-
-OpenGLPipeline::OpenGLPipeline(RenderThread& thread)
-        : mEglManager(thread.eglManager()), mRenderThread(thread) {}
-
-MakeCurrentResult OpenGLPipeline::makeCurrent() {
-    // TODO: Figure out why this workaround is needed, see b/13913604
-    // In the meantime this matches the behavior of GLRenderer, so it is not a regression
-    EGLint error = 0;
-    bool haveNewSurface = mEglManager.makeCurrent(mEglSurface, &error);
-
-    Caches::getInstance().textureCache.resetMarkInUse(this);
-    if (!haveNewSurface) {
-        return MakeCurrentResult::AlreadyCurrent;
-    }
-    return error ? MakeCurrentResult::Failed : MakeCurrentResult::Succeeded;
-}
-
-Frame OpenGLPipeline::getFrame() {
-    LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
-                        "drawRenderNode called on a context with no surface!");
-    return mEglManager.beginFrame(mEglSurface);
-}
-
-bool OpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
-                          const FrameBuilder::LightGeometry& lightGeometry,
-                          LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds,
-                          bool opaque, bool wideColorGamut,
-                          const BakedOpRenderer::LightInfo& lightInfo,
-                          const std::vector<sp<RenderNode>>& renderNodes,
-                          FrameInfoVisualizer* profiler) {
-    mEglManager.damageFrame(frame, dirty);
-
-    bool drew = false;
-
-    auto& caches = Caches::getInstance();
-    FrameBuilder frameBuilder(dirty, frame.width(), frame.height(), lightGeometry, caches);
-
-    frameBuilder.deferLayers(*layerUpdateQueue);
-    layerUpdateQueue->clear();
-
-    frameBuilder.deferRenderNodeScene(renderNodes, contentDrawBounds);
-
-    BakedOpRenderer renderer(caches, mRenderThread.renderState(), opaque, wideColorGamut,
-                             lightInfo);
-    frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-    ProfileRenderer profileRenderer(renderer);
-    profiler->draw(profileRenderer);
-    drew = renderer.didDraw();
-
-    // post frame cleanup
-    caches.clearGarbage();
-    caches.pathCache.trim();
-    caches.tessellationCache.trim();
-
-#if DEBUG_MEMORY_USAGE
-    caches.dumpMemoryUsage();
-#else
-    if (CC_UNLIKELY(Properties::debugLevel & kDebugMemory)) {
-        caches.dumpMemoryUsage();
-    }
-#endif
-
-    return drew;
-}
-
-bool OpenGLPipeline::swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
-                                 FrameInfo* currentFrameInfo, bool* requireSwap) {
-    GL_CHECKPOINT(LOW);
-
-    // Even if we decided to cancel the frame, from the perspective of jank
-    // metrics the frame was swapped at this point
-    currentFrameInfo->markSwapBuffers();
-
-    *requireSwap = drew || mEglManager.damageRequiresSwap();
-
-    if (*requireSwap && (CC_UNLIKELY(!mEglManager.swapBuffers(frame, screenDirty)))) {
-        return false;
-    }
-
-    return *requireSwap;
-}
-
-bool OpenGLPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
-    ATRACE_CALL();
-    // acquire most recent buffer for drawing
-    layer->updateTexImage();
-    layer->apply();
-    return OpenGLReadbackImpl::copyLayerInto(mRenderThread,
-                                             static_cast<GlLayer&>(*layer->backingLayer()), bitmap);
-}
-
-static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
-                          SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) {
-    GlLayer* layer =
-            new GlLayer(renderState, layerWidth, layerHeight, colorFilter, alpha, mode, blend);
-    Caches::getInstance().textureState().activateTexture(0);
-    layer->generateTexture();
-    return layer;
-}
-
-DeferredLayerUpdater* OpenGLPipeline::createTextureLayer() {
-    mEglManager.initialize();
-    return new DeferredLayerUpdater(mRenderThread.renderState(), createLayer, Layer::Api::OpenGL);
-}
-
-void OpenGLPipeline::onStop() {
-    if (mEglManager.isCurrent(mEglSurface)) {
-        mEglManager.makeCurrent(EGL_NO_SURFACE);
-    }
-}
-
-bool OpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior, ColorMode colorMode) {
-    if (mEglSurface != EGL_NO_SURFACE) {
-        mEglManager.destroySurface(mEglSurface);
-        mEglSurface = EGL_NO_SURFACE;
-    }
-
-    if (surface) {
-        const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
-        mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
-    }
-
-    if (mEglSurface != EGL_NO_SURFACE) {
-        const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);
-        mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
-        return true;
-    }
-
-    return false;
-}
-
-bool OpenGLPipeline::isSurfaceReady() {
-    return CC_UNLIKELY(mEglSurface != EGL_NO_SURFACE);
-}
-
-bool OpenGLPipeline::isContextReady() {
-    return CC_LIKELY(mEglManager.hasEglContext());
-}
-
-void OpenGLPipeline::onDestroyHardwareResources() {
-    Caches& caches = Caches::getInstance();
-    // Make sure to release all the textures we were owning as there won't
-    // be another draw
-    caches.textureCache.resetMarkInUse(this);
-    mRenderThread.renderState().flush(Caches::FlushMode::Layers);
-}
-
-void OpenGLPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-                                  LayerUpdateQueue* layerUpdateQueue, bool opaque,
-                                  bool wideColorGamut,
-                                  const BakedOpRenderer::LightInfo& lightInfo) {
-    static const std::vector<sp<RenderNode>> emptyNodeList;
-    auto& caches = Caches::getInstance();
-    FrameBuilder frameBuilder(*layerUpdateQueue, lightGeometry, caches);
-    layerUpdateQueue->clear();
-    // TODO: Handle wide color gamut contexts
-    BakedOpRenderer renderer(caches, mRenderThread.renderState(), opaque, wideColorGamut,
-                             lightInfo);
-    LOG_ALWAYS_FATAL_IF(renderer.didDraw(), "shouldn't draw in buildlayer case");
-    frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-}
-
-TaskManager* OpenGLPipeline::getTaskManager() {
-    return &Caches::getInstance().tasks;
-}
-
-static bool layerMatchesWH(OffscreenBuffer* layer, int width, int height) {
-    return layer->viewportWidth == (uint32_t)width && layer->viewportHeight == (uint32_t)height;
-}
-
-bool OpenGLPipeline::createOrUpdateLayer(RenderNode* node,
-                                         const DamageAccumulator& damageAccumulator,
-                                         bool wideColorGamut, ErrorHandler* errorHandler) {
-    RenderState& renderState = mRenderThread.renderState();
-    OffscreenBufferPool& layerPool = renderState.layerPool();
-    bool transformUpdateNeeded = false;
-    if (node->getLayer() == nullptr) {
-        node->setLayer(
-                layerPool.get(renderState, node->getWidth(), node->getHeight(), wideColorGamut));
-        transformUpdateNeeded = true;
-    } else if (!layerMatchesWH(node->getLayer(), node->getWidth(), node->getHeight())) {
-        // TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering)
-        // Or, ideally, maintain damage between frames on node/layer so ordering is always correct
-        if (node->properties().fitsOnLayer()) {
-            node->setLayer(layerPool.resize(node->getLayer(), node->getWidth(), node->getHeight()));
-        } else {
-            destroyLayer(node);
-        }
-        transformUpdateNeeded = true;
-    }
-
-    if (transformUpdateNeeded && node->getLayer()) {
-        // update the transform in window of the layer to reset its origin wrt light source position
-        Matrix4 windowTransform;
-        damageAccumulator.computeCurrentTransform(&windowTransform);
-        node->getLayer()->setWindowTransform(windowTransform);
-    }
-
-    if (!node->hasLayer()) {
-        Caches::getInstance().dumpMemoryUsage();
-        if (errorHandler) {
-            std::ostringstream err;
-            err << "Unable to create layer for " << node->getName();
-            const int maxTextureSize = Caches::getInstance().maxTextureSize;
-            if (node->getWidth() > maxTextureSize || node->getHeight() > maxTextureSize) {
-                err << ", size " << node->getWidth() << "x" << node->getHeight()
-                    << " exceeds max size " << maxTextureSize;
-            } else {
-                err << ", see logcat for more info";
-            }
-            errorHandler->onError(err.str());
-        }
-    }
-
-    return transformUpdateNeeded;
-}
-
-bool OpenGLPipeline::pinImages(LsaVector<sk_sp<Bitmap>>& images) {
-    TextureCache& cache = Caches::getInstance().textureCache;
-    bool prefetchSucceeded = true;
-    for (auto& bitmapResource : images) {
-        prefetchSucceeded &= cache.prefetchAndMarkInUse(this, bitmapResource.get());
-    }
-    return prefetchSucceeded;
-}
-
-void OpenGLPipeline::unpinImages() {
-    Caches::getInstance().textureCache.resetMarkInUse(this);
-}
-
-void OpenGLPipeline::destroyLayer(RenderNode* node) {
-    if (OffscreenBuffer* layer = node->getLayer()) {
-        layer->renderState.layerPool().putOrDelete(layer);
-        node->setLayer(nullptr);
-    }
-}
-
-void OpenGLPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
-    if (Caches::hasInstance() && thread.eglManager().hasEglContext()) {
-        ATRACE_NAME("Bitmap#prepareToDraw task");
-        Caches::getInstance().textureCache.prefetch(bitmap);
-    }
-}
-
-void OpenGLPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
-    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
-    if (thread.eglManager().hasEglContext()) {
-        mode = DrawGlInfo::kModeProcess;
-    }
-    thread.renderState().invokeFunctor(functor, mode, nullptr);
-}
-
-#define FENCE_TIMEOUT 2000000000
-
-class AutoEglFence {
-public:
-    AutoEglFence(EGLDisplay display) : mDisplay(display) {
-        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
-    }
-
-    ~AutoEglFence() {
-        if (fence != EGL_NO_SYNC_KHR) {
-            eglDestroySyncKHR(mDisplay, fence);
-        }
-    }
-
-    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
-
-private:
-    EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
-class AutoEglImage {
-public:
-    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer) : mDisplay(display) {
-        EGLint imageAttrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
-        image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer,
-                                  imageAttrs);
-    }
-
-    ~AutoEglImage() {
-        if (image != EGL_NO_IMAGE_KHR) {
-            eglDestroyImageKHR(mDisplay, image);
-        }
-    }
-
-    EGLImageKHR image = EGL_NO_IMAGE_KHR;
-
-private:
-    EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
-class AutoGlTexture {
-public:
-    AutoGlTexture(uirenderer::Caches& caches) : mCaches(caches) {
-        glGenTextures(1, &mTexture);
-        caches.textureState().bindTexture(mTexture);
-    }
-
-    ~AutoGlTexture() { mCaches.textureState().deleteTexture(mTexture); }
-
-private:
-    uirenderer::Caches& mCaches;
-    GLuint mTexture = 0;
-};
-
-static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
-                                        GraphicBuffer& buffer, GLint format, GLint type) {
-    EGLDisplay display = eglGetCurrentDisplay();
-    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY, "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
-                        uirenderer::renderthread::EglManager::eglErrorString());
-    // We use an EGLImage to access the content of the GraphicBuffer
-    // The EGL image is later bound to a 2D texture
-    EGLClientBuffer clientBuffer = (EGLClientBuffer)buffer.getNativeBuffer();
-    AutoEglImage autoImage(display, clientBuffer);
-    if (autoImage.image == EGL_NO_IMAGE_KHR) {
-        ALOGW("Could not create EGL image, err =%s",
-              uirenderer::renderthread::EglManager::eglErrorString());
-        return false;
-    }
-    AutoGlTexture glTexture(caches);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
-
-    GL_CHECKPOINT(MODERATE);
-
-    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(), format, type,
-                    bitmap.getPixels());
-
-    GL_CHECKPOINT(MODERATE);
-
-    // The fence is used to wait for the texture upload to finish
-    // properly. We cannot rely on glFlush() and glFinish() as
-    // some drivers completely ignore these API calls
-    AutoEglFence autoFence(display);
-    if (autoFence.fence == EGL_NO_SYNC_KHR) {
-        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
-        return false;
-    }
-    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
-    // pipeline flush (similar to what a glFlush() would do.)
-    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
-                                             EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
-    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
-        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
-        return false;
-    }
-    return true;
-}
-
-// TODO: handle SRGB sanely
-static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
-    switch (internalFormat) {
-        case GL_LUMINANCE:
-            return PIXEL_FORMAT_RGBA_8888;
-        case GL_SRGB8_ALPHA8:
-            return PIXEL_FORMAT_RGBA_8888;
-        case GL_RGBA:
-            return PIXEL_FORMAT_RGBA_8888;
-        case GL_RGB:
-            return PIXEL_FORMAT_RGB_565;
-        case GL_RGBA16F:
-            return PIXEL_FORMAT_RGBA_FP16;
-        default:
-            LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
-            return PIXEL_FORMAT_UNKNOWN;
-    }
-}
-
-sk_sp<Bitmap> OpenGLPipeline::allocateHardwareBitmap(RenderThread& renderThread,
-                                                     SkBitmap& skBitmap) {
-    renderThread.eglManager().initialize();
-    uirenderer::Caches& caches = uirenderer::Caches::getInstance();
-
-    const SkImageInfo& info = skBitmap.info();
-    if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
-        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
-        return nullptr;
-    }
-
-    bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
-    bool hasLinearBlending = caches.extensions().hasLinearBlending();
-    GLint format, type, internalFormat;
-    uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
-                                                    needSRGB && hasLinearBlending, &internalFormat,
-                                                    &format, &type);
-
-    PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
-    sp<GraphicBuffer> buffer = new GraphicBuffer(
-            info.width(), info.height(), pixelFormat,
-            GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER |
-                    GraphicBuffer::USAGE_SW_READ_NEVER,
-            std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
-
-    status_t error = buffer->initCheck();
-    if (error < 0) {
-        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
-        return nullptr;
-    }
-
-    SkBitmap bitmap;
-    if (CC_UNLIKELY(
-                uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(), hasLinearBlending))) {
-        sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
-        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
-    } else {
-        bitmap = skBitmap;
-    }
-
-    if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
-        return nullptr;
-    }
-    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
-}
-
-} /* namespace renderthread */
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
deleted file mode 100644
index 9859e93..0000000
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 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 "BakedOpDispatcher.h"
-#include "BakedOpRenderer.h"
-#include "CanvasContext.h"
-#include "FrameBuilder.h"
-#include "IRenderPipeline.h"
-
-namespace android {
-namespace uirenderer {
-namespace renderthread {
-
-class OpenGLPipeline : public IRenderPipeline {
-public:
-    OpenGLPipeline(RenderThread& thread);
-    virtual ~OpenGLPipeline() {}
-
-    MakeCurrentResult makeCurrent() override;
-    Frame getFrame() override;
-    bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
-              const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
-              const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
-              const BakedOpRenderer::LightInfo& lightInfo,
-              const std::vector<sp<RenderNode>>& renderNodes,
-              FrameInfoVisualizer* profiler) override;
-    bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
-                     FrameInfo* currentFrameInfo, bool* requireSwap) override;
-    bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
-    DeferredLayerUpdater* createTextureLayer() override;
-    bool setSurface(Surface* window, SwapBehavior swapBehavior, ColorMode colorMode) override;
-    void onStop() override;
-    bool isSurfaceReady() override;
-    bool isContextReady() override;
-    void onDestroyHardwareResources() override;
-    void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
-                      LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
-                      const BakedOpRenderer::LightInfo& lightInfo) override;
-    TaskManager* getTaskManager() override;
-    bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
-                             bool wideColorGamut, ErrorHandler* errorHandler) override;
-    bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
-    bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override;
-    void unpinImages() override;
-    void onPrepareTree() override {}
-    static void destroyLayer(RenderNode* node);
-    static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
-    static void invokeFunctor(const RenderThread& thread, Functor* functor);
-    static sk_sp<Bitmap> allocateHardwareBitmap(RenderThread& thread, SkBitmap& skBitmap);
-
-private:
-    EglManager& mEglManager;
-    EGLSurface mEglSurface = EGL_NO_SURFACE;
-    bool mBufferPreserved = false;
-    RenderThread& mRenderThread;
-};
-
-} /* namespace renderthread */
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index f4d230e..84f43ec 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -19,7 +19,6 @@
 #include "CanvasContext.h"
 #include "DeviceInfo.h"
 #include "EglManager.h"
-#include "OpenGLReadback.h"
 #include "RenderProxy.h"
 #include "VulkanManager.h"
 #include "hwui/Bitmap.h"
@@ -28,7 +27,6 @@
 #include "pipeline/skia/SkiaVulkanPipeline.h"
 #include "pipeline/skia/SkiaVulkanReadback.h"
 #include "renderstate/RenderState.h"
-#include "renderthread/OpenGLPipeline.h"
 #include "utils/FatVector.h"
 #include "utils/TimeUtils.h"
 
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index f51e7cc..16c5afd 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -24,7 +24,6 @@
 #include <pipeline/skia/SkiaOpenGLPipeline.h>
 #include <pipeline/skia/SkiaVulkanPipeline.h>
 #include <renderthread/EglManager.h>
-#include <renderthread/OpenGLPipeline.h>
 #include <renderthread/VulkanManager.h>
 #include <utils/Unicode.h>