Optimizing ColorFilter in display lists
Change-Id: Ie4d5e5b0bc45e0ce47bba144049303c270762e54
This commit is contained in:
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user