summaryrefslogtreecommitdiffstats
path: root/libs/hwui
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui')
-rw-r--r--libs/hwui/Caches.h75
-rw-r--r--libs/hwui/GenerationCache.h10
-rw-r--r--libs/hwui/GradientCache.cpp15
-rw-r--r--libs/hwui/GradientCache.h1
-rw-r--r--libs/hwui/LayerCache.cpp13
-rw-r--r--libs/hwui/LayerCache.h1
-rw-r--r--libs/hwui/OpenGLRenderer.cpp164
-rw-r--r--libs/hwui/OpenGLRenderer.h26
-rw-r--r--libs/hwui/PatchCache.cpp4
-rw-r--r--libs/hwui/PatchCache.h1
-rw-r--r--libs/hwui/PathCache.cpp26
-rw-r--r--libs/hwui/PathCache.h3
-rw-r--r--libs/hwui/ProgramCache.h1
-rw-r--r--libs/hwui/Properties.h12
-rw-r--r--libs/hwui/TextDropShadowCache.cpp14
-rw-r--r--libs/hwui/TextDropShadowCache.h21
-rw-r--r--libs/hwui/TextureCache.cpp27
-rw-r--r--libs/hwui/TextureCache.h3
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;