android_view_GLES20Canvas.cpp revision 7ae7ac48aa2b53453c9805075171ecd5bcafd7de
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// Clipping
96// ----------------------------------------------------------------------------
97
98static bool android_view_GLES20Renderer_quickReject(JNIEnv* env, jobject canvas,
99        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
100        SkCanvas::EdgeType edge) {
101    return renderer->quickReject(left, top, right, bottom);
102}
103
104static bool android_view_GLES20Renderer_clipRectF(JNIEnv* env, jobject canvas,
105        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
106    return renderer->clipRect(left, top, right, bottom);
107}
108
109static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas,
110        OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom) {
111    return renderer->clipRect(float(left), float(top), float(right), float(bottom));
112}
113
114static bool android_view_GLES20Renderer_getClipBounds(JNIEnv* env, jobject canvas,
115        OpenGLRenderer* renderer, jobject rect) {
116
117    const android::uirenderer::Rect& bounds(renderer->getClipBounds());
118
119    env->CallVoidMethod(rect, gRectClassInfo.set,
120            int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
121
122    return !bounds.isEmpty();
123}
124
125// ----------------------------------------------------------------------------
126// Transforms
127// ----------------------------------------------------------------------------
128
129static void android_view_GLES20Renderer_translate(JNIEnv* env, jobject canvas,
130        OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
131    renderer->translate(dx, dy);
132}
133
134static void android_view_GLES20Renderer_rotate(JNIEnv* env, jobject canvas,
135        OpenGLRenderer* renderer, jfloat degrees) {
136    renderer->rotate(degrees);
137}
138
139static void android_view_GLES20Renderer_scale(JNIEnv* env, jobject canvas,
140        OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
141    renderer->scale(sx, sy);
142}
143
144static void android_view_GLES20Renderer_setMatrix(JNIEnv* env, jobject canvas,
145        OpenGLRenderer* renderer, SkMatrix* matrix) {
146    renderer->setMatrix(matrix);
147}
148
149static void android_view_GLES20Renderer_getMatrix(JNIEnv* env, jobject canvas,
150        OpenGLRenderer* renderer, SkMatrix* matrix) {
151    renderer->getMatrix(matrix);
152}
153
154static void android_view_GLES20Renderer_concatMatrix(JNIEnv* env, jobject canvas,
155        OpenGLRenderer* renderer, SkMatrix* matrix) {
156    renderer->concatMatrix(matrix);
157}
158
159// ----------------------------------------------------------------------------
160// Drawing
161// ----------------------------------------------------------------------------
162
163static void android_view_GLES20Renderer_drawColor(JNIEnv* env, jobject canvas,
164        OpenGLRenderer* renderer, jint color, jint mode) {
165    renderer->drawColor(color, (SkXfermode::Mode) mode);
166}
167
168static void android_view_GLES20Renderer_drawRect(JNIEnv* env, jobject canvas,
169        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
170        SkPaint* paint) {
171    renderer->drawRect(left, top, right, bottom, paint);
172}
173
174// ----------------------------------------------------------------------------
175// JNI Glue
176// ----------------------------------------------------------------------------
177
178const char* const kClassPathName = "android/view/GLES20Canvas";
179
180static JNINativeMethod gMethods[] = {
181    {   "nCreateRenderer",    "()I",       (void*) android_view_GLES20Renderer_createRenderer },
182    {   "nDestroyRenderer",   "(I)V",      (void*) android_view_GLES20Renderer_destroyRenderer },
183    {   "nSetViewport",       "(III)V",    (void*) android_view_GLES20Renderer_setViewport },
184    {   "nPrepare",           "(I)V",      (void*) android_view_GLES20Renderer_prepare },
185
186    {   "nSave",              "(II)I",     (void*) android_view_GLES20Renderer_save },
187    {   "nRestore",           "(I)V",      (void*) android_view_GLES20Renderer_restore },
188    {   "nRestoreToCount",    "(II)V",     (void*) android_view_GLES20Renderer_restoreToCount },
189    {   "nGetSaveCount",      "(I)I",      (void*) android_view_GLES20Renderer_getSaveCount },
190
191    {   "nQuickReject",       "(IFFFFI)Z", (void*) android_view_GLES20Renderer_quickReject },
192    {   "nClipRect",          "(IFFFF)Z",  (void*) android_view_GLES20Renderer_clipRectF },
193    {   "nClipRect",          "(IIIII)Z",  (void*) android_view_GLES20Renderer_clipRect },
194
195    {   "nTranslate",         "(IFF)V",    (void*) android_view_GLES20Renderer_translate },
196    {   "nRotate",            "(IF)V",     (void*) android_view_GLES20Renderer_rotate },
197    {   "nScale",             "(IFF)V",    (void*) android_view_GLES20Renderer_scale },
198
199    {   "nSetMatrix",         "(II)V",     (void*) android_view_GLES20Renderer_setMatrix },
200    {   "nGetMatrix",         "(II)V",     (void*) android_view_GLES20Renderer_getMatrix },
201    {   "nConcatMatrix",      "(II)V",     (void*) android_view_GLES20Renderer_concatMatrix },
202
203    {   "nDrawColor",         "(III)V",    (void*) android_view_GLES20Renderer_drawColor },
204    {   "nDrawRect",          "(IFFFFI)V", (void*) android_view_GLES20Renderer_drawRect },
205
206    {   "nGetClipBounds",     "(ILandroid/graphics/Rect;)Z",
207            (void*) android_view_GLES20Renderer_getClipBounds },
208};
209
210#define FIND_CLASS(var, className) \
211        var = env->FindClass(className); \
212        LOG_FATAL_IF(! var, "Unable to find class " className); \
213        var = jclass(env->NewGlobalRef(var));
214
215#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
216        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
217        LOG_FATAL_IF(! var, "Unable to find method " methodName);
218
219int register_android_view_GLES20Canvas(JNIEnv* env) {
220    FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
221    GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");
222
223    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
224}
225
226};
227