diff options
author | Romain Guy <romainguy@google.com> | 2013-06-04 18:00:09 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2013-06-04 18:58:36 -0700 |
commit | 8aa195d7081b889f3a7b1f426cbd8556377aae5e (patch) | |
tree | 6cd0ab4181c25d3113c4e39b49e8f8a0c7d12b8b /libs | |
parent | 84f3c5689cffbfc1e45a0101d5bb636323769f54 (diff) | |
download | frameworks_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')
-rw-r--r-- | libs/hwui/Android.mk | 1 | ||||
-rw-r--r-- | libs/hwui/AssetAtlas.cpp | 13 | ||||
-rw-r--r-- | libs/hwui/AssetAtlas.h | 4 | ||||
-rw-r--r-- | libs/hwui/Caches.cpp | 23 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 20 | ||||
-rw-r--r-- | libs/hwui/Dither.cpp | 11 | ||||
-rw-r--r-- | libs/hwui/Dither.h | 7 | ||||
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/GradientCache.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/Image.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 59 | ||||
-rw-r--r-- | libs/hwui/Layer.h | 46 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 4 | ||||
-rw-r--r-- | libs/hwui/PathCache.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/PathCache.h | 2 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.cpp | 22 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.h | 19 | ||||
-rw-r--r-- | libs/hwui/TextDropShadowCache.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/TextDropShadowCache.h | 4 | ||||
-rw-r--r-- | libs/hwui/Texture.cpp | 80 | ||||
-rw-r--r-- | libs/hwui/Texture.h | 79 | ||||
-rw-r--r-- | libs/hwui/TextureCache.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/font/CacheTexture.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/font/CacheTexture.h | 4 |
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 |