android_view_GLES20Canvas.cpp revision 8ba548f81d1ab5f1750cbf86098c4a14e0b8bead
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2010 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "jni.h"
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <nativehelper/JNIHelp.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <SkBitmap.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <SkCanvas.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <SkMatrix.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <SkPaint.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <SkXfermode.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <OpenGLRenderer.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <Rect.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace uirenderer;
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Java APIs
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic struct {
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    jclass clazz;
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    jmethodID set;
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} gRectClassInfo;
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Constructors
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject canvas) {
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return new OpenGLRenderer;
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject canvas,
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer) {
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    delete renderer;
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Setup
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject canvas,
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer, jint width, jint height) {
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    renderer->setViewport(width, height);
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas,
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer) {
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    renderer->prepare();
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// State
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic jint android_view_GLES20Canvas_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer,
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        jint flags) {
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return renderer->save(flags);
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject canvas,
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer) {
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return renderer->getSaveCount();
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void android_view_GLES20Canvas_restore(JNIEnv* env, jobject canvas,
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer) {
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    renderer->restore();
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas,
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer, jint saveCount) {
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    renderer->restoreToCount(saveCount);
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Layers
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject canvas,
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SkPaint* paint, jint saveFlags) {
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas,
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        jint alpha, jint saveFlags) {
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Clipping
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject canvas,
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SkCanvas::EdgeType edge) {
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return renderer->quickReject(left, top, right, bottom);
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject canvas,
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return renderer->clipRect(left, top, right, bottom);
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject canvas,
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom) {
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return renderer->clipRect(float(left), float(top), float(right), float(bottom));
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas,
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        OpenGLRenderer* renderer, jobject rect) {
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const android::uirenderer::Rect& bounds(renderer->getClipBounds());
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    env->CallVoidMethod(rect, gRectClassInfo.set,
136            int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
137
138    return !bounds.isEmpty();
139}
140
141// ----------------------------------------------------------------------------
142// Transforms
143// ----------------------------------------------------------------------------
144
145static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject canvas,
146        OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
147    renderer->translate(dx, dy);
148}
149
150static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject canvas,
151        OpenGLRenderer* renderer, jfloat degrees) {
152    renderer->rotate(degrees);
153}
154
155static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject canvas,
156        OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
157    renderer->scale(sx, sy);
158}
159
160static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject canvas,
161        OpenGLRenderer* renderer, SkMatrix* matrix) {
162    renderer->setMatrix(matrix);
163}
164
165static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject canvas,
166        OpenGLRenderer* renderer, SkMatrix* matrix) {
167    renderer->getMatrix(matrix);
168}
169
170static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas,
171        OpenGLRenderer* renderer, SkMatrix* matrix) {
172    renderer->concatMatrix(matrix);
173}
174
175// ----------------------------------------------------------------------------
176// Drawing
177// ----------------------------------------------------------------------------
178
179static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject canvas,
180        OpenGLRenderer* renderer, SkBitmap* bitmap, float left, float top,
181        SkPaint* paint, jint bitmapDensity, jint canvasDensity,jint screenDensity) {
182    if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) {
183        renderer->drawBitmap(bitmap, left, top, paint);
184    } else {
185        renderer->save(0);
186        const float scale = canvasDensity / float(bitmapDensity);
187        renderer->translate(left, top);
188        renderer->scale(scale, scale);
189        renderer->drawBitmap(bitmap, left, top, paint);
190        renderer->restore();
191    }
192}
193
194static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject canvas,
195        OpenGLRenderer* renderer, SkBitmap* bitmap,
196        float srcLeft, float srcTop, float srcRight, float srcBottom,
197        float dstLeft, float dstTop, float dstRight, float dstBottom,
198        SkMatrix* matrix, SkPaint* paint,
199        jint bitmapDensity, jint canvasDensity, jint screenDensity) {
200    if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) {
201        renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
202                dstLeft, dstTop, dstRight, dstBottom, matrix, paint);
203    } else {
204
205    }
206}
207
208static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject canvas,
209        OpenGLRenderer* renderer, jint color, SkXfermode::Mode mode) {
210    renderer->drawColor(color, mode);
211}
212
213static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
214        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
215        SkPaint* paint) {
216    renderer->drawRect(left, top, right, bottom, paint);
217}
218
219// ----------------------------------------------------------------------------
220// JNI Glue
221// ----------------------------------------------------------------------------
222
223const char* const kClassPathName = "android/view/GLES20Canvas";
224
225static JNINativeMethod gMethods[] = {
226    {   "nCreateRenderer",    "()I",                (void*) android_view_GLES20Canvas_createRenderer },
227    {   "nDestroyRenderer",   "(I)V",               (void*) android_view_GLES20Canvas_destroyRenderer },
228    {   "nSetViewport",       "(III)V",             (void*) android_view_GLES20Canvas_setViewport },
229    {   "nPrepare",           "(I)V",               (void*) android_view_GLES20Canvas_prepare },
230
231    {   "nSave",              "(II)I",              (void*) android_view_GLES20Canvas_save },
232    {   "nRestore",           "(I)V",               (void*) android_view_GLES20Canvas_restore },
233    {   "nRestoreToCount",    "(II)V",              (void*) android_view_GLES20Canvas_restoreToCount },
234    {   "nGetSaveCount",      "(I)I",               (void*) android_view_GLES20Canvas_getSaveCount },
235
236    {   "nSaveLayer",         "(IFFFFII)I",         (void*) android_view_GLES20Canvas_saveLayer },
237    {   "nSaveLayerAlpha",    "(IFFFFII)I",         (void*) android_view_GLES20Canvas_saveLayerAlpha },
238
239    {   "nQuickReject",       "(IFFFFI)Z",          (void*) android_view_GLES20Canvas_quickReject },
240    {   "nClipRect",          "(IFFFF)Z",           (void*) android_view_GLES20Canvas_clipRectF },
241    {   "nClipRect",          "(IIIII)Z",           (void*) android_view_GLES20Canvas_clipRect },
242
243    {   "nTranslate",         "(IFF)V",             (void*) android_view_GLES20Canvas_translate },
244    {   "nRotate",            "(IF)V",              (void*) android_view_GLES20Canvas_rotate },
245    {   "nScale",             "(IFF)V",             (void*) android_view_GLES20Canvas_scale },
246
247    {   "nSetMatrix",         "(II)V",              (void*) android_view_GLES20Canvas_setMatrix },
248    {   "nGetMatrix",         "(II)V",              (void*) android_view_GLES20Canvas_getMatrix },
249    {   "nConcatMatrix",      "(II)V",              (void*) android_view_GLES20Canvas_concatMatrix },
250
251    {   "nDrawBitmap",        "(IIFFIIII)V",        (void*) android_view_GLES20Canvas_drawBitmap },
252    {   "nDrawBitmap",        "(IIFFFFFFFFIIIII)V", (void*) android_view_GLES20Canvas_drawBitmapRect },
253    {   "nDrawColor",         "(III)V",             (void*) android_view_GLES20Canvas_drawColor },
254    {   "nDrawRect",          "(IFFFFI)V",          (void*) android_view_GLES20Canvas_drawRect },
255
256    {   "nGetClipBounds",     "(ILandroid/graphics/Rect;)Z",
257            (void*) android_view_GLES20Canvas_getClipBounds },
258};
259
260#define FIND_CLASS(var, className) \
261        var = env->FindClass(className); \
262        LOG_FATAL_IF(! var, "Unable to find class " className); \
263        var = jclass(env->NewGlobalRef(var));
264
265#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
266        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
267        LOG_FATAL_IF(! var, "Unable to find method " methodName);
268
269int register_android_view_GLES20Canvas(JNIEnv* env) {
270    FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
271    GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");
272
273    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
274}
275
276};
277