Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7768e029 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Add support for ColorFilters."

parents 532abb65 db1938e0
Loading
Loading
Loading
Loading
+46 −14
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.DrawFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
@@ -376,9 +377,11 @@ class GLES20Canvas extends Canvas {
    @Override
    public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
        // Shaders are ignored when drawing patches
        boolean hasColorFilter = paint != null && setupColorFilter(paint);
        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
        nDrawPatch(mRenderer, bitmap.mNativeBitmap, chunks, dst.left, dst.top,
                dst.right, dst.bottom, nativePaint);
        if (hasColorFilter) nResetModifiers(mRenderer);
    }

    private native void nDrawPatch(int renderer, int bitmap, byte[] chunks, float left, float top,
@@ -387,8 +390,10 @@ class GLES20Canvas extends Canvas {
    @Override
    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
        // Shaders are ignored when drawing bitmaps
        boolean hasColorFilter = paint != null && setupColorFilter(paint);
        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint);
        if (hasColorFilter) nResetModifiers(mRenderer);
    }

    private native void nDrawBitmap(int renderer, int bitmap, float left, float top, int paint);
@@ -396,8 +401,10 @@ class GLES20Canvas extends Canvas {
    @Override
    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
        // Shaders are ignored when drawing bitmaps
        boolean hasColorFilter = paint != null && setupColorFilter(paint);
        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, matrix.native_instance, nativePaint);
        if (hasColorFilter) nResetModifiers(mRenderer);
    }

    private native void nDrawBitmap(int renderer, int bitmap, int matrix, int paint);
@@ -405,6 +412,7 @@ class GLES20Canvas extends Canvas {
    @Override
    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
        // Shaders are ignored when drawing bitmaps
        boolean hasColorFilter = paint != null && setupColorFilter(paint);
        final int nativePaint = paint == null ? 0 : paint.mNativePaint;

        int left, top, right, bottom;
@@ -421,14 +429,17 @@ class GLES20Canvas extends Canvas {

        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
        if (hasColorFilter) nResetModifiers(mRenderer);
    }

    @Override
    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
        // Shaders are ignored when drawing bitmaps
        boolean hasColorFilter = paint != null && setupColorFilter(paint);
        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, src.left, src.top, src.right, src.bottom,
                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
        if (hasColorFilter) nResetModifiers(mRenderer);
    }

    private native void nDrawBitmap(int renderer, int bitmap,
@@ -439,11 +450,13 @@ class GLES20Canvas extends Canvas {
    public void drawBitmap(int[] colors, int offset, int stride, float x, float y,
            int width, int height, boolean hasAlpha, Paint paint) {
        // Shaders are ignored when drawing bitmaps
        boolean hasColorFilter = paint != null && setupColorFilter(paint);
        final Bitmap.Config config = hasAlpha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
        final Bitmap b = Bitmap.createBitmap(colors, offset, stride, width, height, config);
        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
        nDrawBitmap(mRenderer, b.mNativeBitmap, x, y, nativePaint);
        b.recycle();
        if (hasColorFilter) nResetModifiers(mRenderer);
    }

    @Override
@@ -556,9 +569,9 @@ class GLES20Canvas extends Canvas {

    @Override
    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
        boolean hasShader = setupShader(paint);
        boolean hasModifier = setupModifiers(paint);
        nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
        if (hasShader) nResetShader(mRenderer);
        if (hasModifier) nResetModifiers(mRenderer);
    }

    private native void nDrawRect(int renderer, float left, float top, float right, float bottom,
@@ -589,9 +602,9 @@ class GLES20Canvas extends Canvas {
        if ((index | count | (index + count) | (text.length - index - count)) < 0) {
            throw new IndexOutOfBoundsException();
        }
        boolean hasShader = setupShader(paint);
        boolean hasModifier = setupModifiers(paint);
        nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint);
        if (hasShader) nResetShader(mRenderer);
        if (hasModifier) nResetModifiers(mRenderer);
    }
    
    private native void nDrawText(int renderer, char[] text, int index, int count, float x, float y,
@@ -599,7 +612,7 @@ class GLES20Canvas extends Canvas {

    @Override
    public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
        boolean hasShader = setupShader(paint);
        boolean hasModifier = setupModifiers(paint);
        if (text instanceof String || text instanceof SpannedString ||
                text instanceof SpannableString) {
            nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
@@ -613,7 +626,7 @@ class GLES20Canvas extends Canvas {
            nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint);
            TemporaryBuffer.recycle(buf);
        }
        if (hasShader) nResetShader(mRenderer);
        if (hasModifier) nResetModifiers(mRenderer);
    }

    @Override
@@ -621,9 +634,9 @@ class GLES20Canvas extends Canvas {
        if ((start | end | (end - start) | (text.length() - end)) < 0) {
            throw new IndexOutOfBoundsException();
        }
        boolean hasShader = setupShader(paint);
        boolean hasModifier = setupModifiers(paint);
        nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint);
        if (hasShader) nResetShader(mRenderer);
        if (hasModifier) nResetModifiers(mRenderer);
    }

    private native void nDrawText(int renderer, String text, int start, int end, float x, float y,
@@ -631,9 +644,9 @@ class GLES20Canvas extends Canvas {

    @Override
    public void drawText(String text, float x, float y, Paint paint) {
        boolean hasShader = setupShader(paint);
        boolean hasModifier = setupModifiers(paint);
        nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags, paint.mNativePaint);
        if (hasShader) nResetShader(mRenderer);
        if (hasModifier) nResetModifiers(mRenderer);
    }

    @Override
@@ -666,15 +679,34 @@ class GLES20Canvas extends Canvas {
        // TODO: Implement
    }

    private boolean setupShader(Paint paint) {
    private boolean setupModifiers(Paint paint) {
        boolean hasModifier = false;

        final Shader shader = paint.getShader();
        if (shader != null) {
            nSetupShader(mRenderer, shader.native_shader);
            hasModifier = true;
        }

        final ColorFilter filter = paint.getColorFilter();
        if (filter != null) {
            nSetupColorFilter(mRenderer, filter.nativeColorFilter);
            hasModifier = true;
        }

        return hasModifier;
    }
    
    private boolean setupColorFilter(Paint paint) {
        final ColorFilter filter = paint.getColorFilter();
        if (filter != null) {
            nSetupColorFilter(mRenderer, filter.nativeColorFilter);
            return true;
        }
        return false;        
    }
    
    private native void nSetupShader(int renderer, int shader);
    private native void nResetShader(int renderer);
    private native void nSetupColorFilter(int renderer, int colorFilter);
    private native void nResetModifiers(int renderer);
}
+46 −19
Original line number Diff line number Diff line
@@ -23,28 +23,38 @@
#include "SkColorMatrixFilter.h"
#include "SkPorterDuff.h"

#include <SkiaColorFilter.h>

namespace android {

using namespace uirenderer;

class SkColorFilterGlue {
public:

    static void finalizer(JNIEnv* env, jobject clazz, SkColorFilter* obj) {
    static void finalizer(JNIEnv* env, jobject clazz, SkColorFilter* obj, SkiaColorFilter* f) {
        delete f;
        obj->safeUnref();
    }

    static SkColorFilter* CreatePorterDuffFilter(JNIEnv* env, jobject,
                            jint srcColor, SkPorterDuff::Mode mode) {
        return SkColorFilter::CreateModeFilter(srcColor,
                                           SkPorterDuff::ToXfermodeMode(mode));
    static SkColorFilter* CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor,
            SkPorterDuff::Mode mode) {
        return SkColorFilter::CreateModeFilter(srcColor, SkPorterDuff::ToXfermodeMode(mode));
    }
 
    static SkColorFilter* CreateLightingFilter(JNIEnv* env, jobject,
                                               jint mul, jint add) {
    static SkiaColorFilter* glCreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor,
            SkPorterDuff::Mode mode) {
        return new SkiaBlendFilter(srcColor, SkPorterDuff::ToXfermodeMode(mode));
    }

    static SkColorFilter* CreateLightingFilter(JNIEnv* env, jobject, jint mul, jint add) {
        return SkColorFilter::CreateLightingFilter(mul, add);
    }
    
    static SkColorFilter* CreateColorMatrixFilter(JNIEnv* env, jobject,
                                                  jfloatArray jarray) {
    static SkiaColorFilter* glCreateLightingFilter(JNIEnv* env, jobject, jint mul, jint add) {
        return new SkiaLightingFilter(mul, add);
    }

    static SkColorFilter* CreateColorMatrixFilter(JNIEnv* env, jobject, jfloatArray jarray) {
        AutoJavaFloatArray autoArray(env, jarray, 20);
        const float* src = autoArray.ptr();

@@ -59,25 +69,43 @@ public:
#endif
    }

    static SkiaColorFilter* glCreateColorMatrixFilter(JNIEnv* env, jobject, jfloatArray jarray) {
        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 new SkiaColorMatrixFilter(colorMatrix, colorVector);
    }
};

static JNINativeMethod colorfilter_methods[] = {
    {"finalizer", "(I)V", (void*) SkColorFilterGlue::finalizer}
    {"finalizer", "(II)V", (void*) SkColorFilterGlue::finalizer}
};

static JNINativeMethod porterduff_methods[] = {
    {"native_CreatePorterDuffFilter","(II)I",
        (void*) SkColorFilterGlue::CreatePorterDuffFilter}
    { "native_CreatePorterDuffFilter", "(II)I", (void*) SkColorFilterGlue::CreatePorterDuffFilter   },
    { "nCreatePorterDuffFilter",       "(II)I", (void*) SkColorFilterGlue::glCreatePorterDuffFilter }
};

static JNINativeMethod lighting_methods[] = {
    {"native_CreateLightingFilter","(II)I",
        (void*) SkColorFilterGlue::CreateLightingFilter}
    { "native_CreateLightingFilter", "(II)I", (void*) SkColorFilterGlue::CreateLightingFilter   },
    { "nCreateLightingFilter",       "(II)I", (void*) SkColorFilterGlue::glCreateLightingFilter },
};

static JNINativeMethod colormatrix_methods[] = {
    {"nativeColorMatrixFilter","([F)I",
        (void*) SkColorFilterGlue::CreateColorMatrixFilter}
    { "nativeColorMatrixFilter", "([F)I", (void*) SkColorFilterGlue::CreateColorMatrixFilter   },
    { "nColorMatrixFilter",      "([F)I", (void*) SkColorFilterGlue::glCreateColorMatrixFilter }
};

#define REG(env, name, array) \
@@ -85,7 +113,6 @@ static JNINativeMethod colormatrix_methods[] = {
                                                    SK_ARRAY_COUNT(array));  \
    if (result < 0) return result


int register_android_graphics_ColorFilter(JNIEnv* env) {
    int result;
    
+11 −3
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include <OpenGLRenderer.h>
#include <SkiaShader.h>
#include <SkiaColorFilter.h>
#include <Rect.h>
#include <ui/Rect.h>

@@ -228,12 +229,13 @@ static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
}

// ----------------------------------------------------------------------------
// Shaders
// Shaders and color filters
// ----------------------------------------------------------------------------

static void android_view_GLES20Canvas_resetShader(JNIEnv* env, jobject canvas,
static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer) {
    renderer->resetShader();
    renderer->resetColorFilter();
}

static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas,
@@ -241,6 +243,11 @@ static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas,
    renderer->setupShader(shader);
}

static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, SkiaColorFilter* filter) {
    renderer->setupColorFilter(filter);
}

// ----------------------------------------------------------------------------
// Text
// ----------------------------------------------------------------------------
@@ -311,8 +318,9 @@ static JNINativeMethod gMethods[] = {
    {   "nDrawColor",         "(III)V",          (void*) android_view_GLES20Canvas_drawColor },
    {   "nDrawRect",          "(IFFFFI)V",       (void*) android_view_GLES20Canvas_drawRect },

    {   "nResetShader",       "(I)V",            (void*) android_view_GLES20Canvas_resetShader },
    {   "nResetModifiers",    "(I)V",            (void*) android_view_GLES20Canvas_resetModifiers },
    {   "nSetupShader",       "(II)V",           (void*) android_view_GLES20Canvas_setupShader },
    {   "nSetupColorFilter",  "(II)V",           (void*) android_view_GLES20Canvas_setupColorFilter },

    {   "nDrawText",          "(I[CIIFFII)V",    (void*) android_view_GLES20Canvas_drawTextArray },
    {   "nDrawText",          "(ILjava/lang/String;IIFFII)V",
+12 −4
Original line number Diff line number Diff line
@@ -23,12 +23,20 @@ package android.graphics;


public class ColorFilter {
    int native_instance;

    /**
     * @hide
     */
    public int nativeColorFilter;

    protected void finalize() throws Throwable {
        finalizer(native_instance);
        try {
            super.finalize();
        } finally {
            finalizer(native_instance, nativeColorFilter);
        }
    }

    private static native void finalizer(int native_instance);

    int native_instance;
    private static native void finalizer(int native_instance, int nativeColorFilter);
}
+5 −1
Original line number Diff line number Diff line
@@ -25,7 +25,9 @@ public class ColorMatrixColorFilter extends ColorFilter {
     *               is constructed will not be reflected in the filter.
     */
    public ColorMatrixColorFilter(ColorMatrix matrix) {
        native_instance = nativeColorMatrixFilter(matrix.getArray());
        final float[] colorMatrix = matrix.getArray();
        native_instance = nativeColorMatrixFilter(colorMatrix);
        nativeColorFilter = nColorMatrixFilter(colorMatrix);
    }

    /**
@@ -40,7 +42,9 @@ public class ColorMatrixColorFilter extends ColorFilter {
            throw new ArrayIndexOutOfBoundsException();
        }
        native_instance = nativeColorMatrixFilter(array);
        nativeColorFilter = nColorMatrixFilter(array);
    }

    private static native int nativeColorMatrixFilter(float[] array);
    private static native int nColorMatrixFilter(float[] array);
}
Loading