diff options
Diffstat (limited to 'libs/hwui')
-rw-r--r-- | libs/hwui/Caches.h | 75 | ||||
-rw-r--r-- | libs/hwui/GenerationCache.h | 10 | ||||
-rw-r--r-- | libs/hwui/GradientCache.cpp | 15 | ||||
-rw-r--r-- | libs/hwui/GradientCache.h | 1 | ||||
-rw-r--r-- | libs/hwui/LayerCache.cpp | 13 | ||||
-rw-r--r-- | libs/hwui/LayerCache.h | 1 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 164 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 26 | ||||
-rw-r--r-- | libs/hwui/PatchCache.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/PatchCache.h | 1 | ||||
-rw-r--r-- | libs/hwui/PathCache.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/PathCache.h | 3 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.h | 1 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 12 | ||||
-rw-r--r-- | libs/hwui/TextDropShadowCache.cpp | 14 | ||||
-rw-r--r-- | libs/hwui/TextDropShadowCache.h | 21 | ||||
-rw-r--r-- | libs/hwui/TextureCache.cpp | 27 | ||||
-rw-r--r-- | libs/hwui/TextureCache.h | 3 |
18 files changed, 257 insertions, 160 deletions
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h new file mode 100644 index 0000000..0789d89 --- /dev/null +++ b/libs/hwui/Caches.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2010 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. + */ + +#ifndef ANDROID_UI_CACHES_H +#define ANDROID_UI_CACHES_H + +#define LOG_TAG "OpenGLRenderer" + +#include <utils/Singleton.h> + +#include "TextureCache.h" +#include "LayerCache.h" +#include "GradientCache.h" +#include "PatchCache.h" +#include "FontRenderer.h" +#include "ProgramCache.h" +#include "PathCache.h" +#include "TextDropShadowCache.h" + +namespace android { +namespace uirenderer { + +struct CacheLogger { + CacheLogger() { + LOGD("Creating caches"); + } +}; // struct CacheLogger + +class Caches: public Singleton<Caches> { + Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO), + lastDstMode(GL_ZERO), currentProgram(NULL) { + dropShadowCache.setFontRenderer(fontRenderer); + } + + friend class Singleton<Caches>; + + CacheLogger logger; + +public: + bool blend; + GLenum lastSrcMode; + GLenum lastDstMode; + Program* currentProgram; + + TextureCache textureCache; + LayerCache layerCache; + GradientCache gradientCache; + ProgramCache programCache; + PathCache pathCache; + PatchCache patchCache; + TextDropShadowCache dropShadowCache; + FontRenderer fontRenderer; +}; // class Caches + +}; // namespace uirenderer + +using namespace uirenderer; +ANDROID_SINGLETON_STATIC_INSTANCE(Caches); + +}; // namespace android + +#endif // ANDROID_UI_CACHES_H diff --git a/libs/hwui/GenerationCache.h b/libs/hwui/GenerationCache.h index 45b3ffa..c358c80 100644 --- a/libs/hwui/GenerationCache.h +++ b/libs/hwui/GenerationCache.h @@ -104,12 +104,14 @@ void GenerationCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* list template<typename K, typename V> void GenerationCache<K, V>::clear() { if (mListener) { - while (mCache.size() > 0) { - removeOldest(); + for (uint32_t i = 0; i < mCache.size(); i++) { + sp<Entry<K, V> > entry = mCache.valueAt(i); + if (mListener) { + (*mListener)(entry->key, entry->value); + } } - } else { - mCache.clear(); } + mCache.clear(); mYoungest.clear(); mOldest.clear(); } diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp index 59fa0a7..58920bd 100644 --- a/libs/hwui/GradientCache.cpp +++ b/libs/hwui/GradientCache.cpp @@ -22,6 +22,7 @@ #include <SkGradientShader.h> #include "GradientCache.h" +#include "Properties.h" namespace android { namespace uirenderer { @@ -30,6 +31,20 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// +GradientCache::GradientCache(): + mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity), + mSize(0), mMaxSize(MB(DEFAULT_GRADIENT_CACHE_SIZE)) { + char property[PROPERTY_VALUE_MAX]; + if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) { + LOGD(" Setting gradient cache size to %sMB", property); + setMaxSize(MB(atof(property))); + } else { + LOGD(" Using default gradient cache size of %.2fMB", DEFAULT_GRADIENT_CACHE_SIZE); + } + + mCache.setOnEntryRemovedListener(this); +} + GradientCache::GradientCache(uint32_t maxByteSize): mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h index 12c8a23..8795920 100644 --- a/libs/hwui/GradientCache.h +++ b/libs/hwui/GradientCache.h @@ -32,6 +32,7 @@ namespace uirenderer { */ class GradientCache: public OnEntryRemoved<SkShader*, Texture*> { public: + GradientCache(); GradientCache(uint32_t maxByteSize); ~GradientCache(); diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp index 3d263a3..a204778 100644 --- a/libs/hwui/LayerCache.cpp +++ b/libs/hwui/LayerCache.cpp @@ -21,6 +21,7 @@ #include <utils/Log.h> #include "LayerCache.h" +#include "Properties.h" namespace android { namespace uirenderer { @@ -29,6 +30,18 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// +LayerCache::LayerCache(): + mCache(GenerationCache<LayerSize, Layer*>::kUnlimitedCapacity), + mIdGenerator(1), mSize(0), mMaxSize(MB(DEFAULT_LAYER_CACHE_SIZE)) { + char property[PROPERTY_VALUE_MAX]; + if (property_get(PROPERTY_LAYER_CACHE_SIZE, property, NULL) > 0) { + LOGD(" Setting layer cache size to %sMB", property); + setMaxSize(MB(atof(property))); + } else { + LOGD(" Using default layer cache size of %.2fMB", DEFAULT_LAYER_CACHE_SIZE); + } +} + LayerCache::LayerCache(uint32_t maxByteSize): mCache(GenerationCache<LayerSize, Layer*>::kUnlimitedCapacity), mIdGenerator(1), mSize(0), mMaxSize(maxByteSize) { diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h index 2580551..9860994 100644 --- a/libs/hwui/LayerCache.h +++ b/libs/hwui/LayerCache.h @@ -43,6 +43,7 @@ namespace uirenderer { class LayerCache: public OnEntryRemoved<LayerSize, Layer*> { public: + LayerCache(); LayerCache(uint32_t maxByteSize); ~LayerCache(); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 49d49da..033d8e2 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -23,11 +23,9 @@ #include <SkCanvas.h> #include <SkTypeface.h> -#include <cutils/properties.h> #include <utils/Log.h> #include "OpenGLRenderer.h" -#include "Properties.h" namespace android { namespace uirenderer { @@ -36,18 +34,8 @@ namespace uirenderer { // Defines /////////////////////////////////////////////////////////////////////////////// -#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f -#define DEFAULT_LAYER_CACHE_SIZE 6.0f -#define DEFAULT_PATH_CACHE_SIZE 6.0f -#define DEFAULT_PATCH_CACHE_SIZE 100 -#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f -#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f - #define REQUIRED_TEXTURE_UNITS_COUNT 3 -// Converts a number of mega-bytes into bytes -#define MB(s) s * 1024 * 1024 - // Generates simple and textured vertices #define FV(x, y, u, v) { { x, y }, { u, v } } @@ -102,54 +90,9 @@ static const GLenum gTextureUnits[] = { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// -OpenGLRenderer::OpenGLRenderer(): - mBlend(false), mLastSrcMode(GL_ZERO), mLastDstMode(GL_ZERO), - mTextureCache(MB(DEFAULT_TEXTURE_CACHE_SIZE)), - mLayerCache(MB(DEFAULT_LAYER_CACHE_SIZE)), - mGradientCache(MB(DEFAULT_GRADIENT_CACHE_SIZE)), - mPathCache(MB(DEFAULT_PATH_CACHE_SIZE)), - mPatchCache(DEFAULT_PATCH_CACHE_SIZE), - mDropShadowCache(MB(DEFAULT_DROP_SHADOW_CACHE_SIZE)) { +OpenGLRenderer::OpenGLRenderer(): mCaches(Caches::getInstance()) { LOGD("Create OpenGLRenderer"); - char property[PROPERTY_VALUE_MAX]; - if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) { - LOGD(" Setting texture cache size to %sMB", property); - mTextureCache.setMaxSize(MB(atof(property))); - } else { - LOGD(" Using default texture cache size of %.2fMB", DEFAULT_TEXTURE_CACHE_SIZE); - } - - if (property_get(PROPERTY_LAYER_CACHE_SIZE, property, NULL) > 0) { - LOGD(" Setting layer cache size to %sMB", property); - mLayerCache.setMaxSize(MB(atof(property))); - } else { - LOGD(" Using default layer cache size of %.2fMB", DEFAULT_LAYER_CACHE_SIZE); - } - - if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) { - LOGD(" Setting gradient cache size to %sMB", property); - mGradientCache.setMaxSize(MB(atof(property))); - } else { - LOGD(" Using default gradient cache size of %.2fMB", DEFAULT_GRADIENT_CACHE_SIZE); - } - - if (property_get(PROPERTY_PATH_CACHE_SIZE, property, NULL) > 0) { - LOGD(" Setting path cache size to %sMB", property); - mPathCache.setMaxSize(MB(atof(property))); - } else { - LOGD(" Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE); - } - - if (property_get(PROPERTY_DROP_SHADOW_CACHE_SIZE, property, NULL) > 0) { - LOGD(" Setting drop shadow cache size to %sMB", property); - mDropShadowCache.setMaxSize(MB(atof(property))); - } else { - LOGD(" Using default drop shadow cache size of %.2fMB", DEFAULT_DROP_SHADOW_CACHE_SIZE); - } - mDropShadowCache.setFontRenderer(mFontRenderer); - - mCurrentProgram = NULL; mShader = NULL; mColorFilter = NULL; mHasShadow = false; @@ -167,14 +110,6 @@ OpenGLRenderer::OpenGLRenderer(): OpenGLRenderer::~OpenGLRenderer() { LOGD("Destroy OpenGLRenderer"); - - mTextureCache.clear(); - mLayerCache.clear(); - mGradientCache.clear(); - mPathCache.clear(); - mPatchCache.clear(); - mProgramCache.clear(); - mDropShadowCache.clear(); } /////////////////////////////////////////////////////////////////////////////// @@ -195,6 +130,8 @@ void OpenGLRenderer::prepare() { mSnapshot = new Snapshot(mFirstSnapshot); mSaveCount = 1; + glViewport(0, 0, mWidth, mHeight); + glDisable(GL_SCISSOR_TEST); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -310,12 +247,12 @@ int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bot bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode,int flags) { LAYER_LOGD("Requesting layer %fx%f", right - left, bottom - top); - LAYER_LOGD("Layer cache size = %d", mLayerCache.getSize()); + LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize()); GLuint previousFbo = snapshot->previous.get() ? snapshot->previous->fbo : 0; LayerSize size(right - left, bottom - top); - Layer* layer = mLayerCache.get(size, previousFbo); + Layer* layer = mCaches.layerCache.get(size, previousFbo); if (!layer) { return false; } @@ -380,7 +317,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { LayerSize size(rect.getWidth(), rect.getHeight()); // Failing to add the layer to the cache should happen only if the // layer is too large - if (!mLayerCache.put(size, layer)) { + if (!mCaches.layerCache.put(size, layer)) { LAYER_LOGD("Deleting layer"); glDeleteFramebuffers(1, &layer->fbo); @@ -461,7 +398,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const S } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mTextureCache.get(bitmap); + const Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -478,7 +415,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mTextureCache.get(bitmap); + const Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -494,7 +431,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mTextureCache.get(bitmap); + const Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -520,7 +457,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mTextureCache.get(bitmap); + const Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -528,7 +465,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch, SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); - Patch* mesh = mPatchCache.get(patch); + Patch* mesh = mCaches.patchCache.get(patch); mesh->updateVertices(bitmap, left, top, right, bottom, &patch->xDivs[0], &patch->yDivs[0], patch->numXDivs, patch->numYDivs); @@ -607,10 +544,11 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, const GLfloat g = a * ((color >> 8) & 0xFF) / 255.0f; const GLfloat b = a * ((color ) & 0xFF) / 255.0f; - mFontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize()); + mCaches.fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), + paint->getTextSize()); if (mHasShadow) { glActiveTexture(gTextureUnits[0]); - const ShadowTexture* shadow = mDropShadowCache.get(paint, text, bytesCount, + const ShadowTexture* shadow = mCaches.dropShadowCache.get(paint, text, bytesCount, count, mShadowRadius); const AutoTexture autoCleanup(shadow); @@ -618,20 +556,20 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, // Draw the mesh glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); - glDisableVertexAttribArray(mCurrentProgram->getAttrib("texCoords")); + glDisableVertexAttribArray(mCaches.currentProgram->getAttrib("texCoords")); } GLuint textureUnit = 0; glActiveTexture(gTextureUnits[textureUnit]); - setupTextureAlpha8(mFontRenderer.getTexture(), 0, 0, textureUnit, x, y, r, g, b, a, + setupTextureAlpha8(mCaches.fontRenderer.getTexture(), 0, 0, textureUnit, x, y, r, g, b, a, mode, false, true); const Rect& clip = mSnapshot->getLocalClip(); - mFontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y); + mCaches.fontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDisableVertexAttribArray(mCurrentProgram->getAttrib("texCoords")); + glDisableVertexAttribArray(mCaches.currentProgram->getAttrib("texCoords")); drawTextDecorations(text, bytesCount, length, x, y, paint); @@ -646,7 +584,7 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { GLuint textureUnit = 0; glActiveTexture(gTextureUnits[textureUnit]); - const PathTexture* texture = mPathCache.get(path, paint); + const PathTexture* texture = mCaches.pathCache.get(path, paint); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -671,7 +609,7 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { // Draw the mesh glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); - glDisableVertexAttribArray(mCurrentProgram->getAttrib("texCoords")); + glDisableVertexAttribArray(mCaches.currentProgram->getAttrib("texCoords")); } /////////////////////////////////////////////////////////////////////////////// @@ -685,7 +623,7 @@ void OpenGLRenderer::resetShader() { void OpenGLRenderer::setupShader(SkiaShader* shader) { mShader = shader; if (mShader) { - mShader->set(&mTextureCache, &mGradientCache); + mShader->set(&mCaches.textureCache, &mCaches.gradientCache); } } @@ -761,18 +699,18 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t } // Build and use the appropriate shader - useProgram(mProgramCache.get(description)); + useProgram(mCaches.programCache.get(description)); // Setup the blending mode chooseBlending(true, mode); bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit); - glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit); + glUniform1i(mCaches.currentProgram->getUniform("sampler"), textureUnit); - int texCoordsSlot = mCurrentProgram->getAttrib("texCoords"); + int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); glEnableVertexAttribArray(texCoordsSlot); // Setup attributes - glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE, + glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, gMeshStride, &mMeshVertices[0].position[0]); glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, &mMeshVertices[0].texture[0]); @@ -784,17 +722,17 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t } else { mModelView.loadIdentity(); } - mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform); - glUniform4f(mCurrentProgram->color, r, g, b, a); + mCaches.currentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform); + glUniform4f(mCaches.currentProgram->color, r, g, b, a); textureUnit++; if (applyFilters) { // Setup attributes and uniforms required by the shaders if (mShader) { - mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit); + mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &textureUnit); } if (mColorFilter) { - mColorFilter->setupProgram(mCurrentProgram); + mColorFilter->setupProgram(mCaches.currentProgram); } } } @@ -879,29 +817,29 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot } // Build and use the appropriate shader - useProgram(mProgramCache.get(description)); + useProgram(mCaches.programCache.get(description)); // Setup attributes - glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE, + glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, gMeshStride, &mMeshVertices[0].position[0]); // Setup uniforms mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); if (!ignoreTransform) { - mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform); + mCaches.currentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform); } else { mat4 identity; - mCurrentProgram->set(mOrthoMatrix, mModelView, identity); + mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity); } - glUniform4f(mCurrentProgram->color, r, g, b, a); + glUniform4f(mCaches.currentProgram->color, r, g, b, a); // Setup attributes and uniforms required by the shaders if (mShader) { - mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit); + mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &textureUnit); } if (mColorFilter) { - mColorFilter->setupProgram(mCurrentProgram); + mColorFilter->setupProgram(mCaches.currentProgram); } // Draw the mesh @@ -936,28 +874,28 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); - useProgram(mProgramCache.get(description)); - mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform); + useProgram(mCaches.programCache.get(description)); + mCaches.currentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform); chooseBlending(blend || alpha < 1.0f, mode); // Texture bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 0); - glUniform1i(mCurrentProgram->getUniform("sampler"), 0); + glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0); // Always premultiplied - glUniform4f(mCurrentProgram->color, alpha, alpha, alpha, alpha); + glUniform4f(mCaches.currentProgram->color, alpha, alpha, alpha, alpha); // Mesh - int texCoordsSlot = mCurrentProgram->getAttrib("texCoords"); + int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); glEnableVertexAttribArray(texCoordsSlot); - glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE, + glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE, gMeshStride, vertices); glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE, gMeshStride, texCoords); // Color filter if (mColorFilter) { - mColorFilter->setupProgram(mCurrentProgram); + mColorFilter->setupProgram(mCaches.currentProgram); } if (!indices) { @@ -971,7 +909,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, bool isPremultiplied) { blend = blend || mode != SkXfermode::kSrcOver_Mode; if (blend) { - if (!mBlend) { + if (!mCaches.blend) { glEnable(GL_BLEND); } @@ -981,22 +919,22 @@ void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, bool isPr sourceMode = GL_SRC_ALPHA; } - if (sourceMode != mLastSrcMode || destMode != mLastDstMode) { + if (sourceMode != mCaches.lastSrcMode || destMode != mCaches.lastDstMode) { glBlendFunc(sourceMode, destMode); - mLastSrcMode = sourceMode; - mLastDstMode = destMode; + mCaches.lastSrcMode = sourceMode; + mCaches.lastDstMode = destMode; } - } else if (mBlend) { + } else if (mCaches.blend) { glDisable(GL_BLEND); } - mBlend = blend; + mCaches.blend = blend; } bool OpenGLRenderer::useProgram(Program* program) { if (!program->isInUse()) { - if (mCurrentProgram != NULL) mCurrentProgram->remove(); + if (mCaches.currentProgram != NULL) mCaches.currentProgram->remove(); program->use(); - mCurrentProgram = program; + mCaches.currentProgram = program; return false; } return true; diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 5c0089f..5748d57 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -35,17 +35,10 @@ #include "Program.h" #include "Rect.h" #include "Snapshot.h" -#include "TextureCache.h" -#include "LayerCache.h" -#include "GradientCache.h" -#include "PatchCache.h" #include "Vertex.h" -#include "FontRenderer.h" -#include "ProgramCache.h" #include "SkiaShader.h" #include "SkiaColorFilter.h" -#include "PathCache.h" -#include "TextDropShadowCache.h" +#include "Caches.h" namespace android { namespace uirenderer { @@ -356,7 +349,6 @@ private: sp<Snapshot> mSnapshot; // Shaders - Program* mCurrentProgram; SkiaShader* mShader; // Color filters @@ -365,17 +357,9 @@ private: // Used to draw textured quads TextureVertex mMeshVertices[4]; - // Last known blend state - bool mBlend; - GLenum mLastSrcMode; - GLenum mLastDstMode; - // GL extensions Extensions mExtensions; - // Font renderer - FontRenderer mFontRenderer; - // Drop shadow bool mHasShadow; float mShadowRadius; @@ -384,13 +368,7 @@ private: int mShadowColor; // Various caches - TextureCache mTextureCache; - LayerCache mLayerCache; - GradientCache mGradientCache; - ProgramCache mProgramCache; - PathCache mPathCache; - PatchCache mPatchCache; - TextDropShadowCache mDropShadowCache; + Caches& mCaches; }; // class OpenGLRenderer }; // namespace uirenderer diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp index 694e3fd..a7c0cce 100644 --- a/libs/hwui/PatchCache.cpp +++ b/libs/hwui/PatchCache.cpp @@ -20,6 +20,7 @@ #include <utils/ResourceTypes.h> #include "PatchCache.h" +#include "Properties.h" namespace android { namespace uirenderer { @@ -28,6 +29,9 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// +PatchCache::PatchCache(): mCache(DEFAULT_PATCH_CACHE_SIZE) { +} + PatchCache::PatchCache(uint32_t maxEntries): mCache(maxEntries) { } diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h index de95087..e874a16 100644 --- a/libs/hwui/PatchCache.h +++ b/libs/hwui/PatchCache.h @@ -43,6 +43,7 @@ namespace uirenderer { class PatchCache: public OnEntryRemoved<PatchDescription, Patch*> { public: + PatchCache(); PatchCache(uint32_t maxCapacity); ~PatchCache(); diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 10440ea..158c0cc 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -22,6 +22,7 @@ #include <SkRect.h> #include "PathCache.h" +#include "Properties.h" namespace android { namespace uirenderer { @@ -30,9 +31,30 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// +PathCache::PathCache(): + mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity), + mSize(0), mMaxSize(MB(DEFAULT_PATH_CACHE_SIZE)) { + char property[PROPERTY_VALUE_MAX]; + if (property_get(PROPERTY_PATH_CACHE_SIZE, property, NULL) > 0) { + LOGD(" Setting path cache size to %sMB", property); + setMaxSize(MB(atof(property))); + } else { + LOGD(" Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE); + } + init(); +} + PathCache::PathCache(uint32_t maxByteSize): mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { + init(); +} + +PathCache::~PathCache() { + mCache.clear(); +} + +void PathCache::init() { mCache.setOnEntryRemovedListener(this); GLint maxTextureSize; @@ -40,10 +62,6 @@ PathCache::PathCache(uint32_t maxByteSize): mMaxTextureSize = maxTextureSize; } -PathCache::~PathCache() { - mCache.clear(); -} - /////////////////////////////////////////////////////////////////////////////// // Size management /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h index d09789f..522e5e0 100644 --- a/libs/hwui/PathCache.h +++ b/libs/hwui/PathCache.h @@ -95,6 +95,7 @@ struct PathTexture: public Texture { */ class PathCache: public OnEntryRemoved<PathCacheEntry, PathTexture*> { public: + PathCache(); PathCache(uint32_t maxByteSize); ~PathCache(); @@ -135,6 +136,8 @@ private: PathTexture* addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint); + void init(); + GenerationCache<PathCacheEntry, PathTexture*> mCache; uint32_t mSize; diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h index fa4b8c4..f211ab6 100644 --- a/libs/hwui/ProgramCache.h +++ b/libs/hwui/ProgramCache.h @@ -183,7 +183,6 @@ private: void printLongString(const String8& shader) const; KeyedVector<programid, Program*> mCache; - }; // class ProgramCache }; // namespace uirenderer diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 7514b6f..dfe022a 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -17,6 +17,8 @@ #ifndef ANDROID_UI_PROPERTIES_H #define ANDROID_UI_PROPERTIES_H +#include <cutils/properties.h> + /** * This file contains the list of system properties used to configure * the OpenGLRenderer. @@ -33,4 +35,14 @@ #define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width" #define PROPERTY_TEXT_CACHE_HEIGHT "ro.hwui.text_cache_height" +// Converts a number of mega-bytes into bytes +#define MB(s) s * 1024 * 1024 + +#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f +#define DEFAULT_LAYER_CACHE_SIZE 6.0f +#define DEFAULT_PATH_CACHE_SIZE 6.0f +#define DEFAULT_PATCH_CACHE_SIZE 100 +#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f +#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f + #endif // ANDROID_UI_PROPERTIES_H diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp index aab5bd4..f95d2be 100644 --- a/libs/hwui/TextDropShadowCache.cpp +++ b/libs/hwui/TextDropShadowCache.cpp @@ -25,6 +25,20 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// +TextDropShadowCache::TextDropShadowCache(): + mCache(GenerationCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity), + mSize(0), mMaxSize(MB(DEFAULT_DROP_SHADOW_CACHE_SIZE)) { + char property[PROPERTY_VALUE_MAX]; + if (property_get(PROPERTY_DROP_SHADOW_CACHE_SIZE, property, NULL) > 0) { + LOGD(" Setting drop shadow cache size to %sMB", property); + setMaxSize(MB(atof(property))); + } else { + LOGD(" Using default drop shadow cache size of %.2fMB", DEFAULT_DROP_SHADOW_CACHE_SIZE); + } + + mCache.setOnEntryRemovedListener(this); +} + TextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize): mCache(GenerationCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h index c3be483..b65d62a 100644 --- a/libs/hwui/TextDropShadowCache.h +++ b/libs/hwui/TextDropShadowCache.h @@ -69,16 +69,16 @@ struct ShadowText { char *text; bool operator<(const ShadowText& rhs) const { - if (len < rhs.len) return true; - else if (len == rhs.len) { - if (radius < rhs.radius) return true; - else if (radius == rhs.radius) { - if (textSize < rhs.textSize) return true; - else if (textSize == rhs.textSize) { - if (typeface < rhs.typeface) return true; - else if (typeface == rhs.typeface) { - if (hash < rhs.hash) return true; - if (hash == rhs.hash) { + if (hash < rhs.hash) return true; + else if (hash == rhs.hash) { + if (len < rhs.len) return true; + else if (len == rhs.len) { + if (radius < rhs.radius) return true; + else if (radius == rhs.radius) { + if (textSize < rhs.textSize) return true; + else if (textSize == rhs.textSize) { + if (typeface < rhs.typeface) return true; + else if (typeface == rhs.typeface) { return strncmp(text, rhs.text, len) < 0; } } @@ -102,6 +102,7 @@ struct ShadowTexture: public Texture { class TextDropShadowCache: public OnEntryRemoved<ShadowText, ShadowTexture*> { public: + TextDropShadowCache(); TextDropShadowCache(uint32_t maxByteSize); ~TextDropShadowCache(); diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 2e8a8be..753c544 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -19,6 +19,7 @@ #include <GLES2/gl2.h> #include "TextureCache.h" +#include "Properties.h" namespace android { namespace uirenderer { @@ -27,19 +28,37 @@ namespace uirenderer { // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// +TextureCache::TextureCache(): + mCache(GenerationCache<SkBitmap*, Texture*>::kUnlimitedCapacity), + mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)) { + char property[PROPERTY_VALUE_MAX]; + if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) { + LOGD(" Setting texture cache size to %sMB", property); + setMaxSize(MB(atof(property))); + } else { + LOGD(" Using default texture cache size of %.2fMB", DEFAULT_TEXTURE_CACHE_SIZE); + } + + init(); +} + TextureCache::TextureCache(uint32_t maxByteSize): mCache(GenerationCache<SkBitmap*, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { - mCache.setOnEntryRemovedListener(this); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); - LOGD("Maximum texture dimension is %d pixels", mMaxTextureSize); + init(); } TextureCache::~TextureCache() { mCache.clear(); } +void TextureCache::init() { + mCache.setOnEntryRemovedListener(this); + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); + LOGD(" Maximum texture dimension is %d pixels", mMaxTextureSize); +} + /////////////////////////////////////////////////////////////////////////////// // Size management /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index 452716c..b5e4c7c 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -32,6 +32,7 @@ namespace uirenderer { */ class TextureCache: public OnEntryRemoved<SkBitmap*, Texture*> { public: + TextureCache(); TextureCache(uint32_t maxByteSize); ~TextureCache(); @@ -78,6 +79,8 @@ private: */ void generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate = false); + void init(); + GenerationCache<SkBitmap*, Texture*> mCache; uint32_t mSize; |