summaryrefslogtreecommitdiffstats
path: root/libs/hwui
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-08-06 13:49:28 -0700
committerRomain Guy <romainguy@google.com>2013-08-06 18:35:01 -0700
commit7f6d6b0370df4b5a9e0f45bffc31ea6caeeb509d (patch)
tree00e4cbd5c4b2f7e27d4c4f42ea05bdee576a0766 /libs/hwui
parent605ca203782781aa023b5b2963edbf2966379c45 (diff)
downloadframeworks_base-7f6d6b0370df4b5a9e0f45bffc31ea6caeeb509d.zip
frameworks_base-7f6d6b0370df4b5a9e0f45bffc31ea6caeeb509d.tar.gz
frameworks_base-7f6d6b0370df4b5a9e0f45bffc31ea6caeeb509d.tar.bz2
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
Diffstat (limited to 'libs/hwui')
-rw-r--r--libs/hwui/AssetAtlas.cpp5
-rw-r--r--libs/hwui/AssetAtlas.h17
-rw-r--r--libs/hwui/DeferredDisplayList.h2
-rw-r--r--libs/hwui/DisplayListOp.h4
4 files changed, 21 insertions, 7 deletions
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index d98a538..eb8bb9f 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -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);
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 9afc54d..a28efc6 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -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
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 6c5a847..1ef0152 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -40,7 +40,7 @@ class Batch;
class DrawBatch;
class MergingDrawBatch;
-typedef void* mergeid_t;
+typedef const void* mergeid_t;
class DeferredDisplayList {
public:
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 83de651..1b52b65 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -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();