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

Commit 2db5e993 authored by Romain Guy's avatar Romain Guy
Browse files

Merge scaled bitmaps with translated bitmaps

Change-Id: I03089f48f97b69fcb4a0171984d3ff548d41c4a8
parent 779321fd
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -145,7 +145,10 @@ public:
     * dropped, so we make simplifying qualifications on the ops that can merge, per op type.
     */
    bool canMergeWith(DrawOp* op) {
        if (!op->state.mMatrix.isPureTranslate()) return false;
        if (getBatchId() == DeferredDisplayList::kOpBatch_Bitmap) {
            // Bitmap batches can handle translate and scaling
            if (!op->state.mMatrix.isSimple()) return false;
        } else if (!op->state.mMatrix.isPureTranslate()) return false;

        bool isTextBatch = getBatchId() == DeferredDisplayList::kOpBatch_Text ||
                getBatchId() == DeferredDisplayList::kOpBatch_ColorText;
+14 −2
Original line number Diff line number Diff line
@@ -757,10 +757,16 @@ public:
        TextureVertex vertices[6 * ops.size()];
        TextureVertex* vertex = &vertices[0];

        bool transformed = false;

        // TODO: manually handle rect clip for bitmaps by adjusting texCoords per op,
        // and allowing them to be merged in getBatchId()
        for (unsigned int i = 0; i < ops.size(); i++) {
            const Rect& opBounds = ops[i]->state.mBounds;
            // When we reach multiDraw(), the matrix can be either
            // pureTranslate or simple (translate and/or scale).
            // If the matrix is not pureTranslate, then we have a scale
            if (!ops[i]->state.mMatrix.isPureTranslate()) transformed = true;

            Rect texCoords(0, 0, 1, 1);
            ((DrawBitmapOp*) ops[i])->mUvMapper.map(texCoords);
@@ -774,7 +780,8 @@ public:
            SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, bottom);
        }

        return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0], bounds, mPaint);
        return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0],
                transformed, bounds, mPaint);
    }

    virtual void output(int level, uint32_t logFlags) {
@@ -783,13 +790,18 @@ public:

    virtual const char* name() { return "DrawBitmap"; }

    bool bitmapMergeAllowed() {
        return state.mMatrix.isSimple() && !state.mClipped &&
                OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
    }

    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
        *batchId = DeferredDisplayList::kOpBatch_Bitmap;
        *mergeId = mAtlasEntry ? (mergeid_t) &mAtlasEntry->atlas : (mergeid_t) mBitmap;

        // don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
        // MergingDrawBatch::canMergeWith
        return mergeAllowed() && (mBitmap->getConfig() != SkBitmap::kA8_Config);
        return bitmapMergeAllowed() && (mBitmap->getConfig() != SkBitmap::kA8_Config);
    }

    const SkBitmap* bitmap() { return mBitmap; }
+6 −2
Original line number Diff line number Diff line
@@ -1359,11 +1359,15 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDef
        // state has bounds initialized in local coordinates
        if (!state.mBounds.isEmpty()) {
            currentMatrix.mapRect(state.mBounds);
            state.mClipped = !currentClip.contains(state.mBounds);
            if (!state.mBounds.intersect(currentClip)) {
                // quick rejected
                return true;
            }
        } else {
            // If we don't have bounds, let's assume we're clipped
            // to prevent merging
            state.mClipped = true;
            state.mBounds.set(currentClip);
        }
    }
@@ -2010,7 +2014,7 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, Sk
}

status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureVertex* vertices,
        const Rect& bounds, SkPaint* paint) {
        bool transformed, const Rect& bounds, SkPaint* paint) {

    // merged draw operations don't need scissor, but clip should still be valid
    mCaches.setScissorEnabled(mScissorOptimizationDisabled);
@@ -2026,7 +2030,7 @@ status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureV
    getAlphaAndMode(paint, &alpha, &mode);

    texture->setWrap(GL_CLAMP_TO_EDGE, true);
    texture->setFilter(GL_NEAREST, true); // merged ops are always pure-translation for now
    texture->setFilter(transformed ? FILTER(paint) : GL_NEAREST, true);

    const float x = (int) floorf(bounds.left + 0.5f);
    const float y = (int) floorf(bounds.top + 0.5f);
+2 −1
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ struct DeferredDisplayState {
    // the below are set and used by the OpenGLRenderer at record and deferred playback
    bool mClipValid;
    Rect mClip;
    bool mClipped;
    mat4 mMatrix;
    DrawModifiers mDrawModifiers;
    float mAlpha;
@@ -252,7 +253,7 @@ public:
    virtual status_t drawLayer(Layer* layer, float x, float y);
    virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
    status_t drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureVertex* vertices,
            const Rect& bounds, SkPaint* paint);
            bool transformed, const Rect& bounds, SkPaint* paint);
    virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
    virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
            float srcRight, float srcBottom, float dstLeft, float dstTop,
+2 −2
Original line number Diff line number Diff line
@@ -125,11 +125,11 @@ public:
        return intersect(r.left, r.top, r.right, r.bottom);
    }

    inline bool contains(float l, float t, float r, float b) {
    inline bool contains(float l, float t, float r, float b) const {
        return l >= left && t >= top && r <= right && b <= bottom;
    }

    inline bool contains(const Rect& r) {
    inline bool contains(const Rect& r) const {
        return contains(r.left, r.top, r.right, r.bottom);
    }