19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* libs/android_runtime/android/graphics/ColorFilter.cpp
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2006, The Android Open Source Project
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License.
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License.
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkColorFilter.h"
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkColorMatrixFilter.h"
2447c0d4eaa926d979c5ea366934750526c20af8ffMike Reed#include "SkPorterDuff.h"
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy#include <SkiaColorFilter.h>
27ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase#include <Caches.h>
28db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guyusing namespace uirenderer;
32db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass SkColorFilterGlue {
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
35db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    static void finalizer(JNIEnv* env, jobject clazz, SkColorFilter* obj, SkiaColorFilter* f) {
366062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger        SkSafeUnref(obj);
37ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        // f == NULL when not !USE_OPENGL_RENDERER, so no need to delete outside the ifdef
38ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase#ifdef USE_OPENGL_RENDERER
39ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        if (android::uirenderer::Caches::hasInstance()) {
40ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            android::uirenderer::Caches::getInstance().resourceCache.destructor(f);
41ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        } else {
42ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            delete f;
43ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        }
44ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase#endif
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    static SkiaColorFilter* glCreatePorterDuffFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
48ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            jint srcColor, SkPorterDuff::Mode mode) {
49163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER
50ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        return new SkiaBlendFilter(skFilter, srcColor, SkPorterDuff::ToXfermodeMode(mode));
51163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else
52163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return NULL;
53163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif
54db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    }
55db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
56ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    static SkiaColorFilter* glCreateLightingFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
57ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            jint mul, jint add) {
58163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER
59ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        return new SkiaLightingFilter(skFilter, mul, add);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
61163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return NULL;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
64db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
65ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    static SkiaColorFilter* glCreateColorMatrixFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
66ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase            jfloatArray jarray) {
67163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER
68db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        AutoJavaFloatArray autoArray(env, jarray, 20);
69db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        const float* src = autoArray.ptr();
70db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
71db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        float* colorMatrix = new float[16];
72db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        memcpy(colorMatrix, src, 4 * sizeof(float));
73db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        memcpy(&colorMatrix[4], &src[5], 4 * sizeof(float));
74db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        memcpy(&colorMatrix[8], &src[10], 4 * sizeof(float));
75db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        memcpy(&colorMatrix[12], &src[15], 4 * sizeof(float));
76db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
77db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        float* colorVector = new float[4];
78db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        colorVector[0] = src[4];
79db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        colorVector[1] = src[9];
80db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        colorVector[2] = src[14];
81db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy        colorVector[3] = src[19];
82db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy
83ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase        return new SkiaColorMatrixFilter(skFilter, colorMatrix, colorVector);
84163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else
85163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return NULL;
86163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif
87163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    }
88163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
89163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    static SkColorFilter* CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor,
90163935113919a184122b8b3bd672ef08c8df65dcRomain Guy            SkPorterDuff::Mode mode) {
91163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return SkColorFilter::CreateModeFilter(srcColor, SkPorterDuff::ToXfermodeMode(mode));
92163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    }
93163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
94163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    static SkColorFilter* CreateLightingFilter(JNIEnv* env, jobject, jint mul, jint add) {
95163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return SkColorFilter::CreateLightingFilter(mul, add);
96163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    }
97163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
98163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    static SkColorFilter* CreateColorMatrixFilter(JNIEnv* env, jobject, jfloatArray jarray) {
99163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        AutoJavaFloatArray autoArray(env, jarray, 20);
100163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        const float* src = autoArray.ptr();
101163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
102163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef SK_SCALAR_IS_FIXED
103163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        SkFixed array[20];
104163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        for (int i = 0; i < 20; i++) {
105163935113919a184122b8b3bd672ef08c8df65dcRomain Guy            array[i] = SkFloatToScalar(src[i]);
106163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        }
107163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return new SkColorMatrixFilter(array);
108163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else
109163935113919a184122b8b3bd672ef08c8df65dcRomain Guy        return new SkColorMatrixFilter(src);
110163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif
111db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod colorfilter_methods[] = {
115db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    {"finalizer", "(II)V", (void*) SkColorFilterGlue::finalizer}
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod porterduff_methods[] = {
119db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    { "native_CreatePorterDuffFilter", "(II)I", (void*) SkColorFilterGlue::CreatePorterDuffFilter   },
120ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    { "nCreatePorterDuffFilter",       "(III)I", (void*) SkColorFilterGlue::glCreatePorterDuffFilter }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod lighting_methods[] = {
124db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    { "native_CreateLightingFilter", "(II)I", (void*) SkColorFilterGlue::CreateLightingFilter   },
125ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    { "nCreateLightingFilter",       "(III)I", (void*) SkColorFilterGlue::glCreateLightingFilter },
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod colormatrix_methods[] = {
129db1938e0e6ef816e228c815adccebd5cb05f2aa8Romain Guy    { "nativeColorMatrixFilter", "([F)I", (void*) SkColorFilterGlue::CreateColorMatrixFilter   },
130ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase    { "nColorMatrixFilter",      "(I[F)I", (void*) SkColorFilterGlue::glCreateColorMatrixFilter }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define REG(env, name, array) \
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result = android::AndroidRuntime::registerNativeMethods(env, name, array, \
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    SK_ARRAY_COUNT(array));  \
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (result < 0) return result
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_ColorFilter(JNIEnv* env) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    REG(env, "android/graphics/ColorFilter", colorfilter_methods);
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    REG(env, "android/graphics/PorterDuffColorFilter", porterduff_methods);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    REG(env, "android/graphics/LightingColorFilter", lighting_methods);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    REG(env, "android/graphics/ColorMatrixColorFilter", colormatrix_methods);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
150