Optimizing ColorFilter in display lists

Change-Id: Ie4d5e5b0bc45e0ce47bba144049303c270762e54
This commit is contained in:
Chet Haase
2010-10-22 16:17:12 -07:00
parent 78098341f8
commit ad93c2bb63
11 changed files with 109 additions and 37 deletions

View File

@@ -24,6 +24,7 @@
#include "SkPorterDuff.h"
#include <SkiaColorFilter.h>
#include <Caches.h>
namespace android {
@@ -32,28 +33,37 @@ using namespace uirenderer;
class SkColorFilterGlue {
public:
static void finalizer(JNIEnv* env, jobject clazz, SkColorFilter* obj, SkiaColorFilter* f) {
delete f;
obj->safeUnref();
// f == NULL when not !USE_OPENGL_RENDERER, so no need to delete outside the ifdef
#ifdef USE_OPENGL_RENDERER
if (android::uirenderer::Caches::hasInstance()) {
android::uirenderer::Caches::getInstance().resourceCache.destructor(f);
} else {
delete f;
}
#endif
}
static SkiaColorFilter* glCreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor,
SkPorterDuff::Mode mode) {
static SkiaColorFilter* glCreatePorterDuffFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
jint srcColor, SkPorterDuff::Mode mode) {
#ifdef USE_OPENGL_RENDERER
return new SkiaBlendFilter(srcColor, SkPorterDuff::ToXfermodeMode(mode));
return new SkiaBlendFilter(skFilter, srcColor, SkPorterDuff::ToXfermodeMode(mode));
#else
return NULL;
#endif
}
static SkiaColorFilter* glCreateLightingFilter(JNIEnv* env, jobject, jint mul, jint add) {
static SkiaColorFilter* glCreateLightingFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
jint mul, jint add) {
#ifdef USE_OPENGL_RENDERER
return new SkiaLightingFilter(mul, add);
return new SkiaLightingFilter(skFilter, mul, add);
#else
return NULL;
#endif
}
static SkiaColorFilter* glCreateColorMatrixFilter(JNIEnv* env, jobject, jfloatArray jarray) {
static SkiaColorFilter* glCreateColorMatrixFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
jfloatArray jarray) {
#ifdef USE_OPENGL_RENDERER
AutoJavaFloatArray autoArray(env, jarray, 20);
const float* src = autoArray.ptr();
@@ -70,7 +80,7 @@ public:
colorVector[2] = src[14];
colorVector[3] = src[19];
return new SkiaColorMatrixFilter(colorMatrix, colorVector);
return new SkiaColorMatrixFilter(skFilter, colorMatrix, colorVector);
#else
return NULL;
#endif
@@ -107,17 +117,17 @@ static JNINativeMethod colorfilter_methods[] = {
static JNINativeMethod porterduff_methods[] = {
{ "native_CreatePorterDuffFilter", "(II)I", (void*) SkColorFilterGlue::CreatePorterDuffFilter },
{ "nCreatePorterDuffFilter", "(II)I", (void*) SkColorFilterGlue::glCreatePorterDuffFilter }
{ "nCreatePorterDuffFilter", "(III)I", (void*) SkColorFilterGlue::glCreatePorterDuffFilter }
};
static JNINativeMethod lighting_methods[] = {
{ "native_CreateLightingFilter", "(II)I", (void*) SkColorFilterGlue::CreateLightingFilter },
{ "nCreateLightingFilter", "(II)I", (void*) SkColorFilterGlue::glCreateLightingFilter },
{ "nCreateLightingFilter", "(III)I", (void*) SkColorFilterGlue::glCreateLightingFilter },
};
static JNINativeMethod colormatrix_methods[] = {
{ "nativeColorMatrixFilter", "([F)I", (void*) SkColorFilterGlue::CreateColorMatrixFilter },
{ "nColorMatrixFilter", "([F)I", (void*) SkColorFilterGlue::glCreateColorMatrixFilter }
{ "nColorMatrixFilter", "(I[F)I", (void*) SkColorFilterGlue::glCreateColorMatrixFilter }
};
#define REG(env, name, array) \

View File

@@ -58,6 +58,8 @@ static void Shader_destructor(JNIEnv* env, jobject o, SkShader* shader, SkiaShad
#ifdef USE_OPENGL_RENDERER
if (android::uirenderer::Caches::hasInstance()) {
android::uirenderer::Caches::getInstance().resourceCache.destructor(skiaShader);
} else {
delete skiaShader;
}
#endif
}

View File

@@ -27,7 +27,7 @@ public class ColorMatrixColorFilter extends ColorFilter {
public ColorMatrixColorFilter(ColorMatrix matrix) {
final float[] colorMatrix = matrix.getArray();
native_instance = nativeColorMatrixFilter(colorMatrix);
nativeColorFilter = nColorMatrixFilter(colorMatrix);
nativeColorFilter = nColorMatrixFilter(native_instance, colorMatrix);
}
/**
@@ -42,9 +42,9 @@ public class ColorMatrixColorFilter extends ColorFilter {
throw new ArrayIndexOutOfBoundsException();
}
native_instance = nativeColorMatrixFilter(array);
nativeColorFilter = nColorMatrixFilter(array);
nativeColorFilter = nColorMatrixFilter(native_instance, array);
}
private static native int nativeColorMatrixFilter(float[] array);
private static native int nColorMatrixFilter(float[] array);
private static native int nColorMatrixFilter(int nativeFilter, float[] array);
}

View File

@@ -30,9 +30,9 @@ public class LightingColorFilter extends ColorFilter {
*/
public LightingColorFilter(int mul, int add) {
native_instance = native_CreateLightingFilter(mul, add);
nativeColorFilter = nCreateLightingFilter(mul, add);
nativeColorFilter = nCreateLightingFilter(native_instance, mul, add);
}
private static native int native_CreateLightingFilter(int mul, int add);
private static native int nCreateLightingFilter(int mul, int add);
private static native int nCreateLightingFilter(int nativeFilter, int mul, int add);
}

View File

@@ -26,9 +26,10 @@ public class PorterDuffColorFilter extends ColorFilter {
*/
public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode) {
native_instance = native_CreatePorterDuffFilter(srcColor, mode.nativeInt);
nativeColorFilter = nCreatePorterDuffFilter(srcColor, mode.nativeInt);
nativeColorFilter = nCreatePorterDuffFilter(native_instance, srcColor, mode.nativeInt);
}
private static native int native_CreatePorterDuffFilter(int srcColor, int porterDuffMode);
private static native int nCreatePorterDuffFilter(int srcColor, int porterDuffMode);
private static native int nCreatePorterDuffFilter(int nativeFilter, int srcColor,
int porterDuffMode);
}

View File

@@ -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

View File

@@ -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<SkBitmap*> mBitmapResources;
Vector<SkiaShader*> mShaderResources;
Vector<SkiaColorFilter*> mFilterResources;
Vector<SkPaint*> mPaints;
Vector<SkMatrix*> mMatrices;
@@ -276,6 +281,10 @@ public:
return mMatrices;
}
const Vector<SkiaColorFilter*>& 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<SkBitmap*> mBitmapResources;
Vector<SkiaShader*> mShaderResources;
Vector<SkiaColorFilter*> mFilterResources;
Vector<SkPaint*> mPaints;
DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap;

View File

@@ -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);

View File

@@ -18,6 +18,7 @@
#define ANDROID_UI_RESOURCE_CACHE_H
#include <SkBitmap.h>
#include <SkiaColorFilter.h>
#include <SkiaShader.h>
#include <utils/KeyedVector.h>
@@ -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);

View File

@@ -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;

View File

@@ -18,6 +18,7 @@
#define ANDROID_UI_SKIA_COLOR_FILTER_H
#include <GLES2/gl2.h>
#include <SkColorFilter.h>
#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);