Removing SkiaColorFilter and inspecting the native object directly.

bug: 10650594
Change-Id: I4fcf66d008765afa0e35d011f58bc792183cb74f
This commit is contained in:
Derek Sollenberger
2013-12-10 12:28:58 -05:00
parent 8852ab4357
commit 76d3a1b8d0
27 changed files with 265 additions and 793 deletions

View File

@@ -46,7 +46,6 @@ class GLES20Canvas extends HardwareCanvas {
private static final int MODIFIER_NONE = 0;
private static final int MODIFIER_SHADOW = 1;
private static final int MODIFIER_SHADER = 2;
private static final int MODIFIER_COLOR_FILTER = 4;
private final boolean mOpaque;
private long mRenderer;
@@ -627,15 +626,8 @@ class GLES20Canvas extends HardwareCanvas {
return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
}
int count;
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
try {
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
count = nSaveLayer(mRenderer, nativePaint, saveFlags);
} finally {
if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
}
return count;
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
return nSaveLayer(mRenderer, nativePaint, saveFlags);
}
private static native int nSaveLayer(long renderer, long paint, int saveFlags);
@@ -644,15 +636,8 @@ class GLES20Canvas extends HardwareCanvas {
public int saveLayer(float left, float top, float right, float bottom, Paint paint,
int saveFlags) {
if (left < right && top < bottom) {
int count;
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
try {
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
} finally {
if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
}
return count;
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
}
return save(saveFlags);
}
@@ -734,7 +719,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
Paint paint) {
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom,
startAngle, sweepAngle, useCenter, paint.mNativePaint);
@@ -757,14 +742,9 @@ class GLES20Canvas extends HardwareCanvas {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
// Shaders are ignored when drawing patches
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
try {
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
} finally {
if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
}
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
@Override
@@ -772,14 +752,9 @@ class GLES20Canvas extends HardwareCanvas {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
// Shaders are ignored when drawing patches
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
try {
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
} finally {
if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
}
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
private static native void nDrawPatch(long renderer, long bitmap, byte[] buffer, long chunk,
@@ -900,14 +875,9 @@ class GLES20Canvas extends HardwareCanvas {
}
// Shaders are ignored when drawing bitmaps
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
try {
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
nDrawBitmap(mRenderer, colors, offset, stride, x, y,
width, height, hasAlpha, nativePaint);
} finally {
if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
}
final long nativePaint = paint == null ? 0 : paint.mNativePaint;
nDrawBitmap(mRenderer, colors, offset, stride, x, y,
width, height, hasAlpha, nativePaint);
}
private static native void nDrawBitmap(long renderer, int[] colors, int offset, int stride,
@@ -955,7 +925,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawCircle(float cx, float cy, float radius, Paint paint) {
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
} finally {
@@ -995,7 +965,7 @@ class GLES20Canvas extends HardwareCanvas {
if ((offset | count) < 0 || offset + count > pts.length) {
throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
}
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
} finally {
@@ -1013,7 +983,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawOval(RectF oval, Paint paint) {
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint);
} finally {
@@ -1033,7 +1003,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawPath(Path path, Paint paint) {
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
if (path.isSimplePath) {
if (path.rects != null) {
@@ -1051,7 +1021,7 @@ class GLES20Canvas extends HardwareCanvas {
private static native void nDrawRects(long renderer, long region, long paint);
void drawRects(float[] rects, int count, Paint paint) {
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
nDrawRects(mRenderer, rects, count, paint.mNativePaint);
} finally {
@@ -1118,7 +1088,7 @@ class GLES20Canvas extends HardwareCanvas {
public void drawPoints(float[] pts, int offset, int count, Paint paint) {
if (count < 2) return;
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
} finally {
@@ -1168,7 +1138,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawRect(float left, float top, float right, float bottom, Paint paint) {
if (left == right || top == bottom) return;
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
} finally {
@@ -1196,7 +1166,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
int modifiers = setupModifiers(paint, MODIFIER_SHADER);
try {
nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
rx, ry, paint.mNativePaint);
@@ -1376,12 +1346,6 @@ class GLES20Canvas extends HardwareCanvas {
private int setupModifiers(Bitmap b, Paint paint) {
if (b.getConfig() != Bitmap.Config.ALPHA_8) {
final ColorFilter filter = paint.getColorFilter();
if (filter != null) {
nSetupColorFilter(mRenderer, filter.nativeColorFilter);
return MODIFIER_COLOR_FILTER;
}
return MODIFIER_NONE;
} else {
return setupModifiers(paint);
@@ -1403,12 +1367,6 @@ class GLES20Canvas extends HardwareCanvas {
modifiers |= MODIFIER_SHADER;
}
final ColorFilter filter = paint.getColorFilter();
if (filter != null) {
nSetupColorFilter(mRenderer, filter.nativeColorFilter);
modifiers |= MODIFIER_COLOR_FILTER;
}
return modifiers;
}
@@ -1427,26 +1385,10 @@ class GLES20Canvas extends HardwareCanvas {
modifiers |= MODIFIER_SHADER;
}
final ColorFilter filter = paint.getColorFilter();
if (filter != null && (flags & MODIFIER_COLOR_FILTER) != 0) {
nSetupColorFilter(mRenderer, filter.nativeColorFilter);
modifiers |= MODIFIER_COLOR_FILTER;
}
return modifiers;
}
private int setupColorFilter(Paint paint) {
final ColorFilter filter = paint.getColorFilter();
if (filter != null) {
nSetupColorFilter(mRenderer, filter.nativeColorFilter);
return MODIFIER_COLOR_FILTER;
}
return MODIFIER_NONE;
}
private static native void nSetupShader(long renderer, long shader);
private static native void nSetupColorFilter(long renderer, long colorFilter);
private static native void nSetupShadow(long renderer, float radius,
float dx, float dy, int color);

View File

@@ -48,7 +48,7 @@ abstract class GLES20Layer extends HardwareLayer {
if (paint != null) {
GLES20Canvas.nSetLayerPaint(mLayer, paint.mNativePaint);
GLES20Canvas.nSetLayerColorFilter(mLayer, paint.getColorFilter() != null ?
paint.getColorFilter().nativeColorFilter : 0);
paint.getColorFilter().native_instance : 0);
}
}

View File

@@ -23,7 +23,6 @@
#include "SkColorMatrixFilter.h"
#include "SkPorterDuff.h"
#include <SkiaColorFilter.h>
#include <Caches.h>
namespace android {
@@ -32,64 +31,9 @@ using namespace uirenderer;
class SkColorFilterGlue {
public:
static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong fHandle) {
SkColorFilter* obj = reinterpret_cast<SkColorFilter *>(objHandle);
SkiaColorFilter* f = reinterpret_cast<SkiaColorFilter *>(fHandle);
if (obj) SkSafeUnref(obj);
// f == NULL when not !USE_OPENGL_RENDERER, so no need to delete outside the ifdef
#ifdef USE_OPENGL_RENDERER
if (f && android::uirenderer::Caches::hasInstance()) {
android::uirenderer::Caches::getInstance().resourceCache.destructor(f);
} else {
delete f;
}
#endif
}
static jlong glCreatePorterDuffFilter(JNIEnv* env, jobject, jlong skFilterHandle,
jint srcColor, jint modeHandle) {
SkColorFilter *skFilter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
SkPorterDuff::Mode mode = static_cast<SkPorterDuff::Mode>(modeHandle);
#ifdef USE_OPENGL_RENDERER
return reinterpret_cast<jlong>(new SkiaBlendFilter(skFilter, srcColor, SkPorterDuff::ToXfermodeMode(mode)));
#else
return NULL;
#endif
}
static jlong glCreateLightingFilter(JNIEnv* env, jobject, jlong skFilterHandle,
jint mul, jint add) {
SkColorFilter *skFilter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
#ifdef USE_OPENGL_RENDERER
return reinterpret_cast<jlong>(new SkiaLightingFilter(skFilter, mul, add));
#else
return NULL;
#endif
}
static jlong glCreateColorMatrixFilter(JNIEnv* env, jobject, jlong skFilterHandle,
jfloatArray jarray) {
SkColorFilter *skFilter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
#ifdef USE_OPENGL_RENDERER
AutoJavaFloatArray autoArray(env, jarray, 20);
const float* src = autoArray.ptr();
float* colorMatrix = new float[16];
memcpy(colorMatrix, src, 4 * sizeof(float));
memcpy(&colorMatrix[4], &src[5], 4 * sizeof(float));
memcpy(&colorMatrix[8], &src[10], 4 * sizeof(float));
memcpy(&colorMatrix[12], &src[15], 4 * sizeof(float));
float* colorVector = new float[4];
colorVector[0] = src[4];
colorVector[1] = src[9];
colorVector[2] = src[14];
colorVector[3] = src[19];
return reinterpret_cast<jlong>(new SkiaColorMatrixFilter(skFilter, colorMatrix, colorVector));
#else
return NULL;
#endif
static void finalizer(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
if (filter) SkSafeUnref(filter);
}
static jlong CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor,
@@ -119,22 +63,19 @@ public:
};
static JNINativeMethod colorfilter_methods[] = {
{"destroyFilter", "(JJ)V", (void*) SkColorFilterGlue::finalizer}
{"destroyFilter", "(J)V", (void*) SkColorFilterGlue::finalizer}
};
static JNINativeMethod porterduff_methods[] = {
{ "native_CreatePorterDuffFilter", "(II)J", (void*) SkColorFilterGlue::CreatePorterDuffFilter },
{ "nCreatePorterDuffFilter", "(JII)J", (void*) SkColorFilterGlue::glCreatePorterDuffFilter }
};
static JNINativeMethod lighting_methods[] = {
{ "native_CreateLightingFilter", "(II)J", (void*) SkColorFilterGlue::CreateLightingFilter },
{ "nCreateLightingFilter", "(JII)J", (void*) SkColorFilterGlue::glCreateLightingFilter },
};
static JNINativeMethod colormatrix_methods[] = {
{ "nativeColorMatrixFilter", "([F)J", (void*) SkColorFilterGlue::CreateColorMatrixFilter },
{ "nColorMatrixFilter", "(J[F)J", (void*) SkColorFilterGlue::glCreateColorMatrixFilter }
};
#define REG(env, name, array) \

View File

@@ -47,7 +47,6 @@
#include <LayerRenderer.h>
#include <OpenGLRenderer.h>
#include <SkiaShader.h>
#include <SkiaColorFilter.h>
#include <Stencil.h>
#include <Rect.h>
@@ -81,7 +80,6 @@ using namespace uirenderer;
#define MODIFIER_SHADOW 1
#define MODIFIER_SHADER 2
#define MODIFIER_COLOR_FILTER 4
// ----------------------------------------------------------------------------
@@ -638,7 +636,6 @@ static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
if (modifiers & MODIFIER_SHADOW) renderer->resetShadow();
if (modifiers & MODIFIER_SHADER) renderer->resetShader();
if (modifiers & MODIFIER_COLOR_FILTER) renderer->resetColorFilter();
}
static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject clazz,
@@ -648,12 +645,6 @@ static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject clazz,
renderer->setupShader(shader);
}
static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject clazz,
jlong rendererPtr, jlong colorFilterPtr) {
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
SkiaColorFilter* colorFilter = reinterpret_cast<SkiaColorFilter*>(colorFilterPtr);
renderer->setupColorFilter(colorFilter);
}
static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject clazz,
jlong rendererPtr, jfloat radius, jfloat dx, jfloat dy, jint color) {
@@ -987,7 +978,7 @@ static void android_view_GLES20Canvas_setLayerColorFilter(JNIEnv* env, jobject c
jlong layerPtr, jlong colorFilterPtr) {
Layer* layer = reinterpret_cast<Layer*>(layerPtr);
if (layer) {
SkiaColorFilter* colorFilter = reinterpret_cast<SkiaColorFilter*>(colorFilterPtr);
SkColorFilter* colorFilter = reinterpret_cast<SkColorFilter*>(colorFilterPtr);
layer->setColorFilter(colorFilter);
}
}
@@ -1222,7 +1213,6 @@ static JNINativeMethod gMethods[] = {
{ "nResetModifiers", "(JI)V", (void*) android_view_GLES20Canvas_resetModifiers },
{ "nSetupShader", "(JJ)V", (void*) android_view_GLES20Canvas_setupShader },
{ "nSetupColorFilter", "(JJ)V", (void*) android_view_GLES20Canvas_setupColorFilter },
{ "nSetupShadow", "(JFFFI)V", (void*) android_view_GLES20Canvas_setupShadow },
{ "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter },

View File

@@ -27,24 +27,21 @@ package android.graphics;
* never be used directly.
*/
public class ColorFilter {
// Holds the pointer to the native SkColorFilter instance
long native_instance;
/**
* Holds the pointer to the native SkiaColorFilter instance, from libhwui.
* Holds the pointer to the native SkColorFilter instance.
*
* @hide
*/
public long nativeColorFilter;
public long native_instance;
@Override
protected void finalize() throws Throwable {
try {
super.finalize();
} finally {
destroyFilter(native_instance, nativeColorFilter);
destroyFilter(native_instance);
}
}
static native void destroyFilter(long native_instance, long nativeColorFilter);
static native void destroyFilter(long native_instance);
}

View File

@@ -114,11 +114,9 @@ public class ColorMatrixColorFilter extends ColorFilter {
private void update() {
final float[] colorMatrix = mMatrix.getArray();
destroyFilter(native_instance, nativeColorFilter);
destroyFilter(native_instance);
native_instance = nativeColorMatrixFilter(colorMatrix);
nativeColorFilter = nColorMatrixFilter(native_instance, colorMatrix);
}
private static native long nativeColorMatrixFilter(float[] array);
private static native long nColorMatrixFilter(long nativeFilter, float[] array);
}

View File

@@ -99,11 +99,9 @@ public class LightingColorFilter extends ColorFilter {
}
private void update() {
destroyFilter(native_instance, nativeColorFilter);
destroyFilter(native_instance);
native_instance = native_CreateLightingFilter(mMul, mAdd);
nativeColorFilter = nCreateLightingFilter(native_instance, mMul, mAdd);
}
private static native long native_CreateLightingFilter(int mul, int add);
private static native long nCreateLightingFilter(long nativeFilter, int mul, int add);
}

View File

@@ -91,12 +91,9 @@ public class PorterDuffColorFilter extends ColorFilter {
}
private void update() {
destroyFilter(native_instance, nativeColorFilter);
destroyFilter(native_instance);
native_instance = native_CreatePorterDuffFilter(mColor, mMode.nativeInt);
nativeColorFilter = nCreatePorterDuffFilter(native_instance, mColor, mMode.nativeInt);
}
private static native long native_CreatePorterDuffFilter(int srcColor, int porterDuffMode);
private static native long nCreatePorterDuffFilter(long nativeFilter, int srcColor,
int porterDuffMode);
}

View File

@@ -39,7 +39,6 @@ ifeq ($(USE_OPENGL_RENDERER),true)
RenderBufferCache.cpp \
ResourceCache.cpp \
ShadowTessellator.cpp \
SkiaColorFilter.cpp \
SkiaShader.cpp \
Snapshot.cpp \
SpotShadow.cpp \

View File

@@ -224,6 +224,11 @@ public:
if (op->getPaintAlpha() != mOps[0].op->getPaintAlpha()) return false;
if (op->mPaint && mOps[0].op->mPaint &&
op->mPaint->getColorFilter() != mOps[0].op->mPaint->getColorFilter()) {
return false;
}
/* Draw Modifiers compatibility check
*
* Shadows are ignored, as only text uses them, and in that case they are drawn
@@ -239,7 +244,6 @@ public:
const DrawModifiers& lhsMod = lhs->mDrawModifiers;
const DrawModifiers& rhsMod = rhs->mDrawModifiers;
if (lhsMod.mShader != rhsMod.mShader) return false;
if (lhsMod.mColorFilter != rhsMod.mColorFilter) return false;
// Draw filter testing expects bit fields to be clear if filter not set.
if (lhsMod.mHasDrawFilter != rhsMod.mHasDrawFilter) return false;

View File

@@ -96,10 +96,6 @@ void DisplayList::clearResources() {
caches.resourceCache.destructorLocked(bitmap);
}
for (size_t i = 0; i < mFilterResources.size(); i++) {
caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
}
for (size_t i = 0; i < mPatchResources.size(); i++) {
caches.resourceCache.decrementRefcountLocked(mPatchResources.itemAt(i));
}
@@ -137,7 +133,6 @@ void DisplayList::clearResources() {
mBitmapResources.clear();
mOwnedBitmapResources.clear();
mFilterResources.clear();
mPatchResources.clear();
mShaders.clear();
mSourcePaths.clear();
@@ -188,13 +183,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
caches.resourceCache.incrementRefcountLocked(resource);
}
const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
for (size_t i = 0; i < filterResources.size(); i++) {
SkiaColorFilter* resource = filterResources.itemAt(i);
mFilterResources.add(resource);
caches.resourceCache.incrementRefcountLocked(resource);
}
const Vector<const Res_png_9patch*>& patchResources = recorder.getPatchResources();
for (size_t i = 0; i < patchResources.size(); i++) {
const Res_png_9patch* resource = patchResources.itemAt(i);

View File

@@ -61,7 +61,6 @@ class DisplayListRenderer;
class OpenGLRenderer;
class Rect;
class Layer;
class SkiaColorFilter;
class SkiaShader;
class ClipRectOp;
@@ -582,7 +581,6 @@ private:
Vector<const SkBitmap*> mBitmapResources;
Vector<const SkBitmap*> mOwnedBitmapResources;
Vector<SkiaColorFilter*> mFilterResources;
Vector<const Res_png_9patch*> mPatchResources;
Vector<const SkPaint*> mPaints;

View File

@@ -620,38 +620,6 @@ private:
SkiaShader* mShader;
};
class ResetColorFilterOp : public StateOp {
public:
virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
renderer.resetColorFilter();
}
virtual void output(int level, uint32_t logFlags) const {
OP_LOGS("ResetColorFilter");
}
virtual const char* name() { return "ResetColorFilter"; }
};
class SetupColorFilterOp : public StateOp {
public:
SetupColorFilterOp(SkiaColorFilter* colorFilter)
: mColorFilter(colorFilter) {}
virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
renderer.setupColorFilter(mColorFilter);
}
virtual void output(int level, uint32_t logFlags) const {
OP_LOG("SetupColorFilter, filter %p", mColorFilter);
}
virtual const char* name() { return "SetupColorFilter"; }
private:
SkiaColorFilter* mColorFilter;
};
class ResetShadowOp : public StateOp {
public:
virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {

View File

@@ -53,10 +53,6 @@ void DisplayListRenderer::reset() {
mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i));
}
for (size_t i = 0; i < mFilterResources.size(); i++) {
mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
}
for (size_t i = 0; i < mPatchResources.size(); i++) {
mCaches.resourceCache.decrementRefcountLocked(mPatchResources.itemAt(i));
}
@@ -77,7 +73,6 @@ void DisplayListRenderer::reset() {
mBitmapResources.clear();
mOwnedBitmapResources.clear();
mFilterResources.clear();
mPatchResources.clear();
mSourcePaths.clear();
@@ -457,15 +452,6 @@ void DisplayListRenderer::setupShader(SkiaShader* shader) {
addStateOp(new (alloc()) SetupShaderOp(shader));
}
void DisplayListRenderer::resetColorFilter() {
addStateOp(new (alloc()) ResetColorFilterOp());
}
void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
filter = refColorFilter(filter);
addStateOp(new (alloc()) SetupColorFilterOp(filter));
}
void DisplayListRenderer::resetShadow() {
addStateOp(new (alloc()) ResetShadowOp());
OpenGLRenderer::resetShadow();

View File

@@ -102,9 +102,6 @@ public:
virtual void resetShader();
virtual void setupShader(SkiaShader* shader);
virtual void resetColorFilter();
virtual void setupColorFilter(SkiaColorFilter* filter);
virtual void resetShadow();
virtual void setupShadow(float radius, float dx, float dy, int color);
@@ -182,10 +179,6 @@ public:
return mOwnedBitmapResources;
}
const Vector<SkiaColorFilter*>& getFilterResources() const {
return mFilterResources;
}
const Vector<const Res_png_9patch*>& getPatchResources() const {
return mPatchResources;
}
@@ -349,12 +342,6 @@ private:
return shaderCopy;
}
inline SkiaColorFilter* refColorFilter(SkiaColorFilter* colorFilter) {
mFilterResources.add(colorFilter);
mCaches.resourceCache.incrementRefcount(colorFilter);
return colorFilter;
}
inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
mPatchResources.add(patch);
mCaches.resourceCache.incrementRefcount(patch);
@@ -364,7 +351,6 @@ private:
// TODO: move these to DisplayListData
Vector<const SkBitmap*> mBitmapResources;
Vector<const SkBitmap*> mOwnedBitmapResources;
Vector<SkiaColorFilter*> mFilterResources;
Vector<const Res_png_9patch*> mPatchResources;
Vector<const SkPaint*> mPaints;

View File

@@ -72,9 +72,9 @@ status_t TextSetupFunctor::operator ()(int what, void* data) {
break;
}
}
renderer->setupDrawColorFilter();
renderer->setupDrawColorFilter(paint->getColorFilter());
renderer->setupDrawShader();
renderer->setupDrawBlending(true, mode);
renderer->setupDrawBlending(paint);
renderer->setupDrawProgram();
renderer->setupDrawModelView(kModelViewMode_Translate, false,
0.0f, 0.0f, 0.0f, 0.0f, pureTranslate);
@@ -84,7 +84,7 @@ status_t TextSetupFunctor::operator ()(int what, void* data) {
// needed
renderer->setupDrawTexture(0);
renderer->setupDrawPureColorUniforms();
renderer->setupDrawColorFilterUniforms();
renderer->setupDrawColorFilterUniforms(paint->getColorFilter());
renderer->setupDrawShaderUniforms(pureTranslate);
renderer->setupDrawTextGammaUniforms();

View File

@@ -51,7 +51,7 @@ Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight):
}
Layer::~Layer() {
if (colorFilter) caches.resourceCache.decrementRefcount(colorFilter);
SkSafeUnref(colorFilter);
removeFbo();
deleteTexture();
@@ -135,14 +135,8 @@ void Layer::setPaint(SkPaint* paint) {
OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
}
void Layer::setColorFilter(SkiaColorFilter* filter) {
if (colorFilter) {
caches.resourceCache.decrementRefcount(colorFilter);
}
colorFilter = filter;
if (colorFilter) {
caches.resourceCache.incrementRefcount(colorFilter);
}
void Layer::setColorFilter(SkColorFilter* filter) {
SkRefCnt_SafeAssign(colorFilter, filter);
}
void Layer::bindTexture() const {

View File

@@ -17,6 +17,7 @@
#ifndef ANDROID_HWUI_LAYER_H
#define ANDROID_HWUI_LAYER_H
#include <cutils/compiler.h>
#include <sys/types.h>
#include <GLES2/gl2.h>
@@ -26,9 +27,9 @@
#include <SkPaint.h>
#include <SkXfermode.h>
#include "Matrix.h"
#include "Rect.h"
#include "RenderBuffer.h"
#include "SkiaColorFilter.h"
#include "Texture.h"
#include "Vertex.h"
@@ -217,11 +218,11 @@ public:
this->textureLayer = textureLayer;
}
inline SkiaColorFilter* getColorFilter() const {
inline SkColorFilter* getColorFilter() const {
return colorFilter;
}
ANDROID_API void setColorFilter(SkiaColorFilter* filter);
ANDROID_API void setColorFilter(SkColorFilter* filter);
void bindStencilRenderBuffer() const;
@@ -339,7 +340,7 @@ private:
/**
* Color filter used to draw this layer. Optional.
*/
SkiaColorFilter* colorFilter;
SkColorFilter* colorFilter;
/**
* Opacity of the layer.

View File

@@ -893,7 +893,7 @@ bool OpenGLRenderer::createLayer(float left, float top, float right, float botto
layer->texCoords.set(0.0f, bounds.getHeight() / float(layer->getHeight()),
bounds.getWidth() / float(layer->getWidth()), 0.0f);
layer->setColorFilter(mDrawModifiers.mColorFilter);
layer->setColorFilter(getColorFilter(paint));
layer->setBlend(true);
layer->setDirty(false);
@@ -1011,8 +1011,13 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto
}
if (!fboLayer && layer->getAlpha() < 255) {
drawColorRect(rect.left, rect.top, rect.right, rect.bottom,
layer->getAlpha() << 24, SkXfermode::kDstIn_Mode, true);
// TODO: this seems to point to the fact that the layer should store the paint
SkPaint layerPaint;
layerPaint.setAlpha(layer->getAlpha());
layerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
layerPaint.setColorFilter(layer->getColorFilter());
drawColorRect(rect.left, rect.top, rect.right, rect.bottom, &layerPaint, true);
// Required below, composeLayerRect() will divide by 255
layer->setAlpha(255);
}
@@ -1025,13 +1030,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto
// drawing only the dirty region
if (fboLayer) {
dirtyLayer(rect.left, rect.top, rect.right, rect.bottom, *restored.transform);
if (layer->getColorFilter()) {
setupColorFilter(layer->getColorFilter());
}
composeLayerRegion(layer, rect);
if (layer->getColorFilter()) {
resetColorFilter();
}
} else if (!rect.isEmpty()) {
dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
@@ -1063,11 +1062,11 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
}
setupDrawTextureTransform();
setupDrawColor(alpha, alpha, alpha, alpha);
setupDrawColorFilter();
setupDrawBlending(layer->isBlend() || alpha < 1.0f, layer->getMode());
setupDrawColorFilter(layer->getColorFilter());
setupDrawBlending(layer);
setupDrawProgram();
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(layer->getColorFilter());
if (layer->getRenderTarget() == GL_TEXTURE_2D) {
setupDrawTexture(layer->getTexture());
} else {
@@ -1117,10 +1116,14 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap)
layer->setFilter(GL_LINEAR, true);
}
float alpha = getLayerAlpha(layer);
bool blend = layer->isBlend() || alpha < 1.0f;
SkPaint layerPaint;
layerPaint.setAlpha(getLayerAlpha(layer) * 255);
layerPaint.setXfermodeMode(layer->getMode());
layerPaint.setColorFilter(layer->getColorFilter());
bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f;
drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(),
layer->getTexture(), alpha, layer->getMode(), blend,
layer->getTexture(), &layerPaint, blend,
&mMeshVertices[0].x, &mMeshVertices[0].u,
GL_TRIANGLE_STRIP, gMeshCount, swap, swap || simpleTransform);
@@ -1185,12 +1188,12 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
setupDrawWithTexture();
setupDrawColor(alpha, alpha, alpha, alpha);
setupDrawColorFilter();
setupDrawBlending(layer->isBlend() || alpha < 1.0f, layer->getMode(), false);
setupDrawColorFilter(layer->getColorFilter());
setupDrawBlending(layer);
setupDrawProgram();
setupDrawDirtyRegionsDisabled();
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(layer->getColorFilter());
setupDrawTexture(layer->getTexture());
if (currentTransform()->isPureTranslate()) {
const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
@@ -1262,15 +1265,15 @@ void OpenGLRenderer::drawRegionRectsDebug(const Region& region) {
top = rects[i].top;
}
SkPaint paint;
paint.setColor(colors[offset + (i & 0x1)]);
Rect r(rects[i].left, rects[i].top, rects[i].right, rects[i].bottom);
drawColorRect(r.left, r.top, r.right, r.bottom, colors[offset + (i & 0x1)],
SkXfermode::kSrcOver_Mode);
drawColorRect(r.left, r.top, r.right, r.bottom, paint);
}
}
#endif
void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
SkXfermode::Mode mode, bool dirty) {
void OpenGLRenderer::drawRegionRects(const SkRegion& region, const SkPaint& paint, bool dirty) {
Vector<float> rects;
SkRegion::Iterator it(region);
@@ -1283,7 +1286,7 @@ void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
it.next();
}
drawColorRects(rects.array(), rects.size(), color, mode, true, dirty, false);
drawColorRects(rects.array(), rects.size(), &paint, true, dirty, false);
}
void OpenGLRenderer::dirtyLayer(const float left, const float top,
@@ -1360,9 +1363,12 @@ void OpenGLRenderer::clearLayerRegions() {
// the same thing again
mLayers.clear();
SkPaint clearPaint;
clearPaint.setXfermodeMode(SkXfermode::kClear_Mode);
setupDraw(false);
setupDrawColor(0.0f, 0.0f, 0.0f, 1.0f);
setupDrawBlending(true, SkXfermode::kClear_Mode);
setupDrawBlending(&clearPaint, true);
setupDrawProgram();
setupDrawPureColorUniforms();
setupDrawModelView(kModelViewMode_Translate, false,
@@ -1521,22 +1527,26 @@ void OpenGLRenderer::setStencilFromClip() {
mCaches.stencil.clear();
if (resetScissor) mCaches.disableScissor();
SkPaint paint;
paint.setColor(0xff000000);
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
// NOTE: We could use the region contour path to generate a smaller mesh
// Since we are using the stencil we could use the red book path
// drawing technique. It might increase bandwidth usage though.
// The last parameter is important: we are not drawing in the color buffer
// so we don't want to dirty the current layer, if any
drawRegionRects(*(currentSnapshot()->clipRegion),
0xff000000, SkXfermode::kSrc_Mode, false);
drawRegionRects(*(currentSnapshot()->clipRegion), paint, false);
mCaches.stencil.enableTest();
// Draw the region used to generate the stencil if the appropriate debug
// mode is enabled
if (mCaches.debugStencilClip == Caches::kStencilShowRegion) {
drawRegionRects(*(currentSnapshot()->clipRegion),
0x7f0000ff, SkXfermode::kSrcOver_Mode);
paint.setColor(0x7f0000ff);
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
drawRegionRects(*(currentSnapshot()->clipRegion), paint);
}
} else {
mCaches.stencil.disable();
@@ -1577,7 +1587,10 @@ bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right,
void OpenGLRenderer::debugClip() {
#if DEBUG_CLIP_REGIONS
if (!isRecording() && !currentSnapshot()->clipRegion->isEmpty()) {
drawRegionRects(*(currentSnapshot()->clipRegion), 0x7f00ff00, SkXfermode::kSrcOver_Mode);
SkPaint paint;
paint.setColor(0x7f00ff00);
drawRegionRects(*(currentSnapshot()->clipRegion, paint);
}
#endif
}
@@ -1676,9 +1689,17 @@ void OpenGLRenderer::setupDrawShader() {
}
}
void OpenGLRenderer::setupDrawColorFilter() {
if (mDrawModifiers.mColorFilter) {
mDrawModifiers.mColorFilter->describe(mDescription, mExtensions);
void OpenGLRenderer::setupDrawColorFilter(const SkColorFilter* filter) {
if (filter == NULL) {
return;
}
SkXfermode::Mode mode;
if (filter->asColorMode(NULL, &mode)) {
mDescription.colorOp = ProgramDescription::kColorBlend;
mDescription.colorMode = mode;
} else if (filter->asColorMatrix(NULL)) {
mDescription.colorOp = ProgramDescription::kColorMatrix;
}
}
@@ -1690,22 +1711,26 @@ void OpenGLRenderer::accountForClear(SkXfermode::Mode mode) {
}
}
void OpenGLRenderer::setupDrawBlending(SkXfermode::Mode mode, bool swapSrcDst) {
void OpenGLRenderer::setupDrawBlending(const Layer* layer, bool swapSrcDst) {
SkXfermode::Mode mode = layer->getMode();
// When the blending mode is kClear_Mode, we need to use a modulate color
// argb=1,0,0,0
accountForClear(mode);
bool blend = (mColorSet && mColorA < 1.0f) ||
(mDrawModifiers.mShader && mDrawModifiers.mShader->blend());
bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f ||
(mColorSet && mColorA < 1.0f) ||
(mDrawModifiers.mShader && mDrawModifiers.mShader->blend()) ||
layer->getColorFilter();
chooseBlending(blend, mode, mDescription, swapSrcDst);
}
void OpenGLRenderer::setupDrawBlending(bool blend, SkXfermode::Mode mode, bool swapSrcDst) {
void OpenGLRenderer::setupDrawBlending(const SkPaint* paint, bool blend, bool swapSrcDst) {
SkXfermode::Mode mode = getXfermodeDirect(paint);
// When the blending mode is kClear_Mode, we need to use a modulate color
// argb=1,0,0,0
accountForClear(mode);
blend |= (mColorSet && mColorA < 1.0f) ||
(mDrawModifiers.mShader && mDrawModifiers.mShader->blend()) ||
(mDrawModifiers.mColorFilter && mDrawModifiers.mColorFilter->blend());
(paint && paint->getColorFilter());
chooseBlending(blend, mode, mDescription, swapSrcDst);
}
@@ -1762,10 +1787,47 @@ void OpenGLRenderer::setupDrawShaderUniforms(bool ignoreTransform) {
}
}
void OpenGLRenderer::setupDrawColorFilterUniforms() {
if (mDrawModifiers.mColorFilter) {
mDrawModifiers.mColorFilter->setupProgram(mCaches.currentProgram);
void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) {
if (NULL == filter) {
return;
}
SkColor color;
SkXfermode::Mode mode;
if (filter->asColorMode(&color, &mode)) {
const int alpha = SkColorGetA(color);
const GLfloat a = alpha / 255.0f;
const GLfloat r = a * SkColorGetR(color) / 255.0f;
const GLfloat g = a * SkColorGetG(color) / 255.0f;
const GLfloat b = a * SkColorGetB(color) / 255.0f;
glUniform4f(mCaches.currentProgram->getUniform("colorBlend"), r, g, b, a);
return;
}
SkScalar srcColorMatrix[20];
if (filter->asColorMatrix(srcColorMatrix)) {
float colorMatrix[16];
memcpy(colorMatrix, srcColorMatrix, 4 * sizeof(float));
memcpy(&colorMatrix[4], &srcColorMatrix[5], 4 * sizeof(float));
memcpy(&colorMatrix[8], &srcColorMatrix[10], 4 * sizeof(float));
memcpy(&colorMatrix[12], &srcColorMatrix[15], 4 * sizeof(float));
// Skia uses the range [0..255] for the addition vector, but we need
// the [0..1] range to apply the vector in GLSL
float colorVector[4];
colorVector[0] = srcColorMatrix[4] / 255.0f;
colorVector[1] = srcColorMatrix[9] / 255.0f;
colorVector[2] = srcColorMatrix[14] / 255.0f;
colorVector[3] = srcColorMatrix[19] / 255.0f;
glUniformMatrix4fv(mCaches.currentProgram->getUniform("colorMatrix"), 1,
GL_FALSE, colorMatrix);
glUniform4fv(mCaches.currentProgram->getUniform("colorMatrixVector"), 1, colorVector);
return;
}
// it is an error if we ever get here
}
void OpenGLRenderer::setupDrawTextGammaUniforms() {
@@ -1900,10 +1962,6 @@ status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty,
}
void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint) {
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
int color = paint != NULL ? paint->getColor() : 0;
float x = left;
@@ -1925,7 +1983,7 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, co
// No need to check for a UV mapper on the texture object, only ARGB_8888
// bitmaps get packed in the atlas
drawAlpha8TextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
paint != NULL, color, alpha, mode, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
paint, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform);
}
@@ -1943,26 +2001,19 @@ status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry*
const AutoTexture autoCleanup(texture);
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
texture->setWrap(GL_CLAMP_TO_EDGE, true);
texture->setFilter(pureTranslate ? GL_NEAREST : FILTER(paint), true);
const float x = (int) floorf(bounds.left + 0.5f);
const float y = (int) floorf(bounds.top + 0.5f);
if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
int color = paint != NULL ? paint->getColor() : 0;
drawAlpha8TextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
texture->id, paint != NULL, color, alpha, mode,
&vertices[0].x, &vertices[0].u,
texture->id, paint, &vertices[0].x, &vertices[0].u,
GL_TRIANGLES, bitmapCount * 6, true,
kModelViewMode_Translate, false);
} else {
drawTextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
texture->id, alpha / 255.0f, mode, texture->blend,
&vertices[0].x, &vertices[0].u,
texture->id, paint, texture->blend, &vertices[0].x, &vertices[0].u,
GL_TRIANGLES, bitmapCount * 6, false, true, 0,
kModelViewMode_Translate, false);
}
@@ -2142,14 +2193,14 @@ status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, i
setupDraw();
setupDrawWithTextureAndColor();
setupDrawColor(a, a, a, a);
setupDrawColorFilter();
setupDrawBlending(true, mode, false);
setupDrawColorFilter(getColorFilter(paint));
setupDrawBlending(paint, true);
setupDrawProgram();
setupDrawDirtyRegionsDisabled();
setupDrawModelView(kModelViewMode_TranslateAndScale, false, 0.0f, 0.0f, 1.0f, 1.0f);
setupDrawTexture(texture->id);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
setupDrawMesh(&mesh[0].x, &mesh[0].u, &mesh[0].r);
glDrawArrays(GL_TRIANGLES, 0, count);
@@ -2190,10 +2241,6 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,
mCaches.unbindMeshBuffer();
resetDrawTextureTexCoords(u1, v1, u2, v2);
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
texture->setWrap(GL_CLAMP_TO_EDGE, true);
float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft);
@@ -2235,14 +2282,13 @@ status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,
}
if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
int color = paint ? paint->getColor() : 0;
drawAlpha8TextureMesh(dstLeft, dstTop, dstRight, dstBottom,
texture->id, paint != NULL, color, alpha, mode,
texture->id, paint,
&mMeshVertices[0].x, &mMeshVertices[0].u,
GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform);
} else {
drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom,
texture->id, alpha / 255.0f, mode, texture->blend,
texture->id, paint, texture->blend,
&mMeshVertices[0].x, &mMeshVertices[0].u,
GL_TRIANGLE_STRIP, gMeshCount, false, ignoreTransform);
}
@@ -2285,10 +2331,6 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
texture->setWrap(GL_CLAMP_TO_EDGE, true);
texture->setFilter(GL_LINEAR, true);
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
const bool pureTranslate = currentTransform()->isPureTranslate();
// Mark the current layer dirty where we are going to draw the patch
if (hasLayer() && mesh->hasEmptyQuads) {
@@ -2319,8 +2361,8 @@ status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
top = y;
ignoreTransform = true;
}
drawIndexedTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f,
mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
drawIndexedTextureMesh(left, top, right, bottom, texture->id, paint,
texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
GL_TRIANGLES, mesh->indexCount, false, ignoreTransform,
mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads);
}
@@ -2343,12 +2385,8 @@ status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry*
texture->setWrap(GL_CLAMP_TO_EDGE, true);
texture->setFilter(GL_LINEAR, true);
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f,
mode, texture->blend, &vertices[0].x, &vertices[0].u,
drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, paint,
texture->blend, &vertices[0].x, &vertices[0].u,
GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false);
return DrawGlInfo::kStatusDrew;
@@ -2364,20 +2402,19 @@ status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, cons
}
int color = paint->getColor();
SkXfermode::Mode mode = getXfermode(paint->getXfermode());
bool isAA = paint->isAntiAlias();
setupDraw();
setupDrawNoTexture();
if (isAA) setupDrawAA();
setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
setupDrawColorFilter();
setupDrawColorFilter(getColorFilter(paint));
setupDrawShader();
setupDrawBlending(isAA, mode);
setupDrawBlending(paint, isAA);
setupDrawProgram();
setupDrawModelView(kModelViewMode_Translate, useOffset, 0, 0, 0, 0);
setupDrawColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
setupDrawShaderUniforms();
const void* vertices = vertexBuffer.getBuffer();
@@ -2486,7 +2523,11 @@ status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
Rect clip(*currentClipRect());
clip.snapToPixelBoundaries();
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
SkPaint paint;
paint.setColor(color);
paint.setXfermodeMode(mode);
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, &paint, true);
return DrawGlInfo::kStatusDrew;
}
@@ -2642,14 +2683,14 @@ status_t OpenGLRenderer::drawRect(float left, float top, float right, float bott
path.addRect(left, top, right, bottom);
return drawConvexPath(path, p);
} else {
drawColorRect(left, top, right, bottom, p->getColor(), getXfermode(p->getXfermode()));
drawColorRect(left, top, right, bottom, p);
return DrawGlInfo::kStatusDrew;
}
}
void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text,
int bytesCount, int count, const float* positions,
FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode, float x, float y) {
FontRenderer& fontRenderer, int alpha, float x, float y) {
mCaches.activeTexture(0);
// NOTE: The drop shadow will not perform gamma correction
@@ -2674,15 +2715,15 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text,
setupDraw();
setupDrawWithTexture(true);
setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha);
setupDrawColorFilter();
setupDrawColorFilter(getColorFilter(paint));
setupDrawShader();
setupDrawBlending(true, mode);
setupDrawBlending(paint, true);
setupDrawProgram();
setupDrawModelView(kModelViewMode_TranslateAndScale, false,
sx, sy, sx + shadow->width, sy + shadow->height);
setupDrawTexture(shadow->id);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
setupDrawShaderUniforms();
setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
@@ -2724,7 +2765,7 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count
if (CC_UNLIKELY(mDrawModifiers.mHasShadow)) {
drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer,
alpha, mode, 0.0f, 0.0f);
alpha, 0.0f, 0.0f);
}
// Pick the appropriate texture filtering
@@ -2802,7 +2843,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, f
if (CC_UNLIKELY(mDrawModifiers.mHasShadow)) {
fontRenderer.setFont(paint, mat4::identity());
drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer,
alpha, mode, oldX, oldY);
alpha, oldX, oldY);
}
const bool hasActiveLayer = hasLayer();
@@ -2938,22 +2979,20 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
mCaches.activeTexture(0);
if (CC_LIKELY(!layer->region.isEmpty())) {
SkiaColorFilter* oldFilter = mDrawModifiers.mColorFilter;
mDrawModifiers.mColorFilter = layer->getColorFilter();
if (layer->region.isRect()) {
DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
composeLayerRect(layer, layer->regionRect));
} else if (layer->mesh) {
const float a = getLayerAlpha(layer);
setupDraw();
setupDrawWithTexture();
setupDrawColor(a, a, a, a);
setupDrawColorFilter();
setupDrawBlending(layer->isBlend() || a < 1.0f, layer->getMode(), false);
setupDrawColorFilter(layer->getColorFilter());
setupDrawBlending(layer);
setupDrawProgram();
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(layer->getColorFilter());
setupDrawTexture(layer->getTexture());
if (CC_LIKELY(currentTransform()->isPureTranslate())) {
int tx = (int) floorf(x + currentTransform()->getTranslateX() + 0.5f);
@@ -2989,12 +3028,12 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
#endif
}
mDrawModifiers.mColorFilter = oldFilter;
if (layer->debugDrawUpdate) {
layer->debugDrawUpdate = false;
drawColorRect(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(),
0x7f00ff00, SkXfermode::kSrcOver_Mode);
SkPaint paint;
paint.setColor(0x7f00ff00);
drawColorRect(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), &paint);
}
}
layer->hasDrawnSinceUpdate = true;
@@ -3021,18 +3060,6 @@ void OpenGLRenderer::setupShader(SkiaShader* shader) {
}
}
///////////////////////////////////////////////////////////////////////////////
// Color filters
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::resetColorFilter() {
mDrawModifiers.mColorFilter = NULL;
}
void OpenGLRenderer::setupColorFilter(SkiaColorFilter* filter) {
mDrawModifiers.mColorFilter = filter;
}
///////////////////////////////////////////////////////////////////////////////
// Drop shadow
///////////////////////////////////////////////////////////////////////////////
@@ -3106,15 +3133,15 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
setupDraw();
setupDrawWithTexture(true);
setupDrawAlpha8Color(paint->getColor(), alpha);
setupDrawColorFilter();
setupDrawColorFilter(getColorFilter(paint));
setupDrawShader();
setupDrawBlending(true, mode);
setupDrawBlending(paint, true);
setupDrawProgram();
setupDrawModelView(kModelViewMode_TranslateAndScale, false,
x, y, x + texture->width, y + texture->height);
setupDrawTexture(texture->id);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
setupDrawShaderUniforms();
setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
@@ -3176,14 +3203,7 @@ status_t OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint*
return DrawGlInfo::kStatusDone;
}
int color = paint->getColor();
// If a shader is set, preserve only the alpha
if (mDrawModifiers.mShader) {
color |= 0x00ffffff;
}
SkXfermode::Mode mode = getXfermode(paint->getXfermode());
return drawColorRects(rects, count, color, mode);
return drawColorRects(rects, count, paint, false, true, true);
}
status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlpha,
@@ -3235,12 +3255,18 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlp
return DrawGlInfo::kStatusDrew;
}
status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color,
SkXfermode::Mode mode, bool ignoreTransform, bool dirty, bool clip) {
status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint,
bool ignoreTransform, bool dirty, bool clip) {
if (count == 0) {
return DrawGlInfo::kStatusDone;
}
int color = paint->getColor();
// If a shader is set, preserve only the alpha
if (mDrawModifiers.mShader) {
color |= 0x00ffffff;
}
float left = FLT_MAX;
float top = FLT_MAX;
float right = FLT_MIN;
@@ -3274,15 +3300,15 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
setupDrawNoTexture();
setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha);
setupDrawShader();
setupDrawColorFilter();
setupDrawBlending(mode);
setupDrawColorFilter(getColorFilter(paint));
setupDrawBlending(paint);
setupDrawProgram();
setupDrawDirtyRegionsDisabled();
setupDrawModelView(kModelViewMode_Translate, false,
0.0f, 0.0f, 0.0f, 0.0f, ignoreTransform);
setupDrawColorUniforms();
setupDrawShaderUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
if (dirty && hasLayer()) {
dirtyLayer(left, top, right, bottom, *currentTransform());
@@ -3294,7 +3320,8 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
}
void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
int color, SkXfermode::Mode mode, bool ignoreTransform) {
const SkPaint* paint, bool ignoreTransform) {
int color = paint->getColor();
// If a shader is set, preserve only the alpha
if (mDrawModifiers.mShader) {
color |= 0x00ffffff;
@@ -3304,14 +3331,14 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot
setupDrawNoTexture();
setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha);
setupDrawShader();
setupDrawColorFilter();
setupDrawBlending(mode);
setupDrawColorFilter(getColorFilter(paint));
setupDrawBlending(paint);
setupDrawProgram();
setupDrawModelView(kModelViewMode_TranslateAndScale, false,
left, top, right, bottom, ignoreTransform);
setupDrawColorUniforms();
setupDrawShaderUniforms(ignoreTransform);
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
setupDrawSimpleMesh();
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
@@ -3319,10 +3346,6 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot
void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
Texture* texture, const SkPaint* paint) {
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
texture->setWrap(GL_CLAMP_TO_EDGE, true);
GLvoid* vertices = (GLvoid*) NULL;
@@ -3344,11 +3367,11 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b
texture->setFilter(GL_NEAREST, true);
drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
alpha / 255.0f, mode, texture->blend, vertices, texCoords,
paint, texture->blend, vertices, texCoords,
GL_TRIANGLE_STRIP, gMeshCount, false, true);
} else {
texture->setFilter(FILTER(paint), true);
drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
drawTextureMesh(left, top, right, bottom, texture->id, paint,
texture->blend, vertices, texCoords, GL_TRIANGLE_STRIP, gMeshCount);
}
@@ -3357,75 +3380,84 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b
}
}
void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
GLuint texture, float alpha, SkXfermode::Mode mode, bool blend) {
drawTextureMesh(left, top, right, bottom, texture, alpha, mode, blend,
(GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount);
}
void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom,
GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
GLuint texture, const SkPaint* paint, bool blend,
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
bool swapSrcDst, bool ignoreTransform, GLuint vbo,
ModelViewMode modelViewMode, bool dirty) {
int a;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &a, &mode);
const float alpha = a / 255.0f;
setupDraw();
setupDrawWithTexture();
setupDrawColor(alpha, alpha, alpha, alpha);
setupDrawColorFilter();
setupDrawBlending(blend, mode, swapSrcDst);
setupDrawColorFilter(getColorFilter(paint));
setupDrawBlending(paint, blend, swapSrcDst);
setupDrawProgram();
if (!dirty) setupDrawDirtyRegionsDisabled();
setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
setupDrawTexture(texture);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
setupDrawMesh(vertices, texCoords, vbo);
glDrawArrays(drawMode, 0, elementsCount);
}
void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, float bottom,
GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
GLuint texture, const SkPaint* paint, bool blend,
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
bool swapSrcDst, bool ignoreTransform, GLuint vbo,
ModelViewMode modelViewMode, bool dirty) {
int a;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &a, &mode);
const float alpha = a / 255.0f;
setupDraw();
setupDrawWithTexture();
setupDrawColor(alpha, alpha, alpha, alpha);
setupDrawColorFilter();
setupDrawBlending(blend, mode, swapSrcDst);
setupDrawColorFilter(getColorFilter(paint));
setupDrawBlending(paint, blend, swapSrcDst);
setupDrawProgram();
if (!dirty) setupDrawDirtyRegionsDisabled();
setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
setupDrawTexture(texture);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
setupDrawMeshIndices(vertices, texCoords, vbo);
glDrawElements(drawMode, elementsCount, GL_UNSIGNED_SHORT, NULL);
}
void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, float bottom,
GLuint texture, bool hasColor, int color, int alpha, SkXfermode::Mode mode,
GLuint texture, const SkPaint* paint,
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
bool ignoreTransform, ModelViewMode modelViewMode, bool dirty) {
int color = paint != NULL ? paint->getColor() : 0;
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
setupDraw();
setupDrawWithTexture(true);
if (hasColor) {
if (paint != NULL) {
setupDrawAlpha8Color(color, alpha);
}
setupDrawColorFilter();
setupDrawColorFilter(getColorFilter(paint));
setupDrawShader();
setupDrawBlending(true, mode);
setupDrawBlending(paint, true);
setupDrawProgram();
if (!dirty) setupDrawDirtyRegionsDisabled();
setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
setupDrawTexture(texture);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawColorFilterUniforms(getColorFilter(paint));
setupDrawShaderUniforms(ignoreTransform);
setupDrawMesh(vertices, texCoords);
@@ -3516,7 +3548,7 @@ void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermod
*alpha *= currentSnapshot()->alpha;
}
float OpenGLRenderer::getLayerAlpha(Layer* layer) const {
float OpenGLRenderer::getLayerAlpha(const Layer* layer) const {
float alpha;
if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) {
alpha = mDrawModifiers.mOverrideLayerAlpha;

View File

@@ -21,6 +21,8 @@
#include <GLES2/gl2ext.h>
#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkColorFilter.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkRegion.h>
@@ -43,7 +45,6 @@
#include "Rect.h"
#include "Renderer.h"
#include "StatefulBaseRenderer.h"
#include "SkiaColorFilter.h"
#include "Snapshot.h"
#include "UvMapper.h"
#include "Vertex.h"
@@ -68,7 +69,6 @@ struct DrawModifiers {
}
SkiaShader* mShader;
SkiaColorFilter* mColorFilter;
float mOverrideLayerAlpha;
// Drop shadow
@@ -209,9 +209,6 @@ public:
virtual void resetShader();
virtual void setupShader(SkiaShader* shader);
virtual void resetColorFilter();
virtual void setupColorFilter(SkiaColorFilter* filter);
virtual void resetShadow();
virtual void setupShadow(float radius, float dx, float dy, int color);
@@ -432,18 +429,14 @@ protected:
*
* @param layer The layer from which the alpha is extracted
*/
inline float getLayerAlpha(Layer* layer) const;
inline float getLayerAlpha(const Layer* layer) const;
/**
* Safely retrieves the mode from the specified xfermode. If the specified
* xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
* Safely retrieves the ColorFilter from the given Paint. If the paint is
* null then null is returned.
*/
static inline SkXfermode::Mode getXfermode(SkXfermode* mode) {
SkXfermode::Mode resultMode;
if (!SkXfermode::AsMode(mode, &resultMode)) {
resultMode = SkXfermode::kSrcOver_Mode;
}
return resultMode;
static inline SkColorFilter* getColorFilter(const SkPaint* paint) {
return paint ? paint->getColorFilter() : NULL;
}
/**
@@ -584,12 +577,11 @@ private:
* @param top The top coordinate of the rectangle
* @param right The right coordinate of the rectangle
* @param bottom The bottom coordinate of the rectangle
* @param color The rectangle's ARGB color, defined as a packed 32 bits word
* @param mode The Skia xfermode to use
* @param paint The paint containing the color, blending mode, etc.
* @param ignoreTransform True if the current transform should be ignored
*/
void drawColorRect(float left, float top, float right, float bottom,
int color, SkXfermode::Mode mode, bool ignoreTransform = false);
const SkPaint* paint, bool ignoreTransform = false);
/**
* Draws a series of colored rectangles with the specified color. The specified
@@ -598,15 +590,13 @@ private:
*
* @param rects A list of rectangles, 4 floats (left, top, right, bottom)
* per rectangle
* @param color The rectangles' ARGB color, defined as a packed 32 bits word
* @param mode The Skia xfermode to use
* @param paint The paint containing the color, blending mode, etc.
* @param ignoreTransform True if the current transform should be ignored
* @param dirty True if calling this method should dirty the current layer
* @param clip True if the rects should be clipped, false otherwise
*/
status_t drawColorRects(const float* rects, int count, int color,
SkXfermode::Mode mode, bool ignoreTransform = false,
bool dirty = true, bool clip = true);
status_t drawColorRects(const float* rects, int count, const SkPaint* paint,
bool ignoreTransform = false, bool dirty = true, bool clip = true);
/**
* Draws the shape represented by the specified path texture.
@@ -650,22 +640,6 @@ private:
*/
status_t drawConvexPath(const SkPath& path, const SkPaint* paint);
/**
* Draws a textured rectangle with the specified texture. The specified coordinates
* are transformed by the current snapshot's transform matrix.
*
* @param left The left coordinate of the rectangle
* @param top The top coordinate of the rectangle
* @param right The right coordinate of the rectangle
* @param bottom The bottom coordinate of the rectangle
* @param texture The texture name to map onto the rectangle
* @param alpha An additional translucency parameter, between 0.0f and 1.0f
* @param mode The blending mode
* @param blend True if the texture contains an alpha channel
*/
void drawTextureRect(float left, float top, float right, float bottom, GLuint texture,
float alpha, SkXfermode::Mode mode, bool blend);
/**
* Draws a textured rectangle with the specified texture. The specified coordinates
* are transformed by the current snapshot's transform matrix.
@@ -690,8 +664,7 @@ private:
* @param right The right coordinate of the rectangle
* @param bottom The bottom coordinate of the rectangle
* @param texture The texture name to map onto the rectangle
* @param alpha An additional translucency parameter, between 0.0f and 1.0f
* @param mode The blending mode
* @param paint The paint containing the alpha, blending mode, colorFilter, etc.
* @param blend True if the texture contains an alpha channel
* @param vertices The vertices that define the mesh
* @param texCoords The texture coordinates of each vertex
@@ -703,19 +676,19 @@ private:
* @param dirty True if calling this method should dirty the current layer
*/
void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
float alpha, SkXfermode::Mode mode, bool blend,
const SkPaint* paint, bool blend,
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);
void drawIndexedTextureMesh(float left, float top, float right, float bottom, GLuint texture,
float alpha, SkXfermode::Mode mode, bool blend,
const SkPaint* paint, bool blend,
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);
void drawAlpha8TextureMesh(float left, float top, float right, float bottom,
GLuint texture, bool hasColor, int color, int alpha, SkXfermode::Mode mode,
GLuint texture, const SkPaint* paint,
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
bool ignoreTransform, ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale,
bool dirty = true);
@@ -749,12 +722,11 @@ private:
* @param positions The x, y positions of individual glyphs (or NULL)
* @param fontRenderer The font renderer object
* @param alpha The alpha value for drawing the shadow
* @param mode The xfermode for drawing the shadow
* @param x The x coordinate where the shadow will be drawn
* @param y The y coordinate where the shadow will be drawn
*/
void drawTextShadow(const SkPaint* paint, const char* text, int bytesCount, int count,
const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode,
const float* positions, FontRenderer& fontRenderer, int alpha,
float x, float y);
/**
@@ -839,11 +811,9 @@ private:
void setupDrawAlpha8Color(int color, int alpha);
void setupDrawTextGamma(const SkPaint* paint);
void setupDrawShader();
void setupDrawColorFilter();
void setupDrawBlending(SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
bool swapSrcDst = false);
void setupDrawBlending(bool blend = true, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
bool swapSrcDst = false);
void setupDrawColorFilter(const SkColorFilter* filter);
void setupDrawBlending(const Layer* layer, bool swapSrcDst = false);
void setupDrawBlending(const SkPaint* paint, bool blend = true, bool swapSrcDst = false);
void setupDrawProgram();
void setupDrawDirtyRegionsDisabled();
@@ -867,7 +837,7 @@ private:
void setupDrawColorUniforms();
void setupDrawPureColorUniforms();
void setupDrawShaderUniforms(bool ignoreTransform = false);
void setupDrawColorFilterUniforms();
void setupDrawColorFilterUniforms(const SkColorFilter* paint);
void setupDrawSimpleMesh();
void setupDrawTexture(GLuint texture);
void setupDrawExternalTexture(GLuint texture);
@@ -896,8 +866,7 @@ private:
* Renders the specified region as a series of rectangles. The region
* must be in screen-space coordinates.
*/
void drawRegionRects(const SkRegion& region, int color, SkXfermode::Mode mode,
bool dirty = false);
void drawRegionRects(const SkRegion& region, const SkPaint& paint, bool dirty = false);
/**
* Draws the current clip region if any. Only when DEBUG_CLIP_REGIONS

View File

@@ -51,9 +51,8 @@ namespace uirenderer {
#define PROGRAM_KEY_GRADIENT 0x8
#define PROGRAM_KEY_BITMAP_FIRST 0x10
#define PROGRAM_KEY_COLOR_MATRIX 0x20
#define PROGRAM_KEY_COLOR_LIGHTING 0x40
#define PROGRAM_KEY_COLOR_BLEND 0x80
#define PROGRAM_KEY_BITMAP_NPOT 0x100
#define PROGRAM_KEY_COLOR_BLEND 0x40
#define PROGRAM_KEY_BITMAP_NPOT 0x80
#define PROGRAM_KEY_SWAP_SRC_DST 0x2000
#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
@@ -104,7 +103,6 @@ struct ProgramDescription {
enum ColorModifier {
kColorNone = 0,
kColorMatrix,
kColorLighting,
kColorBlend
};
@@ -248,9 +246,6 @@ struct ProgramDescription {
case kColorMatrix:
key |= PROGRAM_KEY_COLOR_MATRIX;
break;
case kColorLighting:
key |= PROGRAM_KEY_COLOR_LIGHTING;
break;
case kColorBlend:
key |= PROGRAM_KEY_COLOR_BLEND;
key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;

View File

@@ -148,15 +148,12 @@ const char* gFS_Uniforms_GradientSampler[2] = {
};
const char* gFS_Uniforms_BitmapSampler =
"uniform sampler2D bitmapSampler;\n";
const char* gFS_Uniforms_ColorOp[4] = {
const char* gFS_Uniforms_ColorOp[3] = {
// None
"",
// Matrix
"uniform mat4 colorMatrix;\n"
"uniform vec4 colorMatrixVector;\n",
// Lighting
"uniform vec4 lightingMul;\n"
"uniform vec4 lightingAdd;\n",
// PorterDuff
"uniform vec4 colorBlend;\n"
};
@@ -311,17 +308,13 @@ const char* gFS_Main_FragColor_Blend =
" gl_FragColor = blendFramebuffer(fragColor, gl_LastFragColor);\n";
const char* gFS_Main_FragColor_Blend_Swap =
" gl_FragColor = blendFramebuffer(gl_LastFragColor, fragColor);\n";
const char* gFS_Main_ApplyColorOp[4] = {
const char* gFS_Main_ApplyColorOp[3] = {
// None
"",
// Matrix
" fragColor *= colorMatrix;\n"
" fragColor += colorMatrixVector;\n"
" fragColor.rgb *= fragColor.a;\n",
// Lighting
" float lightingAlpha = fragColor.a;\n"
" fragColor = min(fragColor * lightingMul + (lightingAdd * lightingAlpha), lightingAlpha);\n"
" fragColor.a = lightingAlpha;\n",
// PorterDuff
" fragColor = blendColors(colorBlend, fragColor);\n"
};

View File

@@ -178,9 +178,6 @@ public:
virtual void resetShader() = 0;
virtual void setupShader(SkiaShader* shader) = 0;
virtual void resetColorFilter() = 0;
virtual void setupColorFilter(SkiaColorFilter* filter) = 0;
virtual void resetShadow() = 0;
virtual void setupShadow(float radius, float dx, float dy, int color) = 0;

View File

@@ -76,11 +76,6 @@ void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
incrementRefcount((void*) shaderResource, kShader);
}
void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
SkSafeRef(filterResource->getSkColorFilter());
incrementRefcount((void*) filterResource, kColorFilter);
}
void ResourceCache::incrementRefcount(const Res_png_9patch* patchResource) {
incrementRefcount((void*) patchResource, kNinePatch);
}
@@ -114,11 +109,6 @@ void ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) {
incrementRefcountLocked((void*) shaderResource, kShader);
}
void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
SkSafeRef(filterResource->getSkColorFilter());
incrementRefcountLocked((void*) filterResource, kColorFilter);
}
void ResourceCache::incrementRefcountLocked(const Res_png_9patch* patchResource) {
incrementRefcountLocked((void*) patchResource, kNinePatch);
}
@@ -147,11 +137,6 @@ void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
decrementRefcount((void*) shaderResource);
}
void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
SkSafeUnref(filterResource->getSkColorFilter());
decrementRefcount((void*) filterResource);
}
void ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) {
decrementRefcount((void*) patchResource);
}
@@ -188,11 +173,6 @@ void ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) {
decrementRefcountLocked((void*) shaderResource);
}
void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
SkSafeUnref(filterResource->getSkColorFilter());
decrementRefcountLocked((void*) filterResource);
}
void ResourceCache::decrementRefcountLocked(const Res_png_9patch* patchResource) {
decrementRefcountLocked((void*) patchResource);
}
@@ -264,25 +244,6 @@ void ResourceCache::destructorLocked(SkiaShader* resource) {
}
}
void ResourceCache::destructor(SkiaColorFilter* resource) {
Mutex::Autolock _l(mLock);
destructorLocked(resource);
}
void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
ssize_t index = mCache->indexOfKey(resource);
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
delete resource;
return;
}
ref->destroyed = true;
if (ref->refCount == 0) {
deleteResourceReferenceLocked(resource, ref);
}
}
void ResourceCache::destructor(Res_png_9patch* resource) {
Mutex::Autolock _l(mLock);
destructorLocked(resource);
@@ -372,11 +333,6 @@ void ResourceCache::deleteResourceReferenceLocked(const void* resource, Resource
delete shader;
}
break;
case kColorFilter: {
SkiaColorFilter* filter = (SkiaColorFilter*) resource;
delete filter;
}
break;
case kNinePatch: {
if (Caches::hasInstance()) {
Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource);

View File

@@ -20,7 +20,6 @@
#include <cutils/compiler.h>
#include <SkBitmap.h>
#include <SkiaColorFilter.h>
#include <SkiaShader.h>
#include <utils/KeyedVector.h>
@@ -38,7 +37,6 @@ namespace uirenderer {
enum ResourceType {
kBitmap,
kShader,
kColorFilter,
kNinePatch,
kPath,
kLayer
@@ -73,41 +71,35 @@ public:
void incrementRefcount(const SkPath* resource);
void incrementRefcount(const SkBitmap* resource);
void incrementRefcount(SkiaShader* resource);
void incrementRefcount(SkiaColorFilter* resource);
void incrementRefcount(const Res_png_9patch* resource);
void incrementRefcount(Layer* resource);
void incrementRefcountLocked(const SkPath* resource);
void incrementRefcountLocked(const SkBitmap* resource);
void incrementRefcountLocked(SkiaShader* resource);
void incrementRefcountLocked(SkiaColorFilter* resource);
void incrementRefcountLocked(const Res_png_9patch* resource);
void incrementRefcountLocked(Layer* resource);
void decrementRefcount(const SkBitmap* resource);
void decrementRefcount(const SkPath* resource);
void decrementRefcount(SkiaShader* resource);
void decrementRefcount(SkiaColorFilter* resource);
void decrementRefcount(const Res_png_9patch* resource);
void decrementRefcount(Layer* resource);
void decrementRefcountLocked(const SkBitmap* resource);
void decrementRefcountLocked(const SkPath* resource);
void decrementRefcountLocked(SkiaShader* resource);
void decrementRefcountLocked(SkiaColorFilter* resource);
void decrementRefcountLocked(const Res_png_9patch* resource);
void decrementRefcountLocked(Layer* resource);
void destructor(SkPath* resource);
void destructor(const SkBitmap* resource);
void destructor(SkiaShader* resource);
void destructor(SkiaColorFilter* resource);
void destructor(Res_png_9patch* resource);
void destructorLocked(SkPath* resource);
void destructorLocked(const SkBitmap* resource);
void destructorLocked(SkiaShader* resource);
void destructorLocked(SkiaColorFilter* resource);
void destructorLocked(Res_png_9patch* resource);
bool recycle(SkBitmap* resource);

View File

@@ -1,117 +0,0 @@
/*
* 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.
*/
#include "SkiaColorFilter.h"
namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Base color filter
///////////////////////////////////////////////////////////////////////////////
SkiaColorFilter::SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend):
mType(type), mBlend(blend), mSkFilter(skFilter) {
}
SkiaColorFilter::~SkiaColorFilter() {
}
///////////////////////////////////////////////////////////////////////////////
// Color matrix filter
///////////////////////////////////////////////////////////////////////////////
SkiaColorMatrixFilter::SkiaColorMatrixFilter(SkColorFilter* skFilter, float* matrix, float* vector):
SkiaColorFilter(skFilter, kColorMatrix, true), mMatrix(matrix), mVector(vector) {
// Skia uses the range [0..255] for the addition vector, but we need
// the [0..1] range to apply the vector in GLSL
for (int i = 0; i < 4; i++) {
mVector[i] /= 255.0f;
}
// TODO: We should be smarter about this
mBlend = true;
}
SkiaColorMatrixFilter::~SkiaColorMatrixFilter() {
delete[] mMatrix;
delete[] mVector;
}
void SkiaColorMatrixFilter::describe(ProgramDescription& description,
const Extensions& extensions) {
description.colorOp = ProgramDescription::kColorMatrix;
}
void SkiaColorMatrixFilter::setupProgram(Program* program) {
glUniformMatrix4fv(program->getUniform("colorMatrix"), 1, GL_FALSE, &mMatrix[0]);
glUniform4fv(program->getUniform("colorMatrixVector"), 1, mVector);
}
///////////////////////////////////////////////////////////////////////////////
// Lighting color filter
///////////////////////////////////////////////////////////////////////////////
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;
mAddR = ((add >> 16) & 0xFF) / 255.0f;
mAddG = ((add >> 8) & 0xFF) / 255.0f;
mAddB = ((add ) & 0xFF) / 255.0f;
// A lighting filter always ignores alpha
mBlend = false;
}
void SkiaLightingFilter::describe(ProgramDescription& description, const Extensions& extensions) {
description.colorOp = ProgramDescription::kColorLighting;
}
void SkiaLightingFilter::setupProgram(Program* program) {
glUniform4f(program->getUniform("lightingMul"), mMulR, mMulG, mMulB, 1.0f);
glUniform4f(program->getUniform("lightingAdd"), mAddR, mAddG, mAddB, 0.0f);
}
///////////////////////////////////////////////////////////////////////////////
// Blend color filter
///////////////////////////////////////////////////////////////////////////////
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;
mG = mA * ((color >> 8) & 0xFF) / 255.0f;
mB = mA * ((color ) & 0xFF) / 255.0f;
// TODO: We should do something smarter here
mBlend = true;
}
void SkiaBlendFilter::describe(ProgramDescription& description, const Extensions& extensions) {
description.colorOp = ProgramDescription::kColorBlend;
description.colorMode = mMode;
}
void SkiaBlendFilter::setupProgram(Program* program) {
glUniform4f(program->getUniform("colorBlend"), mR, mG, mB, mA);
}
}; // namespace uirenderer
}; // namespace android

View File

@@ -1,132 +0,0 @@
/*
* 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_HWUI_SKIA_COLOR_FILTER_H
#define ANDROID_HWUI_SKIA_COLOR_FILTER_H
#include <GLES2/gl2.h>
#include <SkColorFilter.h>
#include <cutils/compiler.h>
#include "ProgramCache.h"
#include "Extensions.h"
namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Base color filter
///////////////////////////////////////////////////////////////////////////////
/**
* Represents a Skia color filter. A color filter modifies a ProgramDescription
* and sets uniforms on the resulting shaders.
*/
class SkiaColorFilter {
public:
/**
* Type of Skia color filter in use.
*/
enum Type {
kNone,
kColorMatrix,
kLighting,
kBlend,
};
ANDROID_API SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend);
virtual ~SkiaColorFilter();
virtual void describe(ProgramDescription& description, const Extensions& extensions) = 0;
virtual void setupProgram(Program* program) = 0;
inline bool blend() const {
return mBlend;
}
Type type() const {
return mType;
}
SkColorFilter* getSkColorFilter() {
return mSkFilter;
}
protected:
Type mType;
bool mBlend;
private:
SkColorFilter *mSkFilter;
}; // struct SkiaColorFilter
///////////////////////////////////////////////////////////////////////////////
// Implementations
///////////////////////////////////////////////////////////////////////////////
/**
* A color filter that multiplies the source color with a matrix and adds a vector.
*/
class SkiaColorMatrixFilter: public SkiaColorFilter {
public:
ANDROID_API SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector);
~SkiaColorMatrixFilter();
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program);
private:
float* mMatrix;
float* mVector;
}; // struct SkiaColorMatrixFilter
/**
* A color filters that multiplies the source color with a fixed value and adds
* another fixed value. Ignores the alpha channel of both arguments.
*/
class SkiaLightingFilter: public SkiaColorFilter {
public:
ANDROID_API SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add);
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program);
private:
GLfloat mMulR, mMulG, mMulB;
GLfloat mAddR, mAddG, mAddB;
}; // struct SkiaLightingFilter
/**
* A color filters that blends the source color with a specified destination color
* and PorterDuff blending mode.
*/
class SkiaBlendFilter: public SkiaColorFilter {
public:
ANDROID_API SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode);
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program);
private:
SkXfermode::Mode mMode;
GLfloat mR, mG, mB, mA;
}; // struct SkiaBlendFilter
}; // namespace uirenderer
}; // namespace android
#endif // ANDROID_HWUI_SKIA_COLOR_FILTER_H