From ad93c2bb63dfc813b2eefa1043aa63afbddce655 Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Fri, 22 Oct 2010 16:17:12 -0700 Subject: Optimizing ColorFilter in display lists Change-Id: Ie4d5e5b0bc45e0ce47bba144049303c270762e54 --- libs/hwui/DisplayListRenderer.cpp | 10 +++------- libs/hwui/DisplayListRenderer.h | 17 +++++++++++++++++ libs/hwui/ResourceCache.cpp | 34 +++++++++++++++++++++++++++++++++- libs/hwui/ResourceCache.h | 5 +++++ libs/hwui/SkiaColorFilter.cpp | 15 ++++++++------- libs/hwui/SkiaColorFilter.h | 16 ++++++++++++---- 6 files changed, 78 insertions(+), 19 deletions(-) (limited to 'libs/hwui') diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index a9cd5be..0dd9c5a 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -288,7 +288,7 @@ void DisplayList::replay(OpenGLRenderer& renderer) { } break; case SetupColorFilter: { - // TODO: Implement + renderer.setupColorFilter(getColorFilter()); } break; case ResetShadow: { @@ -512,7 +512,6 @@ void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, void DisplayListRenderer::resetShader() { addOp(DisplayList::ResetShader); - OpenGLRenderer::resetShader(); } void DisplayListRenderer::setupShader(SkiaShader* shader) { @@ -522,17 +521,15 @@ void DisplayListRenderer::setupShader(SkiaShader* shader) { void DisplayListRenderer::resetColorFilter() { addOp(DisplayList::ResetColorFilter); - OpenGLRenderer::resetColorFilter(); } void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { - // TODO: Implement - OpenGLRenderer::setupColorFilter(filter); + addOp(DisplayList::SetupColorFilter); + addColorFilter(filter); } void DisplayListRenderer::resetShadow() { addOp(DisplayList::ResetShadow); - OpenGLRenderer::resetShadow(); } void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { @@ -540,7 +537,6 @@ void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int colo addFloat(radius); addPoint(dx, dy); addInt(color); - OpenGLRenderer::setupShadow(radius, dx, dy, color); } }; // namespace uirenderer diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index ce4cfc5..6636de6 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -135,6 +135,10 @@ private: return (SkiaShader*) getInt(); } + SkiaColorFilter* getColorFilter() { + return (SkiaColorFilter*) getInt(); + } + inline int getIndex() { return mReader.readInt(); } @@ -183,6 +187,7 @@ private: Vector mBitmapResources; Vector mShaderResources; + Vector mFilterResources; Vector mPaints; Vector mMatrices; @@ -276,6 +281,10 @@ public: return mMatrices; } + const Vector& getFilterResources() const { + return mFilterResources; + } + private: inline void addOp(DisplayList::Op drawOp) { mWriter.writeInt(drawOp); @@ -372,10 +381,18 @@ private: caches.resourceCache.incrementRefcount(shader); } + inline void addColorFilter(SkiaColorFilter* colorFilter) { + addInt((int)colorFilter); + mFilterResources.add(colorFilter); + Caches& caches = Caches::getInstance(); + caches.resourceCache.incrementRefcount(colorFilter); + } + SkChunkAlloc mHeap; Vector mBitmapResources; Vector mShaderResources; + Vector mFilterResources; Vector mPaints; DefaultKeyedVector mPaintMap; diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index b0fbe65..47c5d48 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -67,6 +67,11 @@ void ResourceCache::incrementRefcount(SkiaShader* shaderResource) { incrementRefcount((void*)shaderResource, kShader); } +void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) { + filterResource->getSkColorFilter()->safeRef(); + incrementRefcount((void*)filterResource, kColorFilter); +} + void ResourceCache::decrementRefcount(void* resource) { ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; if (ref == NULL) { @@ -90,6 +95,11 @@ void ResourceCache::decrementRefcount(SkiaShader* shaderResource) { decrementRefcount((void*)shaderResource); } +void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) { + filterResource->getSkColorFilter()->safeUnref(); + decrementRefcount((void*)filterResource); +} + void ResourceCache::recycle(SkBitmap* resource) { if (mCache->indexOfKey(resource) < 0) { // not tracking this resource; just recycle the pixel data @@ -145,6 +155,20 @@ void ResourceCache::destructor(SkiaShader* resource) { } } +void ResourceCache::destructor(SkiaColorFilter* resource) { + ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; + if (ref == NULL) { + // If we're not tracking this resource, just delete it + delete resource; + return; + } + ref->destroyed = true; + if (ref->refCount == 0) { + deleteResourceReference(resource, ref); + return; + } +} + void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) { if (ref->recycled && ref->resourceType == kBitmap) { ((SkBitmap*) resource)->setPixels(NULL, NULL); @@ -161,12 +185,20 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r } break; case kShader: + { SkiaShader* shader = (SkiaShader*)resource; if (Caches::hasInstance()) { Caches::getInstance().gradientCache.remove(shader->getSkShader()); } delete shader; - break; + } + break; + case kColorFilter: + { + SkiaColorFilter* filter = (SkiaColorFilter*)resource; + delete filter; + } + break; } } mCache->removeItem(resource); diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h index b550367..d9b3718 100644 --- a/libs/hwui/ResourceCache.h +++ b/libs/hwui/ResourceCache.h @@ -18,6 +18,7 @@ #define ANDROID_UI_RESOURCE_CACHE_H #include +#include #include #include @@ -30,6 +31,7 @@ namespace uirenderer { enum ResourceType { kBitmap, kShader, + kColorFilter, }; class ResourceReference { @@ -53,14 +55,17 @@ public: ~ResourceCache(); void incrementRefcount(SkBitmap* resource); void incrementRefcount(SkiaShader* resource); + void incrementRefcount(SkiaColorFilter* resource); void incrementRefcount(const void* resource, ResourceType resourceType); void decrementRefcount(void* resource); void decrementRefcount(SkBitmap* resource); void decrementRefcount(SkiaShader* resource); + void decrementRefcount(SkiaColorFilter* resource); void recycle(void* resource); void recycle(SkBitmap* resource); void destructor(SkBitmap* resource); void destructor(SkiaShader* resource); + void destructor(SkiaColorFilter* resource); private: void deleteResourceReference(void* resource, ResourceReference* ref); void incrementRefcount(void* resource, ResourceType resourceType); diff --git a/libs/hwui/SkiaColorFilter.cpp b/libs/hwui/SkiaColorFilter.cpp index fe57ae7..91b1c32 100644 --- a/libs/hwui/SkiaColorFilter.cpp +++ b/libs/hwui/SkiaColorFilter.cpp @@ -23,7 +23,8 @@ namespace uirenderer { // Base color filter /////////////////////////////////////////////////////////////////////////////// -SkiaColorFilter::SkiaColorFilter(Type type, bool blend): mType(type), mBlend(blend) { +SkiaColorFilter::SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend): + mType(type), mBlend(blend), mSkFilter(skFilter) { } SkiaColorFilter::~SkiaColorFilter() { @@ -33,8 +34,8 @@ SkiaColorFilter::~SkiaColorFilter() { // Color matrix filter /////////////////////////////////////////////////////////////////////////////// -SkiaColorMatrixFilter::SkiaColorMatrixFilter(float* matrix, float* vector): - SkiaColorFilter(kColorMatrix, true), mMatrix(matrix), mVector(vector) { +SkiaColorMatrixFilter::SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector): + SkiaColorFilter(skFilter, kColorMatrix, true), mMatrix(matrix), mVector(vector) { } SkiaColorMatrixFilter::~SkiaColorMatrixFilter() { @@ -56,8 +57,8 @@ void SkiaColorMatrixFilter::setupProgram(Program* program) { // Lighting color filter /////////////////////////////////////////////////////////////////////////////// -SkiaLightingFilter::SkiaLightingFilter(int multiply, int add): - SkiaColorFilter(kLighting, true) { +SkiaLightingFilter::SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add): + SkiaColorFilter(skFilter, kLighting, true) { mMulR = ((multiply >> 16) & 0xFF) / 255.0f; mMulG = ((multiply >> 8) & 0xFF) / 255.0f; mMulB = ((multiply ) & 0xFF) / 255.0f; @@ -80,8 +81,8 @@ void SkiaLightingFilter::setupProgram(Program* program) { // Blend color filter /////////////////////////////////////////////////////////////////////////////// -SkiaBlendFilter::SkiaBlendFilter(int color, SkXfermode::Mode mode): - SkiaColorFilter(kBlend, true), mMode(mode) { +SkiaBlendFilter::SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode): + SkiaColorFilter(skFilter, kBlend, true), mMode(mode) { const int alpha = (color >> 24) & 0xFF; mA = alpha / 255.0f; mR = mA * ((color >> 16) & 0xFF) / 255.0f; diff --git a/libs/hwui/SkiaColorFilter.h b/libs/hwui/SkiaColorFilter.h index 865b6f0..17f49f9 100644 --- a/libs/hwui/SkiaColorFilter.h +++ b/libs/hwui/SkiaColorFilter.h @@ -18,6 +18,7 @@ #define ANDROID_UI_SKIA_COLOR_FILTER_H #include +#include #include "ProgramCache.h" #include "Extensions.h" @@ -44,7 +45,7 @@ struct SkiaColorFilter { kBlend, }; - SkiaColorFilter(Type type, bool blend); + SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend); virtual ~SkiaColorFilter(); virtual void describe(ProgramDescription& description, const Extensions& extensions) = 0; @@ -58,9 +59,16 @@ struct SkiaColorFilter { return mType; } + SkColorFilter *getSkColorFilter() { + return mSkFilter; + } + protected: Type mType; bool mBlend; + +private: + SkColorFilter *mSkFilter; }; // struct SkiaColorFilter /////////////////////////////////////////////////////////////////////////////// @@ -71,7 +79,7 @@ protected: * A color filter that multiplies the source color with a matrix and adds a vector. */ struct SkiaColorMatrixFilter: public SkiaColorFilter { - SkiaColorMatrixFilter(float* matrix, float* vector); + SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector); ~SkiaColorMatrixFilter(); void describe(ProgramDescription& description, const Extensions& extensions); @@ -87,7 +95,7 @@ private: * another fixed value. Ignores the alpha channel of both arguments. */ struct SkiaLightingFilter: public SkiaColorFilter { - SkiaLightingFilter(int multiply, int add); + SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add); void describe(ProgramDescription& description, const Extensions& extensions); void setupProgram(Program* program); @@ -102,7 +110,7 @@ private: * and PorterDuff blending mode. */ struct SkiaBlendFilter: public SkiaColorFilter { - SkiaBlendFilter(int color, SkXfermode::Mode mode); + SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode); void describe(ProgramDescription& description, const Extensions& extensions); void setupProgram(Program* program); -- cgit v1.1