OSDN Git Service

Unify readback Surface/TextureView copy mechanism
authorChris Craik <ccraik@google.com>
Thu, 7 Jul 2016 00:14:05 +0000 (17:14 -0700)
committerChris Craik <ccraik@google.com>
Thu, 7 Jul 2016 17:02:12 +0000 (10:02 -0700)
Removes last usage of old rendering pipeline.

Change-Id: Ia920dec9cd726ca221e11e888562c7df39a9761e

libs/hwui/LayerRenderer.cpp
libs/hwui/LayerRenderer.h
libs/hwui/Readback.cpp
libs/hwui/Readback.h
libs/hwui/renderthread/CanvasContext.cpp

index 137316f..405165f 100644 (file)
@@ -351,115 +351,5 @@ void LayerRenderer::flushLayer(RenderState& renderState, Layer* layer) {
 #endif
 }
 
-bool LayerRenderer::copyLayer(RenderState& renderState, Layer* layer, SkBitmap* bitmap) {
-    Caches& caches = Caches::getInstance();
-    if (layer && layer->isRenderable()
-            && bitmap->width() <= caches.maxTextureSize
-            && bitmap->height() <= caches.maxTextureSize) {
-
-        GLuint fbo = renderState.createFramebuffer();
-        if (!fbo) {
-            ALOGW("Could not obtain an FBO");
-            return false;
-        }
-
-        SkAutoLockPixels alp(*bitmap);
-
-        GLuint texture;
-        GLuint previousFbo;
-        GLsizei previousViewportWidth;
-        GLsizei previousViewportHeight;
-
-        GLenum format;
-        GLenum type;
-
-        bool status = false;
-
-        switch (bitmap->colorType()) {
-            case kAlpha_8_SkColorType:
-                format = GL_ALPHA;
-                type = GL_UNSIGNED_BYTE;
-                break;
-            case kRGB_565_SkColorType:
-                format = GL_RGB;
-                type = GL_UNSIGNED_SHORT_5_6_5;
-                break;
-            case kARGB_4444_SkColorType:
-                format = GL_RGBA;
-                type = GL_UNSIGNED_SHORT_4_4_4_4;
-                break;
-            case kN32_SkColorType:
-            default:
-                format = GL_RGBA;
-                type = GL_UNSIGNED_BYTE;
-                break;
-        }
-
-        float alpha = layer->getAlpha();
-        SkXfermode::Mode mode = layer->getMode();
-        GLuint previousLayerFbo = layer->getFbo();
-
-        layer->setAlpha(255, SkXfermode::kSrc_Mode);
-        layer->setFbo(fbo);
-
-        previousFbo = renderState.getFramebuffer();
-        renderState.getViewport(&previousViewportWidth, &previousViewportHeight);
-        renderState.bindFramebuffer(fbo);
-
-        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, format, bitmap->width(), bitmap->height(),
-                0, format, type, nullptr);
-
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                GL_TEXTURE_2D, texture, 0);
-
-        {
-            LayerRenderer renderer(renderState, layer);
-            renderer.OpenGLRenderer::prepareDirty(bitmap->width(), bitmap->height(),
-                    0.0f, 0.0f, bitmap->width(), bitmap->height(), !layer->isBlend());
-
-            renderState.scissor().setEnabled(false);
-            renderer.translate(0.0f, bitmap->height());
-            renderer.scale(1.0f, -1.0f);
-
-            {
-                Rect bounds;
-                bounds.set(0.0f, 0.0f, bitmap->width(), bitmap->height());
-                renderer.drawTextureLayer(layer, bounds);
-
-                glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
-                        type, bitmap->getPixels());
-
-            }
-
-            status = true;
-        }
-
-        renderState.bindFramebuffer(previousFbo);
-        layer->setAlpha(alpha, mode);
-        layer->setFbo(previousLayerFbo);
-        caches.textureState().deleteTexture(texture);
-        renderState.deleteFramebuffer(fbo);
-        renderState.setViewport(previousViewportWidth, previousViewportHeight);
-
-        GL_CHECKPOINT(MODERATE);
-
-        return status;
-    }
-    return false;
-}
-
 }; // namespace uirenderer
 }; // namespace android
index 38c3705..1fb6b14 100644 (file)
@@ -61,7 +61,6 @@ public:
     static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
             bool isOpaque, bool forceFilter, GLenum renderTarget, const float* textureTransform);
     static void destroyLayer(Layer* layer);
-    static bool copyLayer(RenderState& renderState, Layer* layer, SkBitmap* bitmap);
 
     static void flushLayer(RenderState& renderState, Layer* layer);
 
index 55f823d..60eadff 100644 (file)
@@ -19,6 +19,7 @@
 #include "Caches.h"
 #include "Image.h"
 #include "GlopBuilder.h"
+#include "Layer.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/EglManager.h"
 #include "utils/GLUtils.h"
 namespace android {
 namespace uirenderer {
 
-CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
-        Surface& surface, SkBitmap* bitmap) {
-    // TODO: Clean this up and unify it with LayerRenderer::copyLayer,
-    // of which most of this is copied from.
-    renderThread.eglManager().initialize();
-
-    Caches& caches = Caches::getInstance();
-    RenderState& renderState = renderThread.renderState();
+static CopyResult copyTextureInto(Caches& caches, RenderState& renderState,
+        Texture& sourceTexture, Matrix4& texTransform, SkBitmap* bitmap) {
     int destWidth = bitmap->width();
     int destHeight = bitmap->height();
     if (destWidth > caches.maxTextureSize
@@ -98,6 +93,44 @@ CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
             GL_TEXTURE_2D, texture, 0);
 
+    {
+        // Draw & readback
+        renderState.setViewport(destWidth, destHeight);
+        renderState.scissor().setEnabled(false);
+        renderState.blend().syncEnabled();
+        renderState.stencil().disable();
+
+        Glop glop;
+        GlopBuilder(renderState, caches, &glop)
+                .setRoundRectClipState(nullptr)
+                .setMeshTexturedUnitQuad(nullptr)
+                .setFillExternalTexture(sourceTexture, texTransform)
+                .setTransform(Matrix4::identity(), TransformFlags::None)
+                .setModelViewMapUnitToRect(Rect(destWidth, destHeight))
+                .build();
+        Matrix4 ortho;
+        ortho.loadOrtho(destWidth, destHeight);
+        renderState.render(glop, ortho);
+
+        glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
+                type, bitmap->getPixels());
+    }
+
+    // Cleanup
+    caches.textureState().deleteTexture(texture);
+    renderState.deleteFramebuffer(fbo);
+
+    GL_CHECKPOINT(MODERATE);
+
+    return CopyResult::Success;
+}
+
+CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
+        Surface& surface, SkBitmap* bitmap) {
+    renderThread.eglManager().initialize();
+
+    Caches& caches = Caches::getInstance();
+
     // Setup the source
     sp<GraphicBuffer> sourceBuffer;
     sp<Fence> sourceFence;
@@ -142,7 +175,7 @@ CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
     GLuint sourceTexId;
     // Create a 2D texture to sample from the EGLImage
     glGenTextures(1, &sourceTexId);
-    Caches::getInstance().textureState().bindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId);
+    caches.textureState().bindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId);
     glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, sourceImage);
 
     GLenum status = GL_NO_ERROR;
@@ -155,37 +188,13 @@ CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
     sourceTexture.wrap(sourceTexId,
             sourceBuffer->getWidth(), sourceBuffer->getHeight(), 0 /* total lie */);
 
-    {
-        // Draw & readback
-        renderState.setViewport(destWidth, destHeight);
-        renderState.scissor().setEnabled(false);
-        renderState.blend().syncEnabled();
-        renderState.stencil().disable();
-
-        Rect destRect(destWidth, destHeight);
-        Glop glop;
-        GlopBuilder(renderState, caches, &glop)
-                .setRoundRectClipState(nullptr)
-                .setMeshTexturedUnitQuad(nullptr)
-                .setFillExternalTexture(sourceTexture, texTransform)
-                .setTransform(Matrix4::identity(), TransformFlags::None)
-                .setModelViewMapUnitToRect(destRect)
-                .build();
-        Matrix4 ortho;
-        ortho.loadOrtho(destWidth, destHeight);
-        renderState.render(glop, ortho);
-
-        glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
-                type, bitmap->getPixels());
-    }
-
-    // Cleanup
-    caches.textureState().deleteTexture(texture);
-    renderState.deleteFramebuffer(fbo);
-
-    GL_CHECKPOINT(MODERATE);
+    return copyTextureInto(caches, renderThread.renderState(), sourceTexture, texTransform, bitmap);
+}
 
-    return CopyResult::Success;
+CopyResult Readback::copyTextureLayerInto(renderthread::RenderThread& renderThread,
+        Layer& layer, SkBitmap* bitmap) {
+    return copyTextureInto(Caches::getInstance(), renderThread.renderState(),
+            layer.getTexture(), layer.getTexTransform(), bitmap);
 }
 
 } // namespace uirenderer
index a112c42..bd73734 100644 (file)
@@ -24,6 +24,8 @@
 namespace android {
 namespace uirenderer {
 
+class Layer;
+
 // Keep in sync with PixelCopy.java codes
 enum class CopyResult {
     Success = 0,
@@ -36,8 +38,18 @@ enum class CopyResult {
 
 class Readback {
 public:
+    /**
+     * Copies the surface's most recently queued buffer into the provided bitmap.
+     */
     static CopyResult copySurfaceInto(renderthread::RenderThread& renderThread,
             Surface& surface, SkBitmap* bitmap);
+
+    /**
+     * Copies the TextureLayer's texture content (thus, the currently rendering buffer) into the
+     * provided bitmap.
+     */
+    static CopyResult copyTextureLayerInto(renderthread::RenderThread& renderThread,
+            Layer& layer, SkBitmap* bitmap);
 };
 
 } // namespace uirenderer
index 0a48a0c..4a45071 100644 (file)
@@ -25,6 +25,7 @@
 #include "LayerRenderer.h"
 #include "OpenGLRenderer.h"
 #include "Properties.h"
+#include "Readback.h"
 #include "RenderThread.h"
 #include "hwui/Canvas.h"
 #include "renderstate/RenderState.h"
@@ -648,7 +649,8 @@ void CanvasContext::buildLayer(RenderNode* node, TreeObserver* observer) {
 
 bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
     layer->apply();
-    return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
+    return Readback::copyTextureLayerInto(mRenderThread, *(layer->backingLayer()), bitmap)
+            == CopyResult::Success;
 }
 
 void CanvasContext::destroyHardwareResources(TreeObserver* observer) {