diff options
author | Derek Sollenberger <djsollen@google.com> | 2013-12-10 12:28:58 -0500 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2014-02-07 17:06:14 -0500 |
commit | 76d3a1b8d035d27bc80b0f2fc480a903bd001514 (patch) | |
tree | a6346bbf593d565d89990f0bddecd2a5df92de9d | |
parent | 8852ab4357ffb653bafb36f3b9272866834f7a72 (diff) | |
download | frameworks_base-76d3a1b8d035d27bc80b0f2fc480a903bd001514.zip frameworks_base-76d3a1b8d035d27bc80b0f2fc480a903bd001514.tar.gz frameworks_base-76d3a1b8d035d27bc80b0f2fc480a903bd001514.tar.bz2 |
Removing SkiaColorFilter and inspecting the native object directly.
bug: 10650594
Change-Id: I4fcf66d008765afa0e35d011f58bc792183cb74f
27 files changed, 265 insertions, 793 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index dc68e51..b763888 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -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); diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java index 37154eb..1d30824 100644 --- a/core/java/android/view/GLES20Layer.java +++ b/core/java/android/view/GLES20Layer.java @@ -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); } } diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp index da40acf..09589bd 100644 --- a/core/jni/android/graphics/ColorFilter.cpp +++ b/core/jni/android/graphics/ColorFilter.cpp @@ -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) \ diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 04e51be..b854fb9 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -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 }, diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java index d3c1974..4838aa0 100644 --- a/graphics/java/android/graphics/ColorFilter.java +++ b/graphics/java/android/graphics/ColorFilter.java @@ -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); } diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java index 3f7331d..7822c41 100644 --- a/graphics/java/android/graphics/ColorMatrixColorFilter.java +++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java @@ -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); } diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java index 5829edf..70a3fe8 100644 --- a/graphics/java/android/graphics/LightingColorFilter.java +++ b/graphics/java/android/graphics/LightingColorFilter.java @@ -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); } diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java index 93fc1c7..c078c1c 100644 --- a/graphics/java/android/graphics/PorterDuffColorFilter.java +++ b/graphics/java/android/graphics/PorterDuffColorFilter.java @@ -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); } diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index e4648f6..8c388d9 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -39,7 +39,6 @@ ifeq ($(USE_OPENGL_RENDERER),true) RenderBufferCache.cpp \ ResourceCache.cpp \ ShadowTessellator.cpp \ - SkiaColorFilter.cpp \ SkiaShader.cpp \ Snapshot.cpp \ SpotShadow.cpp \ diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp index 7eb7028..3d58964 100644 --- a/libs/hwui/DeferredDisplayList.cpp +++ b/libs/hwui/DeferredDisplayList.cpp @@ -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; diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index 4742f91..7438849 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -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); diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index adf48d4..6d7f9c8 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -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; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index d4f82ea..0589a02 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -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 { diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 7c85297..0cbf088 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -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(); diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 3c14212..7e62c5d 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -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; diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index f907d64..b79a3b0 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -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(); diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 742ffd4..70eeb39 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -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 { diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 471a4a6..ec80e9c 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -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. diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 4b947a6..fee916b 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -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; @@ -3022,18 +3061,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; diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 131681e..e4d133d 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -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. @@ -658,22 +648,6 @@ 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 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. - * - * @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 to use * @param paint The paint containing the alpha, blending mode, etc. */ @@ -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 diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index 5dfb2fa..33c91b3 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -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; diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index a5ce6f6..6d50410 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -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" }; diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h index 058548a..4754bad 100644 --- a/libs/hwui/Renderer.h +++ b/libs/hwui/Renderer.h @@ -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; diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index e58857c..457cfa9 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -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); diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h index c06b09b..4097ba4 100644 --- a/libs/hwui/ResourceCache.h +++ b/libs/hwui/ResourceCache.h @@ -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); diff --git a/libs/hwui/SkiaColorFilter.cpp b/libs/hwui/SkiaColorFilter.cpp deleted file mode 100644 index df918be..0000000 --- a/libs/hwui/SkiaColorFilter.cpp +++ /dev/null @@ -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 diff --git a/libs/hwui/SkiaColorFilter.h b/libs/hwui/SkiaColorFilter.h deleted file mode 100644 index c222a2d..0000000 --- a/libs/hwui/SkiaColorFilter.h +++ /dev/null @@ -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 |