Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79647500 authored by Chris Craik's avatar Chris Craik
Browse files

Move bitmap transforms out of bitmap ops

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
parent d1a7fca1
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -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
}
+8 −38
Original line number Diff line number Diff line
@@ -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 {
+19 −28
Original line number Diff line number Diff line
@@ -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) {
    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
        save(SkCanvas::kMatrix_SaveFlag);
        translate(dstLeft, dstTop);
        drawBitmap(bitmap, paint);
        restore();
    } else {
        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)) {
        // 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;
    }

        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;
}

+2 −6
Original line number Diff line number Diff line
@@ -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,
+8 −45
Original line number Diff line number Diff line
@@ -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;
Loading