summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-05-24 16:19:19 -0700
committerRomain Guy <romainguy@google.com>2013-05-24 16:19:19 -0700
commita404e16e4933857464046d763ed7629cd0c86cbf (patch)
treefec5bfa47138b29d22b25b9d87dc84ebfea7f1e6 /libs
parent64770d16b0907a8e1ee81ef6c8fa398a6bdbee79 (diff)
downloadframeworks_base-a404e16e4933857464046d763ed7629cd0c86cbf.zip
frameworks_base-a404e16e4933857464046d763ed7629cd0c86cbf.tar.gz
frameworks_base-a404e16e4933857464046d763ed7629cd0c86cbf.tar.bz2
Make sure atlas antries can correctly filter/wrap textures
The virtual textures would each have their own values for wrapping and filtering which could lead to conflict and/or extraneous GL commands being issued. Change-Id: I64cb59a03e598f46bf645bd1d30fccfa63a07431
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/AssetAtlas.cpp60
-rw-r--r--libs/hwui/AssetAtlas.h36
-rw-r--r--libs/hwui/OpenGLRenderer.cpp2
-rw-r--r--libs/hwui/OpenGLRenderer.h1
-rw-r--r--libs/hwui/Texture.h10
5 files changed, 70 insertions, 39 deletions
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index 4d2fc01..8511e7c 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -31,11 +31,12 @@ void AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) {
}
mImage = new Image(buffer);
- mTexture = mImage->getTexture();
- if (mTexture) {
- mWidth = buffer->getWidth();
- mHeight = buffer->getHeight();
+ if (mImage->getTexture()) {
+ mTexture = new Texture();
+ mTexture->id = mImage->getTexture();
+ mTexture->width = buffer->getWidth();
+ mTexture->height = buffer->getHeight();
createEntries(map, count);
} else {
@@ -43,6 +44,7 @@ void AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) {
delete mImage;
mImage = NULL;
+ mTexture = NULL;
}
}
@@ -51,12 +53,13 @@ void AssetAtlas::terminate() {
delete mImage;
mImage = NULL;
+ delete mTexture;
+ mTexture = NULL;
+
for (size_t i = 0; i < mEntries.size(); i++) {
delete mEntries.valueAt(i);
}
mEntries.clear();
-
- mWidth = mHeight = 0;
}
}
@@ -71,13 +74,36 @@ AssetAtlas::Entry* AssetAtlas::getEntry(SkBitmap* const bitmap) const {
Texture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const {
ssize_t index = mEntries.indexOfKey(bitmap);
- return index >= 0 ? &mEntries.valueAt(index)->texture : NULL;
+ return index >= 0 ? mEntries.valueAt(index)->texture : NULL;
}
/**
+ * Delegates changes to wrapping and filtering to the base atlas texture
+ * instead of applying the changes to the virtual textures.
+ */
+struct DelegateTexture: public Texture {
+ DelegateTexture(Texture* delegate): Texture(), mDelegate(delegate) { }
+
+ virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
+ bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
+ mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget);
+ }
+
+ virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
+ bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
+ mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget);
+ }
+private:
+ Texture* const mDelegate;
+}; // struct DelegateTexture
+
+/**
* TODO: This method does not take the rotation flag into account
*/
void AssetAtlas::createEntries(int* map, int count) {
+ const float width = float(mTexture->width);
+ const float height = float(mTexture->height);
+
for (int i = 0; i < count; ) {
SkBitmap* bitmap = (SkBitmap*) map[i++];
int x = map[i++];
@@ -88,15 +114,17 @@ void AssetAtlas::createEntries(int* map, int count) {
if (!bitmap) continue;
const UvMapper mapper(
- x / (float) mWidth, (x + bitmap->width()) / (float) mWidth,
- y / (float) mHeight, (y + bitmap->height()) / (float) mHeight);
-
- Entry* entry = new Entry(bitmap, x, y, rotated, mapper, *this);
- entry->texture.id = mTexture;
- entry->texture.blend = !bitmap->isOpaque();
- entry->texture.width = bitmap->width();
- entry->texture.height = bitmap->height();
- entry->texture.uvMapper = &entry->uvMapper;
+ x / width, (x + bitmap->width()) / width,
+ y / height, (y + bitmap->height()) / height);
+
+ Texture* texture = new DelegateTexture(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();
+ texture->uvMapper = &entry->uvMapper;
mEntries.add(entry->bitmap, entry);
}
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 0bbd2a7..793e300 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -64,6 +64,13 @@ public:
*/
bool rotated;
+ /*
+ * A "virtual texture" object that represents the texture
+ * this entry belongs to. This texture should never be
+ * modified.
+ */
+ Texture* texture;
+
/**
* Maps texture coordinates in the [0..1] range into the
* correct range to sample this entry from the atlas.
@@ -75,22 +82,20 @@ public:
*/
const AssetAtlas& atlas;
- /*
- * A "virtual texture" object that represents the texture
- * this entry belongs to. This texture should never be
- * modified.
- */
- Texture texture;
-
private:
Entry(SkBitmap* bitmap, int x, int y, bool rotated,
- const UvMapper& mapper, const AssetAtlas& atlas):
- bitmap(bitmap), x(x), y(y), rotated(rotated), uvMapper(mapper), atlas(atlas) { }
+ Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas):
+ bitmap(bitmap), x(x), y(y), rotated(rotated),
+ texture(texture), uvMapper(mapper), atlas(atlas) { }
+
+ ~Entry() {
+ delete texture;
+ }
friend class AssetAtlas;
};
- AssetAtlas(): mWidth(0), mHeight(0), mTexture(0), mImage(NULL) { }
+ AssetAtlas(): mTexture(NULL), mImage(NULL) { }
~AssetAtlas() { terminate(); }
/**
@@ -120,7 +125,7 @@ public:
* Can return 0 if the atlas is not initialized.
*/
uint32_t getWidth() const {
- return mWidth;
+ return mTexture ? mTexture->width : 0;
}
/**
@@ -128,7 +133,7 @@ public:
* Can return 0 if the atlas is not initialized.
*/
uint32_t getHeight() const {
- return mHeight;
+ return mTexture ? mTexture->height : 0;
}
/**
@@ -136,7 +141,7 @@ public:
* Can return 0 if the atlas is not initialized.
*/
GLuint getTexture() const {
- return mTexture;
+ return mTexture ? mTexture->id : 0;
}
/**
@@ -154,10 +159,7 @@ public:
private:
void createEntries(int* map, int count);
- uint32_t mWidth;
- uint32_t mHeight;
-
- GLuint mTexture;
+ Texture* mTexture;
Image* mImage;
KeyedVector<SkBitmap*, Entry*> mEntries;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2465b48..f12119a 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2352,7 +2352,7 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
if (CC_LIKELY(mesh && mesh->verticesCount > 0)) {
mCaches.activeTexture(0);
- Texture* texture = entry ? &entry->texture : mCaches.textureCache.get(bitmap);
+ Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
if (!texture) return DrawGlInfo::kStatusDone;
const AutoTexture autoCleanup(texture);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index d9ba93a..6286e94 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -1083,7 +1083,6 @@ private:
// No-ops start/endTiling when set
bool mSuppressTiling;
-
// If true, this renderer will setup drawing to emulate
// an increment stencil buffer in the color buffer
bool mCountOverdraw;
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index dd39cae..f84cd67 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -48,13 +48,15 @@ struct Texture {
uvMapper = NULL;
}
+ virtual ~Texture() { }
+
void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
GLenum renderTarget = GL_TEXTURE_2D) {
setWrapST(wrap, wrap, bindTexture, force, renderTarget);
}
- void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false,
- GLenum renderTarget = GL_TEXTURE_2D) {
+ virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
+ bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
if (firstWrap || force || wrapS != this->wrapS || wrapT != this->wrapT) {
firstWrap = false;
@@ -76,8 +78,8 @@ struct Texture {
setFilterMinMag(filter, filter, bindTexture, force, renderTarget);
}
- void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false, bool force = false,
- GLenum renderTarget = GL_TEXTURE_2D) {
+ virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
+ bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
if (firstFilter || force || min != minFilter || mag != magFilter) {
firstFilter = false;