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

Commit 7f6d6b03 authored by Romain Guy's avatar Romain Guy
Browse files

Split assets atlas batches

Bug #10185769

The assets atlas contains assets that need to be blended and assets
that do not need to be blended. With a single merge id, currently
set to be the pointer to the atlas itself, draw ops merging could
generate batches of commands containing both opaque and translucent
assets. The blend state was chosen from only one of the assets in
the batch, leading either to inefficiencies (blending large opaque
assets) or incorrect behaviors (not blending translucent assets.)

This change introduces two new merge ids in the atlas: an opaque
key and a blend key. These keys are simple booleans set to false
and true respectively (the values do not matter really.) Their
memory addresses are used as the merge ids when createing draw ops
batches, allowing all opaque ops to be batched together and all
translucent ops to be batched together.

Change-Id: I114dba0533c44987e53864b471ccb28c811f2025
parent 605ca203
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ struct DelegateTexture: public Texture {
            bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
        mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget);
    }

private:
    Texture* const mDelegate;
}; // struct DelegateTexture
@@ -125,12 +126,12 @@ void AssetAtlas::createEntries(Caches& caches, int* map, int count) {
                y / height, (y + bitmap->height()) / height);

        Texture* texture = new DelegateTexture(caches, mTexture);
        Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);

        texture->id = mTexture->id;
        texture->blend = !bitmap->isOpaque();
        texture->width = bitmap->width();
        texture->height = bitmap->height();

        Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);
        texture->uvMapper = &entry->uvMapper;

        mEntries.add(entry->bitmap, entry);
+15 −2
Original line number Diff line number Diff line
@@ -84,11 +84,20 @@ public:
         */
        const AssetAtlas& atlas;

        /**
         * Unique identifier used to merge bitmaps and 9-patches stored
         * in the atlas.
         */
        const void* getMergeId() const {
            return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
        }

    private:
        Entry(SkBitmap* bitmap, int x, int y, bool rotated,
                Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas):
                bitmap(bitmap), x(x), y(y), rotated(rotated),
                texture(texture), uvMapper(mapper), atlas(atlas) { }
                texture(texture), uvMapper(mapper), atlas(atlas) {
        }

        ~Entry() {
            delete texture;
@@ -97,7 +106,8 @@ public:
        friend class AssetAtlas;
    };

    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0) { }
    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0),
            mBlendKey(true), mOpaqueKey(false) { }
    ~AssetAtlas() { terminate(); }

    /**
@@ -173,6 +183,9 @@ private:

    uint32_t mGenerationId;

    const bool mBlendKey;
    const bool mOpaqueKey;

    KeyedVector<SkBitmap*, Entry*> mEntries;
}; // class AssetAtlas

+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ class Batch;
class DrawBatch;
class MergingDrawBatch;

typedef void* mergeid_t;
typedef const void* mergeid_t;

class DeferredDisplayList {
public:
+2 −2
Original line number Diff line number Diff line
@@ -818,7 +818,7 @@ public:

    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) &mEntry->atlas : (mergeid_t) mBitmap;
        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;

        // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
        // MergingDrawBatch::canMergeWith()
@@ -1071,7 +1071,7 @@ public:

    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
        deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) &mEntry->atlas : (mergeid_t) mBitmap;
        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
        deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
                OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
        deferInfo.opaqueOverBounds = isOpaqueOverBounds() && mBitmap->isOpaque();