blob: bd3b18d4e2eccb9e7faabdddae4e68b032cd9666 [file] [log] [blame]
Romain Guye4d01122010-06-16 18:44:05 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "jni.h"
18#include <nativehelper/JNIHelp.h>
19#include <android_runtime/AndroidRuntime.h>
20
Romain Guyce0537b2010-06-29 21:05:21 -070021#include <SkBitmap.h>
Romain Guyc7d53492010-06-25 13:41:57 -070022#include <SkCanvas.h>
Romain Guyf6a11b82010-06-23 17:47:49 -070023#include <SkMatrix.h>
Romain Guyc7d53492010-06-25 13:41:57 -070024#include <SkPaint.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070025#include <SkXfermode.h>
Romain Guye4d01122010-06-16 18:44:05 -070026
Romain Guy85bf02f2010-06-22 13:11:24 -070027#include <OpenGLRenderer.h>
Romain Guy9d5316e2010-06-24 19:30:36 -070028#include <Rect.h>
29#include <ui/Rect.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070030
Romain Guye4d01122010-06-16 18:44:05 -070031namespace android {
32
Romain Guy9d5316e2010-06-24 19:30:36 -070033using namespace uirenderer;
34
35// ----------------------------------------------------------------------------
36// Java APIs
37// ----------------------------------------------------------------------------
38
39static struct {
Romain Guy7ae7ac42010-06-25 13:46:18 -070040 jclass clazz;
41 jmethodID set;
Romain Guy9d5316e2010-06-24 19:30:36 -070042} gRectClassInfo;
43
Romain Guye4d01122010-06-16 18:44:05 -070044// ----------------------------------------------------------------------------
45// Constructors
46// ----------------------------------------------------------------------------
47
Romain Guyce0537b2010-06-29 21:05:21 -070048static OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject canvas) {
Romain Guy85bf02f2010-06-22 13:11:24 -070049 return new OpenGLRenderer;
Romain Guye4d01122010-06-16 18:44:05 -070050}
51
Romain Guyce0537b2010-06-29 21:05:21 -070052static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070053 OpenGLRenderer* renderer) {
54 delete renderer;
Romain Guye4d01122010-06-16 18:44:05 -070055}
56
57// ----------------------------------------------------------------------------
58// Setup
59// ----------------------------------------------------------------------------
60
Romain Guyce0537b2010-06-29 21:05:21 -070061static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070062 OpenGLRenderer* renderer, jint width, jint height) {
63 renderer->setViewport(width, height);
Romain Guye4d01122010-06-16 18:44:05 -070064}
65
Romain Guyce0537b2010-06-29 21:05:21 -070066static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070067 OpenGLRenderer* renderer) {
68 renderer->prepare();
Romain Guye4d01122010-06-16 18:44:05 -070069}
70
71// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -070072// State
73// ----------------------------------------------------------------------------
74
Romain Guyce0537b2010-06-29 21:05:21 -070075static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer,
Romain Guybb9524b2010-06-22 18:56:38 -070076 jint flags) {
Romain Guyf6a11b82010-06-23 17:47:49 -070077 return renderer->save(flags);
Romain Guybb9524b2010-06-22 18:56:38 -070078}
79
Romain Guyce0537b2010-06-29 21:05:21 -070080static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070081 OpenGLRenderer* renderer) {
82 return renderer->getSaveCount();
Romain Guybb9524b2010-06-22 18:56:38 -070083}
84
Romain Guyce0537b2010-06-29 21:05:21 -070085static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070086 OpenGLRenderer* renderer) {
87 renderer->restore();
Romain Guybb9524b2010-06-22 18:56:38 -070088}
89
Romain Guyce0537b2010-06-29 21:05:21 -070090static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070091 OpenGLRenderer* renderer, jint saveCount) {
92 renderer->restoreToCount(saveCount);
Romain Guybb9524b2010-06-22 18:56:38 -070093}
94
95// ----------------------------------------------------------------------------
Romain Guybd6b79b2010-06-26 00:13:53 -070096// Layers
97// ----------------------------------------------------------------------------
98
Romain Guyce0537b2010-06-29 21:05:21 -070099static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject canvas,
Romain Guybd6b79b2010-06-26 00:13:53 -0700100 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
101 SkPaint* paint, jint saveFlags) {
102 return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
103}
104
Romain Guyce0537b2010-06-29 21:05:21 -0700105static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas,
Romain Guybd6b79b2010-06-26 00:13:53 -0700106 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
107 jint alpha, jint saveFlags) {
108 return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
109}
110
111// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -0700112// Clipping
113// ----------------------------------------------------------------------------
114
Romain Guyce0537b2010-06-29 21:05:21 -0700115static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject canvas,
Romain Guyc7d53492010-06-25 13:41:57 -0700116 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
117 SkCanvas::EdgeType edge) {
118 return renderer->quickReject(left, top, right, bottom);
119}
120
Romain Guyce0537b2010-06-29 21:05:21 -0700121static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700122 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
123 return renderer->clipRect(left, top, right, bottom);
Romain Guybb9524b2010-06-22 18:56:38 -0700124}
125
Romain Guyce0537b2010-06-29 21:05:21 -0700126static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700127 OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom) {
128 return renderer->clipRect(float(left), float(top), float(right), float(bottom));
129}
Romain Guybb9524b2010-06-22 18:56:38 -0700130
Romain Guyce0537b2010-06-29 21:05:21 -0700131static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas,
Romain Guy9d5316e2010-06-24 19:30:36 -0700132 OpenGLRenderer* renderer, jobject rect) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700133 const android::uirenderer::Rect& bounds(renderer->getClipBounds());
Romain Guy9d5316e2010-06-24 19:30:36 -0700134
Romain Guy7ae7ac42010-06-25 13:46:18 -0700135 env->CallVoidMethod(rect, gRectClassInfo.set,
136 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
Romain Guy9d5316e2010-06-24 19:30:36 -0700137
Romain Guy7ae7ac42010-06-25 13:46:18 -0700138 return !bounds.isEmpty();
Romain Guy9d5316e2010-06-24 19:30:36 -0700139}
140
Romain Guyf6a11b82010-06-23 17:47:49 -0700141// ----------------------------------------------------------------------------
142// Transforms
143// ----------------------------------------------------------------------------
144
Romain Guyce0537b2010-06-29 21:05:21 -0700145static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700146 OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700147 renderer->translate(dx, dy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700148}
149
Romain Guyce0537b2010-06-29 21:05:21 -0700150static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700151 OpenGLRenderer* renderer, jfloat degrees) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700152 renderer->rotate(degrees);
Romain Guyf6a11b82010-06-23 17:47:49 -0700153}
154
Romain Guyce0537b2010-06-29 21:05:21 -0700155static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700156 OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700157 renderer->scale(sx, sy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700158}
159
Romain Guyce0537b2010-06-29 21:05:21 -0700160static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700161 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700162 renderer->setMatrix(matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700163}
164
Romain Guyce0537b2010-06-29 21:05:21 -0700165static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700166 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700167 renderer->getMatrix(matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700168}
169
Romain Guyce0537b2010-06-29 21:05:21 -0700170static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700171 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700172 renderer->concatMatrix(matrix);
Romain Guybb9524b2010-06-22 18:56:38 -0700173}
174
175// ----------------------------------------------------------------------------
176// Drawing
Romain Guy85bf02f2010-06-22 13:11:24 -0700177// ----------------------------------------------------------------------------
178
Romain Guyce0537b2010-06-29 21:05:21 -0700179static 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 }
Romain Guy85bf02f2010-06-22 13:11:24 -0700192}
193
Romain Guyce0537b2010-06-29 21:05:21 -0700194static 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 bitmapDenstiy, jint canvasDensity, jint screenDensity) {
200 // TODO: Implement!
201 LOGE("Not implemented: drawBitmap(IIFFFFFFFFIIIII)V");
202}
203
204static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject canvas,
205 OpenGLRenderer* renderer, jint color, SkXfermode::Mode mode) {
206 renderer->drawColor(color, mode);
207}
208
209static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
Romain Guyc7d53492010-06-25 13:41:57 -0700210 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
211 SkPaint* paint) {
212 renderer->drawRect(left, top, right, bottom, paint);
213}
214
Romain Guy85bf02f2010-06-22 13:11:24 -0700215// ----------------------------------------------------------------------------
Romain Guye4d01122010-06-16 18:44:05 -0700216// JNI Glue
217// ----------------------------------------------------------------------------
218
219const char* const kClassPathName = "android/view/GLES20Canvas";
220
221static JNINativeMethod gMethods[] = {
Romain Guyce0537b2010-06-29 21:05:21 -0700222 { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer },
223 { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer },
224 { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport },
225 { "nPrepare", "(I)V", (void*) android_view_GLES20Canvas_prepare },
Romain Guy85bf02f2010-06-22 13:11:24 -0700226
Romain Guyce0537b2010-06-29 21:05:21 -0700227 { "nSave", "(II)I", (void*) android_view_GLES20Canvas_save },
228 { "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore },
229 { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Canvas_restoreToCount },
230 { "nGetSaveCount", "(I)I", (void*) android_view_GLES20Canvas_getSaveCount },
Romain Guybb9524b2010-06-22 18:56:38 -0700231
Romain Guyce0537b2010-06-29 21:05:21 -0700232 { "nSaveLayer", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayer },
233 { "nSaveLayerAlpha", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha },
Romain Guyc7d53492010-06-25 13:41:57 -0700234
Romain Guyce0537b2010-06-29 21:05:21 -0700235 { "nQuickReject", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_quickReject },
236 { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Canvas_clipRectF },
237 { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Canvas_clipRect },
Romain Guyc7d53492010-06-25 13:41:57 -0700238
Romain Guyce0537b2010-06-29 21:05:21 -0700239 { "nTranslate", "(IFF)V", (void*) android_view_GLES20Canvas_translate },
240 { "nRotate", "(IF)V", (void*) android_view_GLES20Canvas_rotate },
241 { "nScale", "(IFF)V", (void*) android_view_GLES20Canvas_scale },
Romain Guyc7d53492010-06-25 13:41:57 -0700242
Romain Guyce0537b2010-06-29 21:05:21 -0700243 { "nSetMatrix", "(II)V", (void*) android_view_GLES20Canvas_setMatrix },
244 { "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix },
245 { "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix },
Romain Guybd6b79b2010-06-26 00:13:53 -0700246
Romain Guyce0537b2010-06-29 21:05:21 -0700247 { "nDrawBitmap", "(IIFFIIII)V", (void*) android_view_GLES20Canvas_drawBitmap },
248 { "nDrawBitmap", "(IIFFFFFFFFIIIII)V", (void*) android_view_GLES20Canvas_drawBitmapRect },
249 { "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
250 { "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
Romain Guybb9524b2010-06-22 18:56:38 -0700251
Romain Guy9d5316e2010-06-24 19:30:36 -0700252 { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z",
Romain Guyce0537b2010-06-29 21:05:21 -0700253 (void*) android_view_GLES20Canvas_getClipBounds },
Romain Guye4d01122010-06-16 18:44:05 -0700254};
255
Romain Guy9d5316e2010-06-24 19:30:36 -0700256#define FIND_CLASS(var, className) \
257 var = env->FindClass(className); \
258 LOG_FATAL_IF(! var, "Unable to find class " className); \
259 var = jclass(env->NewGlobalRef(var));
260
261#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
262 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
263 LOG_FATAL_IF(! var, "Unable to find method " methodName);
264
Romain Guye4d01122010-06-16 18:44:05 -0700265int register_android_view_GLES20Canvas(JNIEnv* env) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700266 FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
267 GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");
Romain Guy9d5316e2010-06-24 19:30:36 -0700268
Romain Guye4d01122010-06-16 18:44:05 -0700269 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
270}
271
272};