OSDN Git Service

Move bitmap transforms out of bitmap ops
authorChris Craik <ccraik@google.com>
Wed, 6 Aug 2014 20:42:24 +0000 (13:42 -0700)
committerChris Craik <ccraik@google.com>
Wed, 6 Aug 2014 21:11:31 +0000 (21:11 +0000)
bug:11359533

This allows us to deduplicate a lot between the two ops, and fixes the
shader coordinate space for the left,top argument drawBitmap to match
software.

Change-Id: I53da05af9ee74c74e9e70b4ab8053190ca220b16

core/jni/android_view_GLES20Canvas.cpp
libs/hwui/DisplayListOp.h
libs/hwui/DisplayListRenderer.cpp
libs/hwui/DisplayListRenderer.h
libs/hwui/OpenGLRenderer.cpp
libs/hwui/OpenGLRenderer.h
libs/hwui/Renderer.h

index ce76b26..afcfaf6 100644 (file)
@@ -348,7 +348,12 @@ static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
 
     DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-    renderer->drawBitmap(bitmap, left, top, paint);
+
+    // apply transform directly to canvas, so it affects shaders correctly
+    renderer->save(SkCanvas::kMatrix_SaveFlag);
+    renderer->translate(left, top);
+    renderer->drawBitmap(bitmap, paint);
+    renderer->restore();
 }
 
 static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
@@ -375,7 +380,12 @@ static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject claz
     DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-    renderer->drawBitmap(bitmap, *matrix, paint);
+
+    // apply transform directly to canvas, so it affects shaders correctly
+    renderer->save(SkCanvas::kMatrix_SaveFlag);
+    renderer->concatMatrix(*matrix);
+    renderer->drawBitmap(bitmap, paint);
+    renderer->restore();
 }
 
 static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
@@ -399,7 +409,12 @@ static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
 
     DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-    renderer->drawBitmapData(bitmap, left, top, paint);
+
+    // apply transform directly to canvas, so it affects shaders correctly
+    renderer->save(SkCanvas::kMatrix_SaveFlag);
+    renderer->translate(left, top);
+    renderer->drawBitmapData(bitmap, paint);
+    renderer->restore();
 
     // Note - bitmap isn't deleted as DisplayListRenderer owns it now
 }
index 777a35a..6883cc5 100644 (file)
@@ -639,9 +639,10 @@ private:
 
 class DrawBitmapOp : public DrawBoundedOp {
 public:
-    DrawBitmapOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint)
-            : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint),
-            mBitmap(bitmap), mAtlas(Caches::getInstance().assetAtlas) {
+    DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint)
+            : DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint)
+            , mBitmap(bitmap)
+            , mAtlas(Caches::getInstance().assetAtlas) {
         mEntry = mAtlas.getEntry(bitmap);
         if (mEntry) {
             mEntryGenerationId = mAtlas.getGenerationId();
@@ -650,8 +651,7 @@ public:
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
-        return renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top,
-                getPaint(renderer));
+        return renderer.drawBitmap(mBitmap, getPaint(renderer));
     }
 
     AssetAtlas::Entry* getAtlasEntry() {
@@ -745,35 +745,6 @@ protected:
     UvMapper mUvMapper;
 };
 
-class DrawBitmapMatrixOp : public DrawBoundedOp {
-public:
-    DrawBitmapMatrixOp(const SkBitmap* bitmap, const SkMatrix& matrix, const SkPaint* paint)
-            : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) {
-        mLocalBounds.set(0, 0, bitmap->width(), bitmap->height());
-        const mat4 transform(matrix);
-        transform.mapRect(mLocalBounds);
-    }
-
-    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
-        return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer));
-    }
-
-    virtual void output(int level, uint32_t logFlags) const {
-        OP_LOG("Draw bitmap %p matrix " SK_MATRIX_STRING, mBitmap, SK_MATRIX_ARGS(&mMatrix));
-    }
-
-    virtual const char* name() { return "DrawBitmapMatrix"; }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) {
-        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-    }
-
-private:
-    const SkBitmap* mBitmap;
-    const SkMatrix mMatrix;
-};
-
 class DrawBitmapRectOp : public DrawBoundedOp {
 public:
     DrawBitmapRectOp(const SkBitmap* bitmap,
@@ -807,12 +778,11 @@ private:
 
 class DrawBitmapDataOp : public DrawBitmapOp {
 public:
-    DrawBitmapDataOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint)
-            : DrawBitmapOp(bitmap, left, top, paint) {}
+    DrawBitmapDataOp(const SkBitmap* bitmap, const SkPaint* paint)
+            : DrawBitmapOp(bitmap, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
-        return renderer.drawBitmapData(mBitmap, mLocalBounds.left,
-                mLocalBounds.top, getPaint(renderer));
+        return renderer.drawBitmapData(mBitmap, getPaint(renderer));
     }
 
     virtual void output(int level, uint32_t logFlags) const {
index 5286ef8..b210e64 100644 (file)
@@ -194,51 +194,42 @@ status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) {
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top,
-        const SkPaint* paint) {
-    bitmap = refBitmap(bitmap);
-    paint = refPaint(paint);
-
-    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint));
-    return DrawGlInfo::kStatusDone;
-}
-
-status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-        const SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     paint = refPaint(paint);
 
-    addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint));
+    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop,
         float dstRight, float dstBottom, const SkPaint* paint) {
-    bitmap = refBitmap(bitmap);
-    paint = refPaint(paint);
-
-    if (srcLeft == 0 && srcTop == 0 &&
-            srcRight == bitmap->width() && srcBottom == bitmap->height() &&
-            (srcBottom - srcTop == dstBottom - dstTop) &&
-            (srcRight - srcLeft == dstRight - dstLeft)) {
+    if (srcLeft == 0 && srcTop == 0
+            && srcRight == bitmap->width() && srcBottom == bitmap->height()
+            && (srcBottom - srcTop == dstBottom - dstTop)
+            && (srcRight - srcLeft == dstRight - dstLeft)) {
         // transform simple rect to rect drawing case into position bitmap ops, since they merge
-        addDrawOp(new (alloc()) DrawBitmapOp(bitmap, dstLeft, dstTop, paint));
-        return DrawGlInfo::kStatusDone;
-    }
+        save(SkCanvas::kMatrix_SaveFlag);
+        translate(dstLeft, dstTop);
+        drawBitmap(bitmap, paint);
+        restore();
+    } else {
+        bitmap = refBitmap(bitmap);
+        paint = refPaint(paint);
 
-    addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
-                    srcLeft, srcTop, srcRight, srcBottom,
-                    dstLeft, dstTop, dstRight, dstBottom, paint));
+        addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
+                srcLeft, srcTop, srcRight, srcBottom,
+                dstLeft, dstTop, dstRight, dstBottom, paint));
+    }
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top,
-        const SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
     bitmap = refBitmapData(bitmap);
     paint = refPaint(paint);
 
-    addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint));
+    addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint));
     return DrawGlInfo::kStatusDone;
 }
 
index d1d8572..1b3a48a 100644 (file)
@@ -105,15 +105,11 @@ public:
     virtual status_t drawColor(int color, SkXfermode::Mode mode);
 
     // Bitmap-based
-    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint);
-    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
     virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint);
-    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint);
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
     virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint);
     virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
index 5fbef2e..e00d2e3 100755 (executable)
@@ -2034,12 +2034,8 @@ status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry*
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top,
-        const SkPaint* paint) {
-    const float right = left + bitmap->width();
-    const float bottom = top + bitmap->height();
-
-    if (quickRejectSetupScissor(left, top, right, bottom)) {
+status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
+    if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2049,49 +2045,16 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float left, float to
     const AutoTexture autoCleanup(texture);
 
     if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
-        drawAlphaBitmap(texture, left, top, paint);
+        drawAlphaBitmap(texture, 0, 0, paint);
     } else {
-        drawTextureRect(left, top, right, bottom, texture, paint);
+        drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint);
     }
 
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-        const SkPaint* paint) {
-    Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
-    const mat4 transform(matrix);
-    transform.mapRect(r);
-
-    if (quickRejectSetupScissor(r.left, r.top, r.right, r.bottom)) {
-        return DrawGlInfo::kStatusDone;
-    }
-
-    mCaches.activeTexture(0);
-    Texture* texture = getTexture(bitmap);
-    if (!texture) return DrawGlInfo::kStatusDone;
-    const AutoTexture autoCleanup(texture);
-
-    // This could be done in a cheaper way, all we need is pass the matrix
-    // to the vertex shader. The save/restore is a bit overkill.
-    save(SkCanvas::kMatrix_SaveFlag);
-    concatMatrix(matrix);
-    if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
-        drawAlphaBitmap(texture, 0.0f, 0.0f, paint);
-    } else {
-        drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint);
-    }
-    restore();
-
-    return DrawGlInfo::kStatusDrew;
-}
-
-status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top,
-        const SkPaint* paint) {
-    const float right = left + bitmap->width();
-    const float bottom = top + bitmap->height();
-
-    if (quickRejectSetupScissor(left, top, right, bottom)) {
+status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) {
+    if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2100,9 +2063,9 @@ status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, float left, floa
     const AutoTexture autoCleanup(texture);
 
     if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
-        drawAlphaBitmap(texture, left, top, paint);
+        drawAlphaBitmap(texture, 0, 0, paint);
     } else {
-        drawTextureRect(left, top, right, bottom, texture, paint);
+        drawTextureRect(0, 0, bitmap->width(), bitmap->height(), texture, paint);
     }
 
     return DrawGlInfo::kStatusDrew;
index 3bc591f..fd228db 100755 (executable)
@@ -161,17 +161,13 @@ public:
 
     virtual status_t drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
     virtual status_t drawLayer(Layer* layer, float x, float y);
-    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
     status_t drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
             TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
-    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-            const SkPaint* paint);
     virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint);
-    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint);
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
     virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint);
     status_t drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
index 40a21e4..f5cd266 100644 (file)
@@ -160,15 +160,11 @@ public:
     virtual status_t drawColor(int color, SkXfermode::Mode mode) = 0;
 
     // Bitmap-based
-    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint) = 0;
-    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix& matrix,
-            const SkPaint* paint) = 0;
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) = 0;
     virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint) = 0;
-    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
-            const SkPaint* paint) = 0;
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) = 0;
     virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint) = 0;
     virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,