summaryrefslogtreecommitdiffstats
path: root/libs/hwui
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-06-04 18:00:09 -0700
committerRomain Guy <romainguy@google.com>2013-06-04 18:58:36 -0700
commit8aa195d7081b889f3a7b1f426cbd8556377aae5e (patch)
tree6cd0ab4181c25d3113c4e39b49e8f8a0c7d12b8b /libs/hwui
parent84f3c5689cffbfc1e45a0101d5bb636323769f54 (diff)
downloadframeworks_base-8aa195d7081b889f3a7b1f426cbd8556377aae5e.zip
frameworks_base-8aa195d7081b889f3a7b1f426cbd8556377aae5e.tar.gz
frameworks_base-8aa195d7081b889f3a7b1f426cbd8556377aae5e.tar.bz2
Introduce Caches::bindTexture() to reduce glBindTexture calls
Change-Id: Ic345422567c020c0a9035ff51dcf2ae2a1fc59f4
Diffstat (limited to 'libs/hwui')
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/AssetAtlas.cpp13
-rw-r--r--libs/hwui/AssetAtlas.h4
-rw-r--r--libs/hwui/Caches.cpp23
-rw-r--r--libs/hwui/Caches.h20
-rw-r--r--libs/hwui/Dither.cpp11
-rw-r--r--libs/hwui/Dither.h7
-rw-r--r--libs/hwui/FontRenderer.cpp4
-rw-r--r--libs/hwui/GradientCache.cpp4
-rw-r--r--libs/hwui/Image.cpp3
-rw-r--r--libs/hwui/Layer.cpp59
-rw-r--r--libs/hwui/Layer.h46
-rw-r--r--libs/hwui/LayerRenderer.cpp2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp3
-rw-r--r--libs/hwui/OpenGLRenderer.h4
-rw-r--r--libs/hwui/PathCache.cpp4
-rw-r--r--libs/hwui/PathCache.h2
-rw-r--r--libs/hwui/SkiaShader.cpp22
-rw-r--r--libs/hwui/SkiaShader.h19
-rw-r--r--libs/hwui/TextDropShadowCache.cpp7
-rw-r--r--libs/hwui/TextDropShadowCache.h4
-rw-r--r--libs/hwui/Texture.cpp80
-rw-r--r--libs/hwui/Texture.h79
-rw-r--r--libs/hwui/TextureCache.cpp6
-rw-r--r--libs/hwui/font/CacheTexture.cpp8
-rw-r--r--libs/hwui/font/CacheTexture.h4
26 files changed, 275 insertions, 164 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 771ac45..5a30472 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -41,6 +41,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
SkiaShader.cpp \
Snapshot.cpp \
Stencil.cpp \
+ Texture.cpp \
TextureCache.cpp \
TextDropShadowCache.cpp
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index 8511e7c..782c052 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -15,6 +15,7 @@
*/
#include "AssetAtlas.h"
+#include "Caches.h"
#include <GLES2/gl2ext.h>
@@ -33,12 +34,14 @@ void AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) {
mImage = new Image(buffer);
if (mImage->getTexture()) {
- mTexture = new Texture();
+ Caches& caches = Caches::getInstance();
+
+ mTexture = new Texture(caches);
mTexture->id = mImage->getTexture();
mTexture->width = buffer->getWidth();
mTexture->height = buffer->getHeight();
- createEntries(map, count);
+ createEntries(caches, map, count);
} else {
ALOGW("Could not create atlas image");
@@ -82,7 +85,7 @@ Texture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const {
* instead of applying the changes to the virtual textures.
*/
struct DelegateTexture: public Texture {
- DelegateTexture(Texture* delegate): Texture(), mDelegate(delegate) { }
+ DelegateTexture(Caches& caches, Texture* delegate): Texture(caches), mDelegate(delegate) { }
virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
@@ -100,7 +103,7 @@ private:
/**
* TODO: This method does not take the rotation flag into account
*/
-void AssetAtlas::createEntries(int* map, int count) {
+void AssetAtlas::createEntries(Caches& caches, int* map, int count) {
const float width = float(mTexture->width);
const float height = float(mTexture->height);
@@ -117,7 +120,7 @@ void AssetAtlas::createEntries(int* map, int count) {
x / width, (x + bitmap->width()) / width,
y / height, (y + bitmap->height()) / height);
- Texture* texture = new DelegateTexture(mTexture);
+ Texture* texture = new DelegateTexture(caches, mTexture);
Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);
texture->id = mTexture->id;
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 793e300..2624907 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -34,6 +34,8 @@
namespace android {
namespace uirenderer {
+class Caches;
+
/**
* An asset atlas holds a collection of framework bitmaps in a single OpenGL
* texture. Each bitmap is associated with a location, defined in pixels,
@@ -157,7 +159,7 @@ public:
Texture* getEntryTexture(SkBitmap* const bitmap) const;
private:
- void createEntries(int* map, int count);
+ void createEntries(Caches& caches, int* map, int count);
Texture* mTexture;
Image* mImage;
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 9d5a854..23b5d76 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -47,7 +47,8 @@ namespace uirenderer {
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////
-Caches::Caches(): Singleton<Caches>(), mExtensions(Extensions::getInstance()), mInitialized(false) {
+Caches::Caches(): Singleton<Caches>(),
+ mExtensions(Extensions::getInstance()), mInitialized(false) {
init();
initFont();
initConstraints();
@@ -100,6 +101,8 @@ bool Caches::init() {
mInitialized = true;
+ resetBoundTextures();
+
return true;
}
@@ -491,6 +494,24 @@ void Caches::activeTexture(GLuint textureUnit) {
}
}
+void Caches::bindTexture(GLuint texture) {
+ if (mBoundTextures[mTextureUnit] != texture) {
+ glBindTexture(GL_TEXTURE_2D, texture);
+ mBoundTextures[mTextureUnit] = texture;
+ }
+}
+
+void Caches::bindTexture(GLenum target, GLuint texture) {
+ if (mBoundTextures[mTextureUnit] != texture) {
+ glBindTexture(target, texture);
+ mBoundTextures[mTextureUnit] = texture;
+ }
+}
+
+void Caches::resetBoundTextures() {
+ memset(mBoundTextures, 0, REQUIRED_TEXTURE_UNITS_COUNT * sizeof(GLuint));
+}
+
///////////////////////////////////////////////////////////////////////////////
// Scissor
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 54e4138..bd31ec3 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -55,6 +55,7 @@ namespace uirenderer {
// Globals
///////////////////////////////////////////////////////////////////////////////
+// GL ES 2.0 defines that at least 16 texture units must be supported
#define REQUIRED_TEXTURE_UNITS_COUNT 3
#define REGION_MESH_QUAD_COUNT 512
@@ -79,6 +80,7 @@ static const GLsizei gVertexAAWidthOffset = 2 * sizeof(float);
static const GLsizei gVertexAALengthOffset = 3 * sizeof(float);
static const GLsizei gMeshCount = 4;
+// Must define as many texture units as specified by REQUIRED_TEXTURE_UNITS_COUNT
static const GLenum gTextureUnits[] = {
GL_TEXTURE0,
GL_TEXTURE1,
@@ -223,6 +225,22 @@ public:
void activeTexture(GLuint textureUnit);
/**
+ * Binds the specified texture as a GL_TEXTURE_2D texture.
+ */
+ void bindTexture(GLuint texture);
+
+ /**
+ * Binds the specified texture..
+ */
+ void bindTexture(GLenum target, GLuint texture);
+
+ /**
+ * Signals that the cache of bound textures should be cleared.
+ * Other users of the context may have altered which textures are bound.
+ */
+ void resetBoundTextures();
+
+ /**
* Sets the scissor for the current surface.
*/
bool setScissor(GLint x, GLint y, GLint width, GLint height);
@@ -363,6 +381,8 @@ private:
bool mInitialized;
uint32_t mFunctorsCount;
+
+ GLuint mBoundTextures[REQUIRED_TEXTURE_UNITS_COUNT];
}; // class Caches
}; // namespace uirenderer
diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp
index 19b3849..4dc85e0 100644
--- a/libs/hwui/Dither.cpp
+++ b/libs/hwui/Dither.cpp
@@ -24,12 +24,15 @@ namespace uirenderer {
// Lifecycle
///////////////////////////////////////////////////////////////////////////////
+Dither::Dither(): mCaches(NULL), mInitialized(false), mDitherTexture(0) {
+}
+
void Dither::bindDitherTexture() {
if (!mInitialized) {
bool useFloatTexture = Extensions::getInstance().getMajorGlVersion() >= 3;
glGenTextures(1, &mDitherTexture);
- glBindTexture(GL_TEXTURE_2D, mDitherTexture);
+ mCaches->bindTexture(mDitherTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -68,7 +71,7 @@ void Dither::bindDitherTexture() {
mInitialized = true;
} else {
- glBindTexture(GL_TEXTURE_2D, mDitherTexture);
+ mCaches->bindTexture(mDitherTexture);
}
}
@@ -84,8 +87,10 @@ void Dither::clear() {
///////////////////////////////////////////////////////////////////////////////
void Dither::setupProgram(Program* program, GLuint* textureUnit) {
+ if (!mCaches) mCaches = &Caches::getInstance();
+
GLuint textureSlot = (*textureUnit)++;
- Caches::getInstance().activeTexture(textureSlot);
+ mCaches->activeTexture(textureSlot);
bindDitherTexture();
diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h
index 4d1f921..546236b 100644
--- a/libs/hwui/Dither.h
+++ b/libs/hwui/Dither.h
@@ -24,9 +24,7 @@
namespace android {
namespace uirenderer {
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
+class Caches;
// Must be a power of two
#define DITHER_KERNEL_SIZE 4
@@ -39,7 +37,7 @@ namespace uirenderer {
*/
class Dither {
public:
- Dither(): mInitialized(false), mDitherTexture(0) { }
+ Dither();
void clear();
void setupProgram(Program* program, GLuint* textureUnit);
@@ -47,6 +45,7 @@ public:
private:
void bindDitherTexture();
+ Caches* mCaches;
bool mInitialized;
GLuint mDitherTexture;
};
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index a9bf13e..3e3d882 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -376,7 +376,7 @@ void FontRenderer::checkTextureUpdate() {
if (cacheTexture->getTextureId() != lastTextureId) {
lastTextureId = cacheTexture->getTextureId();
caches.activeTexture(0);
- glBindTexture(GL_TEXTURE_2D, lastTextureId);
+ caches.bindTexture(lastTextureId);
}
if (cacheTexture->upload()) {
@@ -429,7 +429,7 @@ void FontRenderer::issueDrawCommand() {
first = false;
}
- glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
+ caches.bindTexture(texture->getTextureId());
texture->setLinearFiltering(mLinearFiltering, false);
TextureVertex* mesh = texture->mesh();
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 507ed95..1ed04fa 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -173,7 +173,7 @@ Texture* GradientCache::addLinearGradient(GradientCacheEntry& gradient,
GradientInfo info;
getGradientInfo(colors, count, info);
- Texture* texture = new Texture;
+ Texture* texture = new Texture();
texture->width = info.width;
texture->height = 2;
texture->blend = info.hasAlpha;
@@ -286,7 +286,7 @@ void GradientCache::generateTexture(uint32_t* colors, float* positions,
memcpy(pixels + rowBytes, pixels, rowBytes);
glGenTextures(1, &texture->id);
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ Caches::getInstance().bindTexture(texture->id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
if (mUseFloatTexture) {
diff --git a/libs/hwui/Image.cpp b/libs/hwui/Image.cpp
index 35ca40d..77c2300 100644
--- a/libs/hwui/Image.cpp
+++ b/libs/hwui/Image.cpp
@@ -18,6 +18,7 @@
#include <utils/Log.h>
+#include "Caches.h"
#include "Image.h"
namespace android {
@@ -38,7 +39,7 @@ Image::Image(sp<GraphicBuffer> buffer) {
} else {
// Create a 2D texture to sample from the EGLImage
glGenTextures(1, &mTexture);
- glBindTexture(GL_TEXTURE_2D, mTexture);
+ Caches::getInstance().bindTexture(mTexture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
GLenum status = GL_NO_ERROR;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 4adad05..60c38ba 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -28,7 +28,8 @@
namespace android {
namespace uirenderer {
-Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight) {
+Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight):
+ caches(Caches::getInstance()), texture(caches) {
mesh = NULL;
meshIndices = NULL;
meshElementCount = 0;
@@ -47,11 +48,11 @@ Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight) {
debugDrawUpdate = false;
hasDrawnSinceUpdate = false;
deferredList = NULL;
- Caches::getInstance().resourceCache.incrementRefcount(this);
+ caches.resourceCache.incrementRefcount(this);
}
Layer::~Layer() {
- if (colorFilter) Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
+ if (colorFilter) caches.resourceCache.decrementRefcount(colorFilter);
removeFbo();
deleteTexture();
@@ -76,7 +77,7 @@ bool Layer::resize(const uint32_t width, const uint32_t height) {
return true;
}
- const uint32_t maxTextureSize = Caches::getInstance().maxTextureSize;
+ const uint32_t maxTextureSize = caches.maxTextureSize;
if (desiredWidth > maxTextureSize || desiredHeight > maxTextureSize) {
ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)",
desiredWidth, desiredHeight, maxTextureSize, maxTextureSize);
@@ -89,7 +90,7 @@ bool Layer::resize(const uint32_t width, const uint32_t height) {
setSize(desiredWidth, desiredHeight);
if (fbo) {
- Caches::getInstance().activeTexture(0);
+ caches.activeTexture(0);
bindTexture();
allocateTexture();
@@ -120,14 +121,14 @@ void Layer::removeFbo(bool flush) {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
- Caches::getInstance().renderBufferCache.put(stencil);
+ caches.renderBufferCache.put(stencil);
stencil = NULL;
}
if (fbo) {
if (flush) LayerRenderer::flushLayer(this);
// If put fails the cache will delete the FBO
- Caches::getInstance().fboCache.put(fbo);
+ caches.fboCache.put(fbo);
fbo = 0;
}
}
@@ -138,11 +139,51 @@ void Layer::setPaint(SkPaint* paint) {
void Layer::setColorFilter(SkiaColorFilter* filter) {
if (colorFilter) {
- Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
+ caches.resourceCache.decrementRefcount(colorFilter);
}
colorFilter = filter;
if (colorFilter) {
- Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
+ caches.resourceCache.incrementRefcount(colorFilter);
+ }
+}
+
+void Layer::bindTexture() const {
+ if (texture.id) {
+ caches.bindTexture(renderTarget, texture.id);
+ }
+}
+
+void Layer::bindStencilRenderBuffer() const {
+ if (stencil) {
+ stencil->bind();
+ }
+}
+
+void Layer::generateTexture() {
+ if (!texture.id) {
+ glGenTextures(1, &texture.id);
+ }
+}
+
+void Layer::deleteTexture() {
+ if (texture.id) {
+ glDeleteTextures(1, &texture.id);
+ texture.id = 0;
+ }
+}
+
+void Layer::clearTexture() {
+ texture.id = 0;
+}
+
+void Layer::allocateTexture() {
+#if DEBUG_LAYERS
+ ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
+#endif
+ if (texture.id) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
}
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 7186603..326b25a 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -40,6 +40,7 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Forward declarations
+class Caches;
class OpenGLRenderer;
class DisplayList;
class DeferredDisplayList;
@@ -221,50 +222,19 @@ struct Layer {
ANDROID_API void setColorFilter(SkiaColorFilter* filter);
- inline void bindTexture() const {
- if (texture.id) {
- glBindTexture(renderTarget, texture.id);
- }
- }
-
- inline void bindStencilRenderBuffer() const {
- if (stencil) {
- stencil->bind();
- }
- }
+ void bindStencilRenderBuffer() const;
- inline void generateTexture() {
- if (!texture.id) {
- glGenTextures(1, &texture.id);
- }
- }
-
- inline void deleteTexture() {
- if (texture.id) {
- glDeleteTextures(1, &texture.id);
- texture.id = 0;
- }
- }
+ void bindTexture() const;
+ void generateTexture();
+ void allocateTexture();
+ void deleteTexture();
/**
* When the caller frees the texture itself, the caller
* must call this method to tell this layer that it lost
* the texture.
*/
- void clearTexture() {
- texture.id = 0;
- }
-
- inline void allocateTexture() {
-#if DEBUG_LAYERS
- ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
-#endif
- if (texture.id) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- }
+ ANDROID_API void clearTexture();
inline mat4& getTexTransform() {
return texTransform;
@@ -320,6 +290,8 @@ struct Layer {
bool hasDrawnSinceUpdate;
private:
+ Caches& caches;
+
/**
* Name of the FBO used to render the layer. If the name is 0
* this layer is not backed by an FBO, but a simple texture.
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 3e55fff..987daae 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -436,7 +436,7 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
if ((error = glGetError()) != GL_NO_ERROR) goto error;
caches.activeTexture(0);
- glBindTexture(GL_TEXTURE_2D, texture);
+ caches.bindTexture(texture);
glPixelStorei(GL_PACK_ALIGNMENT, bitmap->bytesPerPixel());
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index f12119a..f5343b1 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -371,6 +371,7 @@ void OpenGLRenderer::resume() {
dirtyClip();
mCaches.activeTexture(0);
+ mCaches.resetBoundTextures();
mCaches.blend = true;
glEnable(GL_BLEND);
@@ -3109,7 +3110,7 @@ void OpenGLRenderer::resetShader() {
void OpenGLRenderer::setupShader(SkiaShader* shader) {
mDrawModifiers.mShader = shader;
if (mDrawModifiers.mShader) {
- mDrawModifiers.mShader->set(&mCaches.textureCache, &mCaches.gradientCache);
+ mDrawModifiers.mShader->setCaches(mCaches);
}
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 6286e94..e9ea2f3 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -888,7 +888,7 @@ private:
* prior to calling this method.
*/
inline void bindTexture(GLuint texture) {
- glBindTexture(GL_TEXTURE_2D, texture);
+ mCaches.bindTexture(texture);
}
/**
@@ -896,7 +896,7 @@ private:
* prior to calling this method.
*/
inline void bindExternalTexture(GLuint texture) {
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
+ mCaches.bindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
}
/**
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index fdb10e2..3f6485c 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -139,7 +139,7 @@ static void drawPath(const SkPath *path, const SkPaint* paint, SkBitmap& bitmap,
static PathTexture* createTexture(float left, float top, float offset,
uint32_t width, uint32_t height, uint32_t id) {
- PathTexture* texture = new PathTexture();
+ PathTexture* texture = new PathTexture(Caches::getInstance());
texture->left = left;
texture->top = top;
texture->offset = offset;
@@ -300,7 +300,7 @@ void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
glGenTextures(1, &texture->id);
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ Caches::getInstance().bindTexture(texture->id);
// Textures are Alpha8
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index dd1f996..a191f0e 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -58,7 +58,7 @@ class Caches;
* Alpha texture used to represent a path.
*/
struct PathTexture: public Texture {
- PathTexture(): Texture() {
+ PathTexture(Caches& caches): Texture(caches) {
}
~PathTexture() {
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index c38eedb..797ed10 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -69,9 +69,13 @@ void SkiaShader::copyFrom(const SkiaShader& shader) {
mGenerationId = shader.mGenerationId;
}
+SkiaShader::SkiaShader(): mCaches(NULL) {
+}
+
SkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
SkShader::TileMode tileY, SkMatrix* matrix, bool blend):
- mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend) {
+ mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend),
+ mCaches(NULL) {
setMatrix(matrix);
mGenerationId = 0;
}
@@ -87,7 +91,7 @@ void SkiaShader::setupProgram(Program* program, const mat4& modelView, const Sna
}
void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT) {
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ mCaches->bindTexture(texture->id);
texture->setWrapST(wrapS, wrapT);
}
@@ -114,7 +118,7 @@ SkiaShader* SkiaBitmapShader::copy() {
}
void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) {
- Texture* texture = mTextureCache->get(mBitmap);
+ Texture* texture = mCaches->textureCache.get(mBitmap);
if (!texture) return;
mTexture = texture;
@@ -229,7 +233,7 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV
GLuint textureSlot = (*textureUnit)++;
Caches::getInstance().activeTexture(textureSlot);
- Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
+ Texture* texture = mCaches->gradientCache.get(mColors, mPositions, mCount);
// Uniforms
bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
@@ -349,7 +353,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi
GLuint textureSlot = (*textureUnit)++;
Caches::getInstance().activeTexture(textureSlot);
- Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
+ Texture* texture = mCaches->gradientCache.get(mColors, mPositions, mCount);
// Uniforms
bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
@@ -359,7 +363,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi
bindUniformColor(program->getUniform("endColor"), mColors[1]);
}
- Caches::getInstance().dither.setupProgram(program, textureUnit);
+ mCaches->dither.setupProgram(program, textureUnit);
mat4 screenSpace;
computeScreenSpaceMatrix(screenSpace, modelView);
@@ -394,12 +398,6 @@ SkiaShader* SkiaComposeShader::copy() {
return copy;
}
-void SkiaComposeShader::set(TextureCache* textureCache, GradientCache* gradientCache) {
- SkiaShader::set(textureCache, gradientCache);
- mFirst->set(textureCache, gradientCache);
- mSecond->set(textureCache, gradientCache);
-}
-
void SkiaComposeShader::describe(ProgramDescription& description, const Extensions& extensions) {
mFirst->describe(description, extensions);
mSecond->describe(description, extensions);
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index bc12b0d..a63431c 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -33,6 +33,8 @@
namespace android {
namespace uirenderer {
+class Caches;
+
///////////////////////////////////////////////////////////////////////////////
// Base shader
///////////////////////////////////////////////////////////////////////////////
@@ -77,9 +79,8 @@ struct SkiaShader {
return mType;
}
- virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
- mTextureCache = textureCache;
- mGradientCache = gradientCache;
+ virtual void setCaches(Caches& caches) {
+ mCaches = &caches;
}
uint32_t getGenerationId() {
@@ -103,8 +104,7 @@ struct SkiaShader {
void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
protected:
- SkiaShader() {
- }
+ SkiaShader();
/**
* The appropriate texture unit must have been activated prior to invoking
@@ -118,8 +118,7 @@ protected:
SkShader::TileMode mTileY;
bool mBlend;
- TextureCache* mTextureCache;
- GradientCache* mGradientCache;
+ Caches* mCaches;
mat4 mUnitMatrix;
mat4 mShaderMatrix;
@@ -229,7 +228,11 @@ struct SkiaComposeShader: public SkiaShader {
~SkiaComposeShader();
SkiaShader* copy();
- void set(TextureCache* textureCache, GradientCache* gradientCache);
+ void setCaches(Caches& caches) {
+ SkiaShader::setCaches(caches);
+ mFirst->setCaches(caches);
+ mSecond->setCaches(caches);
+ }
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 6976eaa..3b6cb91 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -18,6 +18,7 @@
#include <utils/JenkinsHash.h>
+#include "Caches.h"
#include "Debug.h"
#include "TextDropShadowCache.h"
#include "Properties.h"
@@ -182,7 +183,9 @@ ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32
return NULL;
}
- texture = new ShadowTexture;
+ Caches& caches = Caches::getInstance();
+
+ texture = new ShadowTexture(caches);
texture->left = shadow.penX;
texture->top = shadow.penY;
texture->width = shadow.width;
@@ -202,7 +205,7 @@ ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32
glGenTextures(1, &texture->id);
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ caches.bindTexture(texture->id);
// Textures are Alpha8
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 0bed72b6..04d7357 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -30,6 +30,8 @@
namespace android {
namespace uirenderer {
+class Caches;
+
struct ShadowText {
ShadowText(): len(0), radius(0.0f), textSize(0.0f), typeface(NULL),
flags(0), italicStyle(0.0f), scaleX(0), text(NULL), positions(NULL) {
@@ -114,7 +116,7 @@ inline hash_t hash_type(const ShadowText& entry) {
* Alpha texture used to represent a shadow.
*/
struct ShadowTexture: public Texture {
- ShadowTexture(): Texture() {
+ ShadowTexture(Caches& caches): Texture(caches) {
}
float left;
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
new file mode 100644
index 0000000..e06227c
--- /dev/null
+++ b/libs/hwui/Texture.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <utils/Log.h>
+
+#include "Caches.h"
+#include "Texture.h"
+
+namespace android {
+namespace uirenderer {
+
+Texture::Texture(): id(0), generation(0), blend(false), width(0), height(0),
+ cleanup(false), bitmapSize(0), mipMap(false), uvMapper(NULL),
+ mWrapS(GL_CLAMP_TO_EDGE), mWrapT(GL_CLAMP_TO_EDGE),
+ mMinFilter(GL_NEAREST), mMagFilter(GL_NEAREST),
+ mFirstFilter(true), mFirstWrap(true), mCaches(Caches::getInstance()) {
+}
+
+Texture::Texture(Caches& caches): id(0), generation(0), blend(false), width(0), height(0),
+ cleanup(false), bitmapSize(0), mipMap(false), uvMapper(NULL),
+ mWrapS(GL_CLAMP_TO_EDGE), mWrapT(GL_CLAMP_TO_EDGE),
+ mMinFilter(GL_NEAREST), mMagFilter(GL_NEAREST),
+ mFirstFilter(true), mFirstWrap(true), mCaches(caches) {
+}
+
+void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force,
+ GLenum renderTarget) {
+
+ if (mFirstWrap || force || wrapS != mWrapS || wrapT != mWrapT) {
+ mFirstWrap = false;
+
+ mWrapS = wrapS;
+ mWrapT = wrapT;
+
+ if (bindTexture) {
+ mCaches.bindTexture(renderTarget, id);
+ }
+
+ glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
+ glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
+ }
+}
+
+void Texture::setFilterMinMag(GLenum min, GLenum mag, bool bindTexture, bool force,
+ GLenum renderTarget) {
+
+ if (mFirstFilter || force || min != mMinFilter || mag != mMagFilter) {
+ mFirstFilter = false;
+
+ mMinFilter = min;
+ mMagFilter = mag;
+
+ if (bindTexture) {
+ mCaches.bindTexture(renderTarget, id);
+ }
+
+ if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
+
+ glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
+ glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
+ }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index f84cd67..d249741 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -22,81 +22,34 @@
namespace android {
namespace uirenderer {
+class Caches;
class UvMapper;
/**
* Represents an OpenGL texture.
*/
-struct Texture {
- Texture() {
- cleanup = false;
- bitmapSize = 0;
-
- wrapS = GL_CLAMP_TO_EDGE;
- wrapT = GL_CLAMP_TO_EDGE;
-
- minFilter = GL_NEAREST;
- magFilter = GL_NEAREST;
-
- mipMap = false;
-
- firstFilter = true;
- firstWrap = true;
-
- id = 0;
-
- uvMapper = NULL;
- }
+class Texture {
+public:
+ Texture();
+ Texture(Caches& caches);
virtual ~Texture() { }
- void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
+ inline void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
GLenum renderTarget = GL_TEXTURE_2D) {
setWrapST(wrap, wrap, bindTexture, force, renderTarget);
}
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;
-
- this->wrapS = wrapS;
- this->wrapT = wrapT;
-
- if (bindTexture) {
- glBindTexture(renderTarget, id);
- }
+ bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
- glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
- glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
- }
- }
-
- void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
+ inline void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
GLenum renderTarget = GL_TEXTURE_2D) {
setFilterMinMag(filter, filter, bindTexture, force, renderTarget);
}
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;
-
- minFilter = min;
- magFilter = mag;
-
- if (bindTexture) {
- glBindTexture(renderTarget, id);
- }
-
- if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
-
- glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
- glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
- }
- }
+ bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
/**
* Name of the texture.
@@ -140,17 +93,19 @@ private:
/**
* Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE.
*/
- GLenum wrapS;
- GLenum wrapT;
+ GLenum mWrapS;
+ GLenum mWrapT;
/**
* Last filters set on this texture. Defaults to GL_NEAREST.
*/
- GLenum minFilter;
- GLenum magFilter;
+ GLenum mMinFilter;
+ GLenum mMagFilter;
+
+ bool mFirstFilter;
+ bool mFirstWrap;
- bool firstFilter;
- bool firstWrap;
+ Caches& mCaches;
}; // struct Texture
class AutoTexture {
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 2378eb5..7f5b80f 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -139,7 +139,7 @@ Texture* TextureCache::get(SkBitmap* bitmap) {
}
}
- texture = new Texture;
+ texture = new Texture();
texture->bitmapSize = size;
generateTexture(bitmap, texture, false);
@@ -162,7 +162,7 @@ Texture* TextureCache::get(SkBitmap* bitmap) {
}
Texture* TextureCache::getTransient(SkBitmap* bitmap) {
- Texture* texture = new Texture;
+ Texture* texture = new Texture();
texture->bitmapSize = bitmap->rowBytes() * bitmap->height();
texture->cleanup = true;
@@ -235,7 +235,7 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
texture->width = bitmap->width();
texture->height = bitmap->height();
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ Caches::getInstance().bindTexture(texture->id);
switch (bitmap->getConfig()) {
case SkBitmap::kA8_Config:
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index 6c5267d..2d58338 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -17,6 +17,7 @@
#include <SkGlyph.h>
#include "CacheTexture.h"
+#include "../Caches.h"
#include "../Debug.h"
#include "../Extensions.h"
#include "../PixelBuffer.h"
@@ -110,7 +111,8 @@ CacheBlock* CacheBlock::removeBlock(CacheBlock* head, CacheBlock* blockToRemove)
CacheTexture::CacheTexture(uint16_t width, uint16_t height, uint32_t maxQuadCount) :
mTexture(NULL), mTextureId(0), mWidth(width), mHeight(height),
mLinearFiltering(false), mDirty(false), mNumGlyphs(0),
- mMesh(NULL), mCurrentQuad(0), mMaxQuadCount(maxQuadCount) {
+ mMesh(NULL), mCurrentQuad(0), mMaxQuadCount(maxQuadCount),
+ mCaches(Caches::getInstance()) {
mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true);
@@ -166,7 +168,7 @@ void CacheTexture::setLinearFiltering(bool linearFiltering, bool bind) {
mLinearFiltering = linearFiltering;
const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
- if (bind) glBindTexture(GL_TEXTURE_2D, getTextureId());
+ if (bind) mCaches.bindTexture(getTextureId());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
}
@@ -186,7 +188,7 @@ void CacheTexture::allocateTexture() {
if (!mTextureId) {
glGenTextures(1, &mTextureId);
- glBindTexture(GL_TEXTURE_2D, mTextureId);
+ mCaches.bindTexture(mTextureId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Initialize texture dimensions
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mWidth, mHeight, 0,
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index ddcc836..8c3ea0b 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -30,6 +30,7 @@
namespace android {
namespace uirenderer {
+class Caches;
class PixelBuffer;
/**
@@ -178,9 +179,10 @@ private:
TextureVertex* mMesh;
uint32_t mCurrentQuad;
uint32_t mMaxQuadCount;
+ Caches& mCaches;
CacheBlock* mCacheBlocks;
- Rect mDirtyRect;
bool mHasES3;
+ Rect mDirtyRect;
};
}; // namespace uirenderer