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

Commit 1a831278 authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Glop support for custom textured UVs, simplify drawBitmap(src,dst)"

parents fb10ffe4 14100ac9
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -713,9 +713,7 @@ public:
            mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}

    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
        renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom,
                mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
                mPaint);
        renderer.drawBitmap(mBitmap, mSrc, mLocalBounds, mPaint);
    }

    virtual void output(int level, uint32_t logFlags) const override {
+26 −1
Original line number Diff line number Diff line
@@ -258,7 +258,8 @@ void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float srcLeft, floa
        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()
            && 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
@@ -269,6 +270,30 @@ void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float srcLeft, floa
    } else {
        paint = refPaint(paint);

        if (paint && paint->getShader()) {
            float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft);
            float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop);
            if (!MathUtils::areEqual(scaleX, 1.0f) || !MathUtils::areEqual(scaleY, 1.0f)) {
                // Apply the scale transform on the canvas, so that the shader
                // effectively calculates positions relative to src rect space

                save(SkCanvas::kMatrix_SaveFlag);
                translate(dstLeft, dstTop);
                scale(scaleX, scaleY);

                dstLeft = 0.0f;
                dstTop = 0.0f;
                dstRight = srcRight - srcLeft;
                dstBottom = srcBottom - srcTop;

                addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap),
                        srcLeft, srcTop, srcRight, srcBottom,
                        dstLeft, dstTop, dstRight, dstBottom, paint));
                restore();
                return;
            }
        }

        addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap),
                srcLeft, srcTop, srcRight, srcBottom,
                dstLeft, dstTop, dstRight, dstBottom, paint));
+31 −16
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ namespace android {
namespace uirenderer {

#define TRIGGER_STAGE(stageFlag) \
    LOG_ALWAYS_FATAL_IF(stageFlag & mStageFlags, "Stage %d cannot be run twice"); \
    LOG_ALWAYS_FATAL_IF((stageFlag) & mStageFlags, "Stage %d cannot be run twice", (stageFlag)); \
    mStageFlags = static_cast<StageFlags>(mStageFlags | (stageFlag))

#define REQUIRE_STAGES(requiredFlags) \
@@ -40,10 +40,10 @@ namespace uirenderer {
            "not prepared for current stage")

static void setUnitQuadTextureCoords(Rect uvs, TextureVertex* quadVertex) {
    TextureVertex::setUV(quadVertex++, uvs.left, uvs.top);
    TextureVertex::setUV(quadVertex++, uvs.right, uvs.top);
    TextureVertex::setUV(quadVertex++, uvs.left, uvs.bottom);
    TextureVertex::setUV(quadVertex++, uvs.right, uvs.bottom);
    quadVertex[0] = {0, 0, uvs.left, uvs.top};
    quadVertex[1] = {1, 0, uvs.right, uvs.top};
    quadVertex[2] = {0, 1, uvs.left, uvs.bottom};
    quadVertex[3] = {1, 1, uvs.right, uvs.bottom};
}

GlopBuilder::GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop)
@@ -74,25 +74,40 @@ GlopBuilder& GlopBuilder::setMeshUnitQuad() {
}

GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper) {
    if (uvMapper) {
        // can't use unit quad VBO, so build UV vertices manually
        return setMeshTexturedUvQuad(uvMapper, Rect(0, 0, 1, 1));
    }

    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.vertexFlags = kTextureCoord_Attrib;
    mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
    mOutGlop->mesh.vertexBufferObject = mRenderState.meshState().getUnitQuadVBO();
    mOutGlop->mesh.vertices = nullptr;
    mOutGlop->mesh.texCoordOffset = (GLvoid*) kMeshTextureOffset;
    mOutGlop->mesh.indexBufferObject = 0;
    mOutGlop->mesh.indices = nullptr;
    mOutGlop->mesh.elementCount = 4;
    mOutGlop->mesh.stride = kTextureVertexStride;
    mDescription.hasTexture = true;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshTexturedUvQuad(const UvMapper* uvMapper, Rect uvs) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.vertexFlags = kTextureCoord_Attrib;
    mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP;

    if (CC_UNLIKELY(uvMapper)) {
        Rect uvs(0, 0, 1, 1);
        uvMapper->map(uvs);
    }
    setUnitQuadTextureCoords(uvs, &mOutGlop->mesh.mappedVertices[0]);

    mOutGlop->mesh.vertexBufferObject = 0;
        mOutGlop->mesh.vertices = &mOutGlop->mesh.mappedVertices[0];
    mOutGlop->mesh.vertices = &mOutGlop->mesh.mappedVertices[0].x;
    mOutGlop->mesh.texCoordOffset = &mOutGlop->mesh.mappedVertices[0].u;
    } else {
        // standard UV coordinates, use regular unit quad VBO
        mOutGlop->mesh.vertexBufferObject = mRenderState.meshState().getUnitQuadVBO();
        mOutGlop->mesh.vertices = nullptr;
        mOutGlop->mesh.texCoordOffset = (GLvoid*) kMeshTextureOffset;
    }
    mOutGlop->mesh.indexBufferObject = 0;
    mOutGlop->mesh.indices = nullptr;
    mOutGlop->mesh.elementCount = 4;
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ public:

    GlopBuilder& setMeshUnitQuad();
    GlopBuilder& setMeshTexturedUnitQuad(const UvMapper* uvMapper);
    GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs);
    GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp);
    GlopBuilder& setMeshIndexedQuads(void* vertexData, int quadCount);
    GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount); // TODO: take quadCount
+38 −41
Original line number Diff line number Diff line
@@ -2185,26 +2185,43 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m
    mDirty = true;
}

void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,
         float srcLeft, float srcTop, float srcRight, float srcBottom,
         float dstLeft, float dstTop, float dstRight, float dstBottom,
         const SkPaint* paint) {
    if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) {
void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, const SkPaint* paint) {
    if (quickRejectSetupScissor(dst)) {
        return;
    }

    mCaches.textureState().activateTexture(0);
    Texture* texture = getTexture(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    if (USE_GLOPS) {
        Rect uv(fmax(0.0f, src.left / texture->width),
                fmax(0.0f, src.top / texture->height),
                fmin(1.0f, src.right / texture->width),
                fmin(1.0f, src.bottom / texture->height));

        bool isAlpha8Texture = bitmap->colorType() == kAlpha_8_SkColorType;
        Glop glop;
        GlopBuilder aBuilder(mRenderState, mCaches, &glop);
        aBuilder.setMeshTexturedUvQuad(texture->uvMapper, uv)
                .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha)
                .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false)
                .setModelViewMapUnitToRectSnap(dst)
                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
                .build();
        renderGlop(glop);
        return;
    }

    mCaches.textureState().activateTexture(0);

    const float width = texture->width;
    const float height = texture->height;

    float u1 = fmax(0.0f, srcLeft / width);
    float v1 = fmax(0.0f, srcTop / height);
    float u2 = fmin(1.0f, srcRight / width);
    float v2 = fmin(1.0f, srcBottom / height);
    float u1 = fmax(0.0f, src.left / width);
    float v1 = fmax(0.0f, src.top / height);
    float u2 = fmin(1.0f, src.right / width);
    float v2 = fmin(1.0f, src.bottom / height);

    getMapper(texture).map(u1, v1, u2, v2);

@@ -2213,25 +2230,21 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,

    texture->setWrap(GL_CLAMP_TO_EDGE, true);

    float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft);
    float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop);
    float scaleX = (dst.right - dst.left) / (src.right - src.left);
    float scaleY = (dst.bottom - dst.top) / (src.bottom - src.top);

    bool scaled = scaleX != 1.0f || scaleY != 1.0f;
    // Apply a scale transform on the canvas only when a shader is in use
    // Skia handles the ratio between the dst and src rects as a scale factor
    // when a shader is set
    bool useScaleTransform = getShader(paint) && scaled;
    bool ignoreTransform = false;

    if (CC_LIKELY(currentTransform()->isPureTranslate() && !useScaleTransform)) {
        float x = (int) floorf(dstLeft + currentTransform()->getTranslateX() + 0.5f);
        float y = (int) floorf(dstTop + currentTransform()->getTranslateY() + 0.5f);
    if (CC_LIKELY(currentTransform()->isPureTranslate())) {
        float x = (int) floorf(dst.left + currentTransform()->getTranslateX() + 0.5f);
        float y = (int) floorf(dst.top + currentTransform()->getTranslateY() + 0.5f);

        dstRight = x + (dstRight - dstLeft);
        dstBottom = y + (dstBottom - dstTop);
        dst.right = x + (dst.right - dst.left);
        dst.bottom = y + (dst.bottom - dst.top);

        dstLeft = x;
        dstTop = y;
        dst.left = x;
        dst.top = y;

        texture->setFilter(scaled ? PaintUtils::getFilter(paint) : GL_NEAREST, true);
        ignoreTransform = true;
@@ -2239,34 +2252,18 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,
        texture->setFilter(PaintUtils::getFilter(paint), true);
    }

    if (CC_UNLIKELY(useScaleTransform)) {
        save(SkCanvas::kMatrix_SaveFlag);
        translate(dstLeft, dstTop);
        scale(scaleX, scaleY);

        dstLeft = 0.0f;
        dstTop = 0.0f;

        dstRight = srcRight - srcLeft;
        dstBottom = srcBottom - srcTop;
    }

    if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
        drawAlpha8TextureMesh(dstLeft, dstTop, dstRight, dstBottom,
        drawAlpha8TextureMesh(dst.left, dst.top, dst.right, dst.bottom,
                texture->id, paint,
                &mMeshVertices[0].x, &mMeshVertices[0].u,
                GL_TRIANGLE_STRIP, kUnitQuadCount, ignoreTransform);
    } else {
        drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom,
        drawTextureMesh(dst.left, dst.top, dst.right, dst.bottom,
                texture->id, paint, texture->blend,
                &mMeshVertices[0].x, &mMeshVertices[0].u,
                GL_TRIANGLE_STRIP, kUnitQuadCount, false, ignoreTransform);
    }

    if (CC_UNLIKELY(useScaleTransform)) {
        restore();
    }

    resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);

    mDirty = true;
Loading