android_view_GLES20Canvas.cpp revision bd6b79b40247aea7bfe13d0831c6c0472df6c636
1/*
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
21#include <SkCanvas.h>
22#include <SkMatrix.h>
23#include <SkPaint.h>
24#include <SkXfermode.h>
25
26#include <OpenGLRenderer.h>
27#include <Rect.h>
28#include <ui/Rect.h>
29
30namespace android {
31
32using namespace uirenderer;
33
34// ----------------------------------------------------------------------------
35// Java APIs
36// ----------------------------------------------------------------------------
37
38static struct {
39    jclass clazz;
40    jmethodID set;
41} gRectClassInfo;
42
43// ----------------------------------------------------------------------------
44// Constructors
45// ----------------------------------------------------------------------------
46
47static OpenGLRenderer* android_view_GLES20Renderer_createRenderer(JNIEnv* env, jobject canvas) {
48    return new OpenGLRenderer;
49}
50
51static void android_view_GLES20Renderer_destroyRenderer(JNIEnv* env, jobject canvas,
52        OpenGLRenderer* renderer) {
53    delete renderer;
54}
55
56// ----------------------------------------------------------------------------
57// Setup
58// ----------------------------------------------------------------------------
59
60static void android_view_GLES20Renderer_setViewport(JNIEnv* env, jobject canvas,
61        OpenGLRenderer* renderer, jint width, jint height) {
62    renderer->setViewport(width, height);
63}
64
65static void android_view_GLES20Renderer_prepare(JNIEnv* env, jobject canvas,
66        OpenGLRenderer* renderer) {
67    renderer->prepare();
68}
69
70// ----------------------------------------------------------------------------
71// State
72// ----------------------------------------------------------------------------
73
74static jint android_view_GLES20Renderer_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer,
75        jint flags) {
76    return renderer->save(flags);
77}
78
79static jint android_view_GLES20Renderer_getSaveCount(JNIEnv* env, jobject canvas,
80        OpenGLRenderer* renderer) {
81    return renderer->getSaveCount();
82}
83
84static void android_view_GLES20Renderer_restore(JNIEnv* env, jobject canvas,
85        OpenGLRenderer* renderer) {
86    renderer->restore();
87}
88
89static void android_view_GLES20Renderer_restoreToCount(JNIEnv* env, jobject canvas,
90        OpenGLRenderer* renderer, jint saveCount) {
91    renderer->restoreToCount(saveCount);
92}
93
94// ----------------------------------------------------------------------------
95// Layers
96// ----------------------------------------------------------------------------
97
98static jint android_view_GLES20Renderer_saveLayer(JNIEnv* env, jobject canvas,
99        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
100        SkPaint* paint, jint saveFlags) {
101    return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
102}
103
104static jint android_view_GLES20Renderer_saveLayerAlpha(JNIEnv* env, jobject canvas,
105        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
106        jint alpha, jint saveFlags) {
107    return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
108}
109
110// ----------------------------------------------------------------------------
111// Clipping
112// ----------------------------------------------------------------------------
113
114static bool android_view_GLES20Renderer_quickReject(JNIEnv* env, jobject canvas,
115        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
116        SkCanvas::EdgeType edge) {
117    return renderer->quickReject(left, top, right, bottom);
118}
119
120static bool android_view_GLES20Renderer_clipRectF(JNIEnv* env, jobject canvas,
121        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
122    return renderer->clipRect(left, top, right, bottom);
123}
124
125static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas,
126        OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom) {
127    return renderer->clipRect(float(left), float(top), float(right), float(bottom));
128}
129
130static bool android_view_GLES20Renderer_getClipBounds(JNIEnv* env, jobject canvas,
131        OpenGLRenderer* renderer, jobject rect) {
132
133    const android::uirenderer::Rect& bounds(renderer->getClipBounds());
134
135    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_GLES20Renderer_translate(JNIEnv* env, jobject canvas,
146        OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
147    renderer->translate(dx, dy);
148}
149
150static void android_view_GLES20Renderer_rotate(JNIEnv* env, jobject canvas,
151        OpenGLRenderer* renderer, jfloat degrees) {
152    renderer->rotate(degrees);
153}
154
155static void android_view_GLES20Renderer_scale(JNIEnv* env, jobject canvas,
156        OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
157    renderer->scale(sx, sy);
158}
159
160static void android_view_GLES20Renderer_setMatrix(JNIEnv* env, jobject canvas,
161        OpenGLRenderer* renderer, SkMatrix* matrix) {
162    renderer->setMatrix(matrix);
163}
164
165static void android_view_GLES20Renderer_getMatrix(JNIEnv* env, jobject canvas,
166        OpenGLRenderer* renderer, SkMatrix* matrix) {
167    renderer->getMatrix(matrix);
168}
169
170static void android_view_GLES20Renderer_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_GLES20Renderer_drawColor(JNIEnv* env, jobject canvas,
180        OpenGLRenderer* renderer, jint color, jint mode) {
181    renderer->drawColor(color, (SkXfermode::Mode) mode);
182}
183
184static void android_view_GLES20Renderer_drawRect(JNIEnv* env, jobject canvas,
185        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
186        SkPaint* paint) {
187    renderer->drawRect(left, top, right, bottom, paint);
188}
189
190// ----------------------------------------------------------------------------
191// JNI Glue
192// ----------------------------------------------------------------------------
193
194const char* const kClassPathName = "android/view/GLES20Canvas";
195
196static JNINativeMethod gMethods[] = {
197    {   "nCreateRenderer",    "()I",        (void*) android_view_GLES20Renderer_createRenderer },
198    {   "nDestroyRenderer",   "(I)V",       (void*) android_view_GLES20Renderer_destroyRenderer },
199    {   "nSetViewport",       "(III)V",     (void*) android_view_GLES20Renderer_setViewport },
200    {   "nPrepare",           "(I)V",       (void*) android_view_GLES20Renderer_prepare },
201
202    {   "nSave",              "(II)I",      (void*) android_view_GLES20Renderer_save },
203    {   "nRestore",           "(I)V",       (void*) android_view_GLES20Renderer_restore },
204    {   "nRestoreToCount",    "(II)V",      (void*) android_view_GLES20Renderer_restoreToCount },
205    {   "nGetSaveCount",      "(I)I",       (void*) android_view_GLES20Renderer_getSaveCount },
206
207    {   "nSaveLayer",         "(IFFFFII)I", (void*) android_view_GLES20Renderer_saveLayer },
208    {   "nSaveLayerAlpha",    "(IFFFFII)I", (void*) android_view_GLES20Renderer_saveLayerAlpha },
209
210    {   "nQuickReject",       "(IFFFFI)Z",  (void*) android_view_GLES20Renderer_quickReject },
211    {   "nClipRect",          "(IFFFF)Z",   (void*) android_view_GLES20Renderer_clipRectF },
212    {   "nClipRect",          "(IIIII)Z",   (void*) android_view_GLES20Renderer_clipRect },
213
214    {   "nTranslate",         "(IFF)V",     (void*) android_view_GLES20Renderer_translate },
215    {   "nRotate",            "(IF)V",      (void*) android_view_GLES20Renderer_rotate },
216    {   "nScale",             "(IFF)V",     (void*) android_view_GLES20Renderer_scale },
217
218    {   "nSetMatrix",         "(II)V",      (void*) android_view_GLES20Renderer_setMatrix },
219    {   "nGetMatrix",         "(II)V",      (void*) android_view_GLES20Renderer_getMatrix },
220    {   "nConcatMatrix",      "(II)V",      (void*) android_view_GLES20Renderer_concatMatrix },
221
222    {   "nDrawColor",         "(III)V",     (void*) android_view_GLES20Renderer_drawColor },
223    {   "nDrawRect",          "(IFFFFI)V",  (void*) android_view_GLES20Renderer_drawRect },
224
225    {   "nGetClipBounds",     "(ILandroid/graphics/Rect;)Z",
226            (void*) android_view_GLES20Renderer_getClipBounds },
227};
228
229#define FIND_CLASS(var, className) \
230        var = env->FindClass(className); \
231        LOG_FATAL_IF(! var, "Unable to find class " className); \
232        var = jclass(env->NewGlobalRef(var));
233
234#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
235        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
236        LOG_FATAL_IF(! var, "Unable to find method " methodName);
237
238int register_android_view_GLES20Canvas(JNIEnv* env) {
239    FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
240    GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");
241
242    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
243}
244
245};
246