diff options
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 11 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 8 | ||||
-rw-r--r-- | graphics/java/android/graphics/Canvas.java | 9 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 45 |
5 files changed, 62 insertions, 12 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index b86455a..6de06d4 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -994,4 +994,15 @@ class GLES20Canvas extends HardwareCanvas { int indexOffset, int indexCount, Paint paint) { // TODO: Implement } + + @Override + public void setOverrideXfermode(PorterDuff.Mode xfermode) { + int xfermodeValue = -1; + if (xfermode != null) { + xfermodeValue = xfermode.nativeInt; + } + nSetOverrideXfermode(mRenderer, xfermodeValue); + } + + private static native void nSetOverrideXfermode(long renderer, int xfermode); } diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index b023ebd..fe64aba 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -172,6 +172,12 @@ static jint android_view_GLES20Canvas_getMaxTextureHeight(JNIEnv* env, jobject c return Caches::getInstance().maxTextureSize; } +static void android_view_GLES20Canvas_setOverrideXfermode(JNIEnv* env, jobject clazz, + jlong rendererPtr, int xfermode) { + DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); + renderer->setOverrideXfermode(xfermode); +} + // ---------------------------------------------------------------------------- // State // ---------------------------------------------------------------------------- @@ -964,6 +970,8 @@ static JNINativeMethod gMethods[] = { { "nGetMaximumTextureWidth", "()I", (void*) android_view_GLES20Canvas_getMaxTextureWidth }, { "nGetMaximumTextureHeight", "()I", (void*) android_view_GLES20Canvas_getMaxTextureHeight }, + { "nSetOverrideXfermode", "(JI)V", (void*) android_view_GLES20Canvas_setOverrideXfermode }, + #endif }; diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index f45c0cb..6baf1aa 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -250,6 +250,15 @@ public class Canvas { public void insertInorderBarrier() {} /** + * Set a transfer mode that overrides any transfer modes + * in paints used for drawing. Pass null to disable this + * override. Only implemented in GLES20Canvas. + * + * @hide + */ + public void setOverrideXfermode(@Nullable PorterDuff.Mode xfermode) {} + + /** * Return true if the device that the current layer draws into is opaque * (i.e. does not support per-pixel alpha). * diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index c2cb76e..3ec5e40 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -39,6 +39,7 @@ DisplayListRenderer::DisplayListRenderer() , mTranslateY(0.0f) , mDeferredBarrierType(kBarrier_None) , mHighContrastText(false) + , mOverrideXfermode(-1) , mRestoreSaveCount(-1) { } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 2cc2be3..f93a798 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -20,6 +20,7 @@ #include <SkMatrix.h> #include <SkPaint.h> #include <SkPath.h> +#include <SkPorterDuff.h> #include <cutils/compiler.h> #include "DisplayListLogBuffer.h" @@ -161,6 +162,15 @@ public: void setHighContrastText(bool highContrastText) { mHighContrastText = highContrastText; } + + void setOverrideXfermode(int xfermode) { + if (xfermode != -1) { + SkPorterDuff::Mode porterDuffMode = static_cast<SkPorterDuff::Mode>(xfermode); + xfermode = SkPorterDuff::ToXfermodeMode(porterDuffMode); + } + mOverrideXfermode = xfermode; + }; + private: enum DeferredBarrierType { kBarrier_None, @@ -220,18 +230,26 @@ private: inline const SkPaint* refPaint(const SkPaint* paint) { if (!paint) return NULL; - const SkPaint* paintCopy = mPaintMap.valueFor(paint); - if (paintCopy == NULL - || paintCopy->getGenerationID() != paint->getGenerationID() - // We can't compare shader pointers because that will always - // change as we do partial copying via wrapping. However, if the - // shader changes the paint generationID will have changed and - // so we don't hit this comparison anyway - || !(paint->getShader() && paintCopy->getShader() - && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) { - paintCopy = copyPaint(paint); - // replaceValueFor() performs an add if the entry doesn't exist - mPaintMap.replaceValueFor(paint, paintCopy); + const SkPaint* paintCopy; + + if (mOverrideXfermode != -1) { + SkPaint* overriddenPaint = copyPaint(paint); + overriddenPaint->setXfermodeMode(static_cast<SkXfermode::Mode>(mOverrideXfermode)); + paintCopy = overriddenPaint; + } else { + paintCopy = mPaintMap.valueFor(paint); + if (paintCopy == NULL + || paintCopy->getGenerationID() != paint->getGenerationID() + // We can't compare shader pointers because that will always + // change as we do partial copying via wrapping. However, if the + // shader changes the paint generationID will have changed and + // so we don't hit this comparison anyway + || !(paint->getShader() && paintCopy->getShader() + && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) { + paintCopy = copyPaint(paint); + // replaceValueFor() performs an add if the entry doesn't exist + mPaintMap.replaceValueFor(paint, paintCopy); + } } return paintCopy; @@ -304,6 +322,9 @@ private: DeferredBarrierType mDeferredBarrierType; bool mHighContrastText; + // -1 if unset, or SkXfermode::Mode value if set + int mOverrideXfermode; + int mRestoreSaveCount; friend class RenderNode; |