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

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

Glop drawBitmaps, drawPatches

Change-Id: I3f1cd3f47f97d2e0c9b9d153732e26ee0b1c58c2
parent c66f3baa
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -139,6 +139,20 @@ GlopBuilder& GlopBuilder::setMeshTexturedIndexedQuads(TextureVertex* vertexData,
    return *this;
}

GlopBuilder& GlopBuilder::setMeshTexturedMesh(TextureVertex* vertexData, int elementCount) {
    TRIGGER_STAGE(kMeshStage);

    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
    mOutGlop->mesh.indices = { 0, nullptr };
    mOutGlop->mesh.vertices = {
            0,
            VertexAttribFlags::kTextureCoord,
            &vertexData[0].x, &vertexData[0].u, nullptr,
            kTextureVertexStride };
    mOutGlop->mesh.elementCount = elementCount;
    return *this;
}

GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount) {
    TRIGGER_STAGE(kMeshStage);

@@ -269,19 +283,21 @@ void GlopBuilder::setFill(int color, float alphaScale, SkXfermode::Mode mode,
    }
}

GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, bool isAlphaMaskTexture,
GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, int textureFillFlags,
        const SkPaint* paint, float alphaScale) {
    TRIGGER_STAGE(kFillStage);
    REQUIRE_STAGES(kMeshStage);

    GLenum filter = (textureFillFlags & TextureFillFlags::kForceFilter)
            ? GL_LINEAR : PaintUtils::getFilter(paint);
    mOutGlop->fill.texture = { &texture,
            GL_TEXTURE_2D, PaintUtils::getFilter(paint), GL_CLAMP_TO_EDGE, nullptr };
            GL_TEXTURE_2D, filter, GL_CLAMP_TO_EDGE, nullptr };

    if (paint) {
        int color = paint->getColor();
        SkShader* shader = paint->getShader();

        if (!isAlphaMaskTexture) {
        if (!(textureFillFlags & TextureFillFlags::kIsAlphaMaskTexture)) {
            // Texture defines color, so disable shaders, and reset all non-alpha color channels
            color |= 0x00FFFFFF;
            shader = nullptr;
@@ -303,9 +319,9 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, bool isAlphaMask
        }
    }

    mDescription.hasAlpha8Texture = isAlphaMaskTexture;
    if (isAlphaMaskTexture) {
    if (textureFillFlags & TextureFillFlags::kIsAlphaMaskTexture) {
        mDescription.modulate = mOutGlop->fill.color.isNotBlack();
        mDescription.hasAlpha8Texture = true;
    } else {
        mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
    }
+19 −3
Original line number Diff line number Diff line
@@ -33,6 +33,13 @@ class Texture;
class VertexBuffer;
struct Glop;

enum class TextureFillFlags {
    kNone = 0,
    kIsAlphaMaskTexture = 1 << 0,
    kForceFilter = 1 << 1,
};
MAKE_FLAGS_ENUM(TextureFillFlags);

class GlopBuilder {
    PREVENT_COPY_AND_ASSIGN(GlopBuilder);
public:
@@ -43,11 +50,12 @@ public:
    GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs);
    GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp);
    GlopBuilder& setMeshIndexedQuads(Vertex* vertexData, int quadCount);
    GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount);
    GlopBuilder& setMeshTexturedMesh(TextureVertex* vertexData, int elementCount); // TODO: use indexed quads
    GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount); // TODO: use indexed quads
    GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount); // TODO: take quadCount

    GlopBuilder& setFillPaint(const SkPaint& paint, float alphaScale);
    GlopBuilder& setFillTexturePaint(Texture& texture, bool isAlphaMaskTexture,
    GlopBuilder& setFillTexturePaint(Texture& texture, int textureFillFlags,
            const SkPaint* paint, float alphaScale);
    GlopBuilder& setFillPathTexturePaint(PathTexture& texture,
            const SkPaint& paint, float alphaScale);
@@ -63,7 +71,7 @@ public:

    GlopBuilder& setModelViewMapUnitToRect(const Rect destination);
    GlopBuilder& setModelViewMapUnitToRectSnap(const Rect destination);
    GlopBuilder& setModelViewMapUnitToRectOptionalSnap(bool snap, const Rect destination) {
    GlopBuilder& setModelViewMapUnitToRectOptionalSnap(bool snap, const Rect& destination) {
        if (snap) {
            return setModelViewMapUnitToRectSnap(destination);
        } else {
@@ -72,6 +80,14 @@ public:
    }
    GlopBuilder& setModelViewOffsetRect(float offsetX, float offsetY, const Rect source);
    GlopBuilder& setModelViewOffsetRectSnap(float offsetX, float offsetY, const Rect source);
    GlopBuilder& setModelViewOffsetRectOptionalSnap(bool snap,
            float offsetX, float offsetY, const Rect& source) {
        if (snap) {
            return setModelViewOffsetRectSnap(offsetX, offsetY, source);
        } else {
            return setModelViewOffsetRect(offsetX, offsetY, source);
        }
    }

    GlopBuilder& setRoundRectClipState(const RoundRectClipState* roundRectClipState);

+105 −80
Original line number Diff line number Diff line
@@ -883,8 +883,8 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
            && !layer->getForceFilter()
            && layer->getWidth() == (uint32_t) rect.getWidth()
            && layer->getHeight() == (uint32_t) rect.getHeight()) {
        const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
        const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
        const float x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
        const float y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);

        layer->setFilter(GL_NEAREST);
        setupDrawModelView(kModelViewMode_TranslateAndScale, false,
@@ -921,8 +921,8 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap)
        if (simpleTransform) {
            // When we're swapping, the layer is already in screen coordinates
            if (!swap) {
                x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
                y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
                x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
                y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
            }

            layer->setFilter(GL_NEAREST, true);
@@ -1076,8 +1076,8 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
    setupDrawColorFilterUniforms(layer->getColorFilter());
    setupDrawTexture(layer->getTextureId());
    if (currentTransform()->isPureTranslate()) {
        const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
        const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
        const float x = floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
        const float y = floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);

        layer->setFilter(GL_NEAREST);
        setupDrawModelView(kModelViewMode_Translate, false,
@@ -2004,8 +2004,8 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, const SkPaint* paint) {

    bool ignoreTransform = false;
    if (currentTransform()->isPureTranslate()) {
        x = (int) floorf(currentTransform()->getTranslateX() + 0.5f);
        y = (int) floorf(currentTransform()->getTranslateY() + 0.5f);
        x = floorf(currentTransform()->getTranslateX() + 0.5f);
        y = floorf(currentTransform()->getTranslateY() + 0.5f);
        ignoreTransform = true;

        texture->setFilter(GL_NEAREST, true);
@@ -2028,17 +2028,37 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, const SkPaint* paint) {
void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
        int bitmapCount, TextureVertex* vertices, bool pureTranslate,
        const Rect& bounds, const SkPaint* paint) {
    mCaches.textureState().activateTexture(0);
    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
    if (!texture) return;

    const AutoTexture autoCleanup(texture);

    if (USE_GLOPS) {
        // TODO: remove layer dirty in multi-draw callers
        // TODO: snap doesn't need to touch transform, only texture filter.
        bool snap = pureTranslate;
        const float x = floorf(bounds.left + 0.5f);
        const float y = floorf(bounds.top + 0.5f);
        int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType)
                ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone);
        Glop glop;
        GlopBuilder(mRenderState, mCaches, &glop)
                .setMeshTexturedMesh(vertices, bitmapCount * 6)
                .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
                .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false)
                .setModelViewOffsetRectOptionalSnap(snap, x, y, Rect(0, 0, bounds.getWidth(), bounds.getHeight()))
                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
                .build();
        renderGlop(glop);
        return;
    }

    mCaches.textureState().activateTexture(0);
    texture->setWrap(GL_CLAMP_TO_EDGE, true);
    texture->setFilter(pureTranslate ? GL_NEAREST : PaintUtils::getFilter(paint), true);

    const float x = (int) floorf(bounds.left + 0.5f);
    const float y = (int) floorf(bounds.top + 0.5f);
    const float x = floorf(bounds.left + 0.5f);
    const float y = floorf(bounds.top + 0.5f);
    if (CC_UNLIKELY(bitmap->colorType() == kAlpha_8_SkColorType)) {
        drawAlpha8TextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
                texture->id, paint, &vertices[0].x, &vertices[0].u,
@@ -2065,11 +2085,12 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
    const AutoTexture autoCleanup(texture);

    if (USE_GLOPS) {
        bool isAlpha8Texture = bitmap->colorType() == kAlpha_8_SkColorType;
        int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType)
                ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone);
        Glop glop;
        GlopBuilder(mRenderState, mCaches, &glop)
                .setMeshTexturedUnitQuad(texture->uvMapper)
                .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha)
                .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
                .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false)
                .setModelViewMapUnitToRectSnap(Rect(0, 0, texture->width, texture->height))
                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
@@ -2166,11 +2187,10 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m
         * TODO: handle alpha_8 textures correctly by applying paint color, but *not*
         * shader in that case to mimic the behavior in SkiaCanvas::drawBitmapMesh.
         */
        bool isAlpha8Texture = false;
        Glop glop;
        GlopBuilder(mRenderState, mCaches, &glop)
                .setMeshColoredTexturedMesh(mesh.get(), elementCount)
                .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha)
                .setFillTexturePaint(*texture, static_cast<int>(TextureFillFlags::kNone), paint, currentSnapshot()->alpha)
                .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false)
                .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom))
                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
@@ -2229,11 +2249,12 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons
                fmin(1.0f, src.right / texture->width),
                fmin(1.0f, src.bottom / texture->height));

        bool isAlpha8Texture = bitmap->colorType() == kAlpha_8_SkColorType;
        int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType)
                ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone);
        Glop glop;
        GlopBuilder(mRenderState, mCaches, &glop)
                .setMeshTexturedUvQuad(texture->uvMapper, uv)
                .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha)
                .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
                .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false)
                .setModelViewMapUnitToRectSnap(dst)
                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
@@ -2266,8 +2287,8 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons
    bool ignoreTransform = false;

    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);
        float x = floorf(dst.left + currentTransform()->getTranslateX() + 0.5f);
        float y = floorf(dst.top + currentTransform()->getTranslateY() + 0.5f);

        dst.right = x + (dst.right - dst.left);
        dst.bottom = y + (dst.bottom - dst.top);
@@ -2298,27 +2319,13 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons
    mDirty = true;
}

void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
        float left, float top, float right, float bottom, const SkPaint* paint) {
    if (quickRejectSetupScissor(left, top, right, bottom)) {
        return;
    }

    AssetAtlas::Entry* entry = mRenderState.assetAtlas().getEntry(bitmap);
    const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(),
            right - left, bottom - top, patch);

    drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint);
}

void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
        AssetAtlas::Entry* entry, float left, float top, float right, float bottom,
        const SkPaint* paint) {
    if (quickRejectSetupScissor(left, top, right, bottom)) {
    if (!mesh || !mesh->verticesCount || quickRejectSetupScissor(left, top, right, bottom)) {
        return;
    }

    if (CC_LIKELY(mesh && mesh->verticesCount > 0)) {
    mCaches.textureState().activateTexture(0);
    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
    if (!texture) return;
@@ -2336,8 +2343,8 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
        for (size_t i = 0; i < count; i++) {
            const Rect& bounds = mesh->quads.itemAt(i);
            if (CC_LIKELY(pureTranslate)) {
                    const float x = (int) floorf(bounds.left + offsetX + 0.5f);
                    const float y = (int) floorf(bounds.top + offsetY + 0.5f);
                const float x = floorf(bounds.left + offsetX + 0.5f);
                const float y = floorf(bounds.top + offsetY + 0.5f);
                dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getHeight());
            } else {
                dirtyLayer(left + bounds.left, top + bounds.top,
@@ -2348,8 +2355,8 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,

    bool ignoreTransform = false;
    if (CC_LIKELY(pureTranslate)) {
            const float x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f);
            const float y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f);
        const float x = floorf(left + currentTransform()->getTranslateX() + 0.5f);
        const float y = floorf(top + currentTransform()->getTranslateY() + 0.5f);

        right = x + right - left;
        bottom = y + bottom - top;
@@ -2361,7 +2368,6 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
            texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
            GL_TRIANGLES, mesh->indexCount, false, ignoreTransform,
            mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads);
    }

    mDirty = true;
}
@@ -2372,18 +2378,37 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
 * The caller is responsible for properly dirtying the current layer.
 */
void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
        TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) {
        TextureVertex* vertices, uint32_t elementCount, const SkPaint* paint) {
    mCaches.textureState().activateTexture(0);
    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    if (USE_GLOPS) {
        // TODO: get correct bounds from caller
        // 9 patches are built for stretching - always filter
        int textureFillFlags = static_cast<int>(TextureFillFlags::kForceFilter);
        if (bitmap->colorType() == kAlpha_8_SkColorType) {
            textureFillFlags |= TextureFillFlags::kIsAlphaMaskTexture;
        }
        Glop glop;
        GlopBuilder(mRenderState, mCaches, &glop)
                .setMeshTexturedIndexedQuads(vertices, elementCount)
                .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
                .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false)
                .setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0))
                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
                .build();
        renderGlop(glop);
        return;
    }

    texture->setWrap(GL_CLAMP_TO_EDGE, true);
    texture->setFilter(GL_LINEAR, true);

    drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, paint,
            texture->blend, &vertices[0].x, &vertices[0].u,
            GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false);
            GL_TRIANGLES, elementCount, false, true, 0, kModelViewMode_Translate, false);

    mDirty = true;
}
@@ -2775,8 +2800,8 @@ void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
    float y = 0.0f;
    const bool pureTranslate = currentTransform()->isPureTranslate();
    if (pureTranslate) {
        x = (int) floorf(x + currentTransform()->getTranslateX() + 0.5f);
        y = (int) floorf(y + currentTransform()->getTranslateY() + 0.5f);
        x = floorf(x + currentTransform()->getTranslateX() + 0.5f);
        y = floorf(y + currentTransform()->getTranslateY() + 0.5f);
    }

    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
@@ -2914,8 +2939,8 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float
    const bool pureTranslate = transform.isPureTranslate();

    if (CC_LIKELY(pureTranslate)) {
        x = (int) floorf(x + transform.getTranslateX() + 0.5f);
        y = (int) floorf(y + transform.getTranslateY() + 0.5f);
        x = floorf(x + transform.getTranslateX() + 0.5f);
        y = floorf(y + transform.getTranslateY() + 0.5f);
    }

    int alpha;
@@ -3426,8 +3451,8 @@ void OpenGLRenderer::drawTextureRect(Texture* texture, const SkPaint* paint) {
    }

    if (CC_LIKELY(currentTransform()->isPureTranslate())) {
        const float x = (int) floorf(currentTransform()->getTranslateX() + 0.5f);
        const float y = (int) floorf(currentTransform()->getTranslateY() + 0.5f);
        const float x = floorf(currentTransform()->getTranslateX() + 0.5f);
        const float y = floorf(currentTransform()->getTranslateY() + 0.5f);

        texture->setFilter(GL_NEAREST, true);
        drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
+0 −2
Original line number Diff line number Diff line
@@ -206,8 +206,6 @@ public:
            const float* vertices, const int* colors, const SkPaint* paint);
    void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
            TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint);
    void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
            float left, float top, float right, float bottom, const SkPaint* paint);
    void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
            float left, float top, float right, float bottom, const SkPaint* paint);
    void drawColor(int color, SkXfermode::Mode mode);
+12 −0
Original line number Diff line number Diff line
@@ -36,9 +36,21 @@
        #Type " must have standard layout")

#define MAKE_FLAGS_ENUM(enumType) \
        inline int operator|=(int lhs, enumType rhs) { \
            return lhs | static_cast<int>(rhs); \
        } \
        inline int operator|(int lhs, enumType rhs) { \
            return lhs | static_cast<int>(rhs); \
        } \
        inline int operator|(enumType lhs, int rhs) { \
            return static_cast<int>(lhs) | rhs; \
        } \
        inline int operator|(enumType lhs, enumType rhs) { \
            return static_cast<int>(lhs) | static_cast<int>(rhs); \
        } \
        inline int operator&=(int lhs, enumType rhs) { \
            return lhs & static_cast<int>(rhs); \
        } \
        inline int operator&(int lhs, enumType rhs) { \
            return lhs & static_cast<int>(rhs); \
        } \