blob: dbf482e6c0dda6903336ef87c98892eef1ab29b2 [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>
Romain Guydeba7852010-07-07 17:54:48 -070020#include <utils/ResourceTypes.h>
Romain Guye4d01122010-06-16 18:44:05 -070021
Romain Guyce0537b2010-06-29 21:05:21 -070022#include <SkBitmap.h>
Romain Guyc7d53492010-06-25 13:41:57 -070023#include <SkCanvas.h>
Romain Guyf6a11b82010-06-23 17:47:49 -070024#include <SkMatrix.h>
Romain Guyc7d53492010-06-25 13:41:57 -070025#include <SkPaint.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070026#include <SkXfermode.h>
Romain Guye4d01122010-06-16 18:44:05 -070027
Romain Guy85bf02f2010-06-22 13:11:24 -070028#include <OpenGLRenderer.h>
Romain Guy9d5316e2010-06-24 19:30:36 -070029#include <Rect.h>
30#include <ui/Rect.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070031
Romain Guye4d01122010-06-16 18:44:05 -070032namespace android {
33
Romain Guy9d5316e2010-06-24 19:30:36 -070034using namespace uirenderer;
35
36// ----------------------------------------------------------------------------
37// Java APIs
38// ----------------------------------------------------------------------------
39
40static struct {
Romain Guy7ae7ac42010-06-25 13:46:18 -070041 jclass clazz;
42 jmethodID set;
Romain Guy9d5316e2010-06-24 19:30:36 -070043} gRectClassInfo;
44
Romain Guye4d01122010-06-16 18:44:05 -070045// ----------------------------------------------------------------------------
46// Constructors
47// ----------------------------------------------------------------------------
48
Romain Guyce0537b2010-06-29 21:05:21 -070049static OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject canvas) {
Romain Guy85bf02f2010-06-22 13:11:24 -070050 return new OpenGLRenderer;
Romain Guye4d01122010-06-16 18:44:05 -070051}
52
Romain Guyce0537b2010-06-29 21:05:21 -070053static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070054 OpenGLRenderer* renderer) {
55 delete renderer;
Romain Guye4d01122010-06-16 18:44:05 -070056}
57
58// ----------------------------------------------------------------------------
59// Setup
60// ----------------------------------------------------------------------------
61
Romain Guyce0537b2010-06-29 21:05:21 -070062static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070063 OpenGLRenderer* renderer, jint width, jint height) {
64 renderer->setViewport(width, height);
Romain Guye4d01122010-06-16 18:44:05 -070065}
66
Romain Guyce0537b2010-06-29 21:05:21 -070067static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070068 OpenGLRenderer* renderer) {
69 renderer->prepare();
Romain Guye4d01122010-06-16 18:44:05 -070070}
71
72// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -070073// State
74// ----------------------------------------------------------------------------
75
Romain Guyce0537b2010-06-29 21:05:21 -070076static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer,
Romain Guybb9524b2010-06-22 18:56:38 -070077 jint flags) {
Romain Guyf6a11b82010-06-23 17:47:49 -070078 return renderer->save(flags);
Romain Guybb9524b2010-06-22 18:56:38 -070079}
80
Romain Guyce0537b2010-06-29 21:05:21 -070081static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070082 OpenGLRenderer* renderer) {
83 return renderer->getSaveCount();
Romain Guybb9524b2010-06-22 18:56:38 -070084}
85
Romain Guyce0537b2010-06-29 21:05:21 -070086static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070087 OpenGLRenderer* renderer) {
88 renderer->restore();
Romain Guybb9524b2010-06-22 18:56:38 -070089}
90
Romain Guyce0537b2010-06-29 21:05:21 -070091static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070092 OpenGLRenderer* renderer, jint saveCount) {
93 renderer->restoreToCount(saveCount);
Romain Guybb9524b2010-06-22 18:56:38 -070094}
95
96// ----------------------------------------------------------------------------
Romain Guybd6b79b2010-06-26 00:13:53 -070097// Layers
98// ----------------------------------------------------------------------------
99
Romain Guyce0537b2010-06-29 21:05:21 -0700100static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject canvas,
Romain Guybd6b79b2010-06-26 00:13:53 -0700101 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
102 SkPaint* paint, jint saveFlags) {
103 return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
104}
105
Romain Guyce0537b2010-06-29 21:05:21 -0700106static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas,
Romain Guybd6b79b2010-06-26 00:13:53 -0700107 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
108 jint alpha, jint saveFlags) {
109 return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
110}
111
112// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -0700113// Clipping
114// ----------------------------------------------------------------------------
115
Romain Guyce0537b2010-06-29 21:05:21 -0700116static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject canvas,
Romain Guyc7d53492010-06-25 13:41:57 -0700117 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
118 SkCanvas::EdgeType edge) {
119 return renderer->quickReject(left, top, right, bottom);
120}
121
Romain Guyce0537b2010-06-29 21:05:21 -0700122static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700123 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
124 return renderer->clipRect(left, top, right, bottom);
Romain Guybb9524b2010-06-22 18:56:38 -0700125}
126
Romain Guyce0537b2010-06-29 21:05:21 -0700127static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700128 OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom) {
129 return renderer->clipRect(float(left), float(top), float(right), float(bottom));
130}
Romain Guybb9524b2010-06-22 18:56:38 -0700131
Romain Guyce0537b2010-06-29 21:05:21 -0700132static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas,
Romain Guy9d5316e2010-06-24 19:30:36 -0700133 OpenGLRenderer* renderer, jobject rect) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700134 const android::uirenderer::Rect& bounds(renderer->getClipBounds());
Romain Guy9d5316e2010-06-24 19:30:36 -0700135
Romain Guy7ae7ac42010-06-25 13:46:18 -0700136 env->CallVoidMethod(rect, gRectClassInfo.set,
137 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
Romain Guy9d5316e2010-06-24 19:30:36 -0700138
Romain Guy7ae7ac42010-06-25 13:46:18 -0700139 return !bounds.isEmpty();
Romain Guy9d5316e2010-06-24 19:30:36 -0700140}
141
Romain Guyf6a11b82010-06-23 17:47:49 -0700142// ----------------------------------------------------------------------------
143// Transforms
144// ----------------------------------------------------------------------------
145
Romain Guyce0537b2010-06-29 21:05:21 -0700146static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700147 OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700148 renderer->translate(dx, dy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700149}
150
Romain Guyce0537b2010-06-29 21:05:21 -0700151static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700152 OpenGLRenderer* renderer, jfloat degrees) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700153 renderer->rotate(degrees);
Romain Guyf6a11b82010-06-23 17:47:49 -0700154}
155
Romain Guyce0537b2010-06-29 21:05:21 -0700156static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700157 OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700158 renderer->scale(sx, sy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700159}
160
Romain Guyce0537b2010-06-29 21:05:21 -0700161static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700162 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700163 renderer->setMatrix(matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700164}
165
Romain Guyce0537b2010-06-29 21:05:21 -0700166static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700167 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700168 renderer->getMatrix(matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700169}
170
Romain Guyce0537b2010-06-29 21:05:21 -0700171static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700172 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700173 renderer->concatMatrix(matrix);
Romain Guybb9524b2010-06-22 18:56:38 -0700174}
175
176// ----------------------------------------------------------------------------
177// Drawing
Romain Guy85bf02f2010-06-22 13:11:24 -0700178// ----------------------------------------------------------------------------
179
Romain Guyce0537b2010-06-29 21:05:21 -0700180static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject canvas,
Romain Guydbd77cd2010-07-09 10:36:05 -0700181 OpenGLRenderer* renderer, SkBitmap* bitmap, float left, float top, SkPaint* paint) {
182 renderer->drawBitmap(bitmap, left, top, paint);
Romain Guy85bf02f2010-06-22 13:11:24 -0700183}
184
Romain Guyce0537b2010-06-29 21:05:21 -0700185static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject canvas,
186 OpenGLRenderer* renderer, SkBitmap* bitmap,
187 float srcLeft, float srcTop, float srcRight, float srcBottom,
Romain Guydbd77cd2010-07-09 10:36:05 -0700188 float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) {
189 renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
190 dstLeft, dstTop, dstRight, dstBottom, paint);
Romain Guyf86ef572010-07-01 11:05:42 -0700191}
Romain Guy8ba548f2010-06-30 19:21:21 -0700192
Romain Guyf86ef572010-07-01 11:05:42 -0700193static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject canvas,
Romain Guydbd77cd2010-07-09 10:36:05 -0700194 OpenGLRenderer* renderer, SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
195 renderer->drawBitmap(bitmap, matrix, paint);
Romain Guyce0537b2010-06-29 21:05:21 -0700196}
197
Romain Guydeba7852010-07-07 17:54:48 -0700198static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas,
199 OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray chunks,
Romain Guydbd77cd2010-07-09 10:36:05 -0700200 float left, float top, float right, float bottom, SkPaint* paint) {
Romain Guydeba7852010-07-07 17:54:48 -0700201
202 jbyte* storage = env->GetByteArrayElements(chunks, NULL);
203 Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage);
204 Res_png_9patch::deserialize(patch);
205
Romain Guydbd77cd2010-07-09 10:36:05 -0700206 renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
Romain Guydeba7852010-07-07 17:54:48 -0700207
208 // TODO: make sure that 0 is correct for the flags
209 env->ReleaseByteArrayElements(chunks, storage, 0);
210}
211
Romain Guyce0537b2010-06-29 21:05:21 -0700212static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject canvas,
213 OpenGLRenderer* renderer, jint color, SkXfermode::Mode mode) {
214 renderer->drawColor(color, mode);
215}
216
217static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
Romain Guyc7d53492010-06-25 13:41:57 -0700218 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
219 SkPaint* paint) {
220 renderer->drawRect(left, top, right, bottom, paint);
221}
222
Romain Guy85bf02f2010-06-22 13:11:24 -0700223// ----------------------------------------------------------------------------
Romain Guyd27977d2010-07-14 19:18:51 -0700224// Shaders
225// ----------------------------------------------------------------------------
226
227static void android_view_GLES20Canvas_resetShader(JNIEnv* env, jobject canvas,
228 OpenGLRenderer* renderer) {
229 renderer->resetShader();
230}
231
232static void android_view_GLES20Canvas_setupBitmapShader(JNIEnv* env, jobject canvas,
233 OpenGLRenderer* renderer, SkShader* shader, SkBitmap* bitmap,
234 SkShader::TileMode tileX, SkShader::TileMode tileY, SkMatrix* matrix) {
235 renderer->setupBitmapShader(bitmap, tileX, tileY, matrix,
236 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
237}
238
239// ----------------------------------------------------------------------------
Romain Guye4d01122010-06-16 18:44:05 -0700240// JNI Glue
241// ----------------------------------------------------------------------------
242
243const char* const kClassPathName = "android/view/GLES20Canvas";
244
245static JNINativeMethod gMethods[] = {
Romain Guydbd77cd2010-07-09 10:36:05 -0700246 { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer },
247 { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer },
248 { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport },
249 { "nPrepare", "(I)V", (void*) android_view_GLES20Canvas_prepare },
Romain Guy85bf02f2010-06-22 13:11:24 -0700250
Romain Guydbd77cd2010-07-09 10:36:05 -0700251 { "nSave", "(II)I", (void*) android_view_GLES20Canvas_save },
252 { "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore },
253 { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Canvas_restoreToCount },
254 { "nGetSaveCount", "(I)I", (void*) android_view_GLES20Canvas_getSaveCount },
Romain Guybb9524b2010-06-22 18:56:38 -0700255
Romain Guydbd77cd2010-07-09 10:36:05 -0700256 { "nSaveLayer", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayer },
257 { "nSaveLayerAlpha", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha },
Romain Guyc7d53492010-06-25 13:41:57 -0700258
Romain Guydbd77cd2010-07-09 10:36:05 -0700259 { "nQuickReject", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_quickReject },
260 { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Canvas_clipRectF },
261 { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Canvas_clipRect },
Romain Guyc7d53492010-06-25 13:41:57 -0700262
Romain Guydbd77cd2010-07-09 10:36:05 -0700263 { "nTranslate", "(IFF)V", (void*) android_view_GLES20Canvas_translate },
264 { "nRotate", "(IF)V", (void*) android_view_GLES20Canvas_rotate },
265 { "nScale", "(IFF)V", (void*) android_view_GLES20Canvas_scale },
Romain Guyc7d53492010-06-25 13:41:57 -0700266
Romain Guydbd77cd2010-07-09 10:36:05 -0700267 { "nSetMatrix", "(II)V", (void*) android_view_GLES20Canvas_setMatrix },
268 { "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix },
269 { "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix },
Romain Guybd6b79b2010-06-26 00:13:53 -0700270
Romain Guydbd77cd2010-07-09 10:36:05 -0700271 { "nDrawBitmap", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawBitmap },
272 { "nDrawBitmap", "(IIFFFFFFFFI)V", (void*) android_view_GLES20Canvas_drawBitmapRect },
273 { "nDrawBitmap", "(IIII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
274 { "nDrawPatch", "(II[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch },
275 { "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
276 { "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
Romain Guybb9524b2010-06-22 18:56:38 -0700277
Romain Guyd27977d2010-07-14 19:18:51 -0700278 { "nResetShader", "(I)V", (void*) android_view_GLES20Canvas_resetShader },
279 { "nSetupBitmapShader", "(IIIIII)V", (void*) android_view_GLES20Canvas_setupBitmapShader },
280
Romain Guy9d5316e2010-06-24 19:30:36 -0700281 { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z",
Romain Guyce0537b2010-06-29 21:05:21 -0700282 (void*) android_view_GLES20Canvas_getClipBounds },
Romain Guye4d01122010-06-16 18:44:05 -0700283};
284
Romain Guy9d5316e2010-06-24 19:30:36 -0700285#define FIND_CLASS(var, className) \
286 var = env->FindClass(className); \
287 LOG_FATAL_IF(! var, "Unable to find class " className); \
288 var = jclass(env->NewGlobalRef(var));
289
290#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
291 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
292 LOG_FATAL_IF(! var, "Unable to find method " methodName);
293
Romain Guye4d01122010-06-16 18:44:05 -0700294int register_android_view_GLES20Canvas(JNIEnv* env) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700295 FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
296 GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");
Romain Guy9d5316e2010-06-24 19:30:36 -0700297
Romain Guye4d01122010-06-16 18:44:05 -0700298 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
299}
300
301};