blob: 7521af4628479a35c8b7bc91c843b4819eab6e20 [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
Romain Guya1db5742010-07-20 13:09:13 -070017#define LOG_TAG "OpenGLRenderer"
18
Romain Guye4d01122010-06-16 18:44:05 -070019#include "jni.h"
20#include <nativehelper/JNIHelp.h>
21#include <android_runtime/AndroidRuntime.h>
Romain Guydeba7852010-07-07 17:54:48 -070022#include <utils/ResourceTypes.h>
Romain Guye4d01122010-06-16 18:44:05 -070023
Romain Guyce0537b2010-06-29 21:05:21 -070024#include <SkBitmap.h>
Romain Guyc7d53492010-06-25 13:41:57 -070025#include <SkCanvas.h>
Romain Guyf6a11b82010-06-23 17:47:49 -070026#include <SkMatrix.h>
Romain Guyc7d53492010-06-25 13:41:57 -070027#include <SkPaint.h>
Romain Guy079ba2c2010-07-16 14:12:24 -070028#include <SkRegion.h>
Romain Guya1db5742010-07-20 13:09:13 -070029#include <SkScalerContext.h>
Romain Guy61c8c9c2010-08-09 20:48:09 -070030#include <SkTemplates.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070031#include <SkXfermode.h>
Romain Guye4d01122010-06-16 18:44:05 -070032
Romain Guyb051e892010-09-28 19:09:36 -070033#include <DisplayListRenderer.h>
Romain Guye2d345e2010-09-24 18:39:22 -070034#include <OpenGLDebugRenderer.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070035#include <OpenGLRenderer.h>
Romain Guy06f96e22010-07-30 19:18:16 -070036#include <SkiaShader.h>
Romain Guydb1938e2010-08-02 18:50:22 -070037#include <SkiaColorFilter.h>
Romain Guy9d5316e2010-06-24 19:30:36 -070038#include <Rect.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070039
Romain Guye8e62a42010-07-23 18:55:21 -070040#include "TextLayout.h"
41
Romain Guye4d01122010-06-16 18:44:05 -070042namespace android {
43
Romain Guy9d5316e2010-06-24 19:30:36 -070044using namespace uirenderer;
45
Romain Guy16393512010-08-08 00:14:31 -070046/**
47 * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
48 * devices. This means all the logic must be compiled only when the
49 * preprocessor variable USE_OPENGL_RENDERER is defined.
50 */
51#ifdef USE_OPENGL_RENDERER
52
Romain Guybdb801ca2010-10-04 17:22:29 -070053///////////////////////////////////////////////////////////////////////////////
54// Defines
55///////////////////////////////////////////////////////////////////////////////
56
57// Debug
Romain Guye2d345e2010-09-24 18:39:22 -070058#define DEBUG_RENDERER 0
Romain Guybdb801ca2010-10-04 17:22:29 -070059#define PROFILE_RENDERER 0
60
61// Debug
62#if DEBUG_RENDERER
63 #define RENDERER_LOGD(...) LOGD(__VA_ARGS__)
64#else
65 #define RENDERER_LOGD(...)
66#endif
Romain Guye2d345e2010-09-24 18:39:22 -070067
Romain Guy9d5316e2010-06-24 19:30:36 -070068// ----------------------------------------------------------------------------
69// Java APIs
70// ----------------------------------------------------------------------------
71
72static struct {
Romain Guy7ae7ac42010-06-25 13:46:18 -070073 jclass clazz;
74 jmethodID set;
Romain Guy9d5316e2010-06-24 19:30:36 -070075} gRectClassInfo;
76
Romain Guye4d01122010-06-16 18:44:05 -070077// ----------------------------------------------------------------------------
78// Constructors
79// ----------------------------------------------------------------------------
80
Romain Guyce0537b2010-06-29 21:05:21 -070081static OpenGLRenderer* android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject canvas) {
Romain Guybdb801ca2010-10-04 17:22:29 -070082 RENDERER_LOGD("Create OpenGLRenderer");
83#if PROFILE_RENDERER
Romain Guye2d345e2010-09-24 18:39:22 -070084 return new OpenGLDebugRenderer;
85#else
Romain Guy85bf02f2010-06-22 13:11:24 -070086 return new OpenGLRenderer;
Romain Guye2d345e2010-09-24 18:39:22 -070087#endif
Romain Guye4d01122010-06-16 18:44:05 -070088}
89
Romain Guyce0537b2010-06-29 21:05:21 -070090static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -070091 OpenGLRenderer* renderer) {
Romain Guybdb801ca2010-10-04 17:22:29 -070092 RENDERER_LOGD("Destroy OpenGLRenderer");
Romain Guyf6a11b82010-06-23 17:47:49 -070093 delete renderer;
Romain Guye4d01122010-06-16 18:44:05 -070094}
95
96// ----------------------------------------------------------------------------
97// Setup
98// ----------------------------------------------------------------------------
99
Romain Guyce0537b2010-06-29 21:05:21 -0700100static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700101 OpenGLRenderer* renderer, jint width, jint height) {
102 renderer->setViewport(width, height);
Romain Guye4d01122010-06-16 18:44:05 -0700103}
104
Romain Guyce0537b2010-06-29 21:05:21 -0700105static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700106 OpenGLRenderer* renderer) {
107 renderer->prepare();
Romain Guye4d01122010-06-16 18:44:05 -0700108}
109
Romain Guyb025b9c2010-09-16 14:16:48 -0700110static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject canvas,
111 OpenGLRenderer* renderer) {
112 renderer->finish();
113}
114
Romain Guyda8532c2010-08-31 11:50:35 -0700115static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject canvas,
116 OpenGLRenderer* renderer) {
117 renderer->acquireContext();
118}
119
120static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject canvas,
121 OpenGLRenderer* renderer) {
122 renderer->releaseContext();
123}
124
Romain Guye4d01122010-06-16 18:44:05 -0700125// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -0700126// State
127// ----------------------------------------------------------------------------
128
Romain Guyce0537b2010-06-29 21:05:21 -0700129static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer,
Romain Guybb9524b2010-06-22 18:56:38 -0700130 jint flags) {
Romain Guyf6a11b82010-06-23 17:47:49 -0700131 return renderer->save(flags);
Romain Guybb9524b2010-06-22 18:56:38 -0700132}
133
Romain Guyce0537b2010-06-29 21:05:21 -0700134static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700135 OpenGLRenderer* renderer) {
136 return renderer->getSaveCount();
Romain Guybb9524b2010-06-22 18:56:38 -0700137}
138
Romain Guyce0537b2010-06-29 21:05:21 -0700139static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700140 OpenGLRenderer* renderer) {
141 renderer->restore();
Romain Guybb9524b2010-06-22 18:56:38 -0700142}
143
Romain Guyce0537b2010-06-29 21:05:21 -0700144static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700145 OpenGLRenderer* renderer, jint saveCount) {
146 renderer->restoreToCount(saveCount);
Romain Guybb9524b2010-06-22 18:56:38 -0700147}
148
149// ----------------------------------------------------------------------------
Romain Guybd6b79b2010-06-26 00:13:53 -0700150// Layers
151// ----------------------------------------------------------------------------
152
Romain Guyce0537b2010-06-29 21:05:21 -0700153static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject canvas,
Romain Guybd6b79b2010-06-26 00:13:53 -0700154 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
155 SkPaint* paint, jint saveFlags) {
156 return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
157}
158
Romain Guyce0537b2010-06-29 21:05:21 -0700159static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas,
Romain Guybd6b79b2010-06-26 00:13:53 -0700160 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
161 jint alpha, jint saveFlags) {
162 return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
163}
164
165// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -0700166// Clipping
167// ----------------------------------------------------------------------------
168
Romain Guyce0537b2010-06-29 21:05:21 -0700169static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject canvas,
Romain Guyc7d53492010-06-25 13:41:57 -0700170 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
171 SkCanvas::EdgeType edge) {
172 return renderer->quickReject(left, top, right, bottom);
173}
174
Romain Guyce0537b2010-06-29 21:05:21 -0700175static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject canvas,
Romain Guy079ba2c2010-07-16 14:12:24 -0700176 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
177 SkRegion::Op op) {
178 return renderer->clipRect(left, top, right, bottom, op);
Romain Guybb9524b2010-06-22 18:56:38 -0700179}
180
Romain Guyce0537b2010-06-29 21:05:21 -0700181static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject canvas,
Romain Guy079ba2c2010-07-16 14:12:24 -0700182 OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom,
183 SkRegion::Op op) {
184 return renderer->clipRect(float(left), float(top), float(right), float(bottom), op);
Romain Guyf6a11b82010-06-23 17:47:49 -0700185}
Romain Guybb9524b2010-06-22 18:56:38 -0700186
Romain Guyce0537b2010-06-29 21:05:21 -0700187static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas,
Romain Guy9d5316e2010-06-24 19:30:36 -0700188 OpenGLRenderer* renderer, jobject rect) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700189 const android::uirenderer::Rect& bounds(renderer->getClipBounds());
Romain Guy9d5316e2010-06-24 19:30:36 -0700190
Romain Guy7ae7ac42010-06-25 13:46:18 -0700191 env->CallVoidMethod(rect, gRectClassInfo.set,
192 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
Romain Guy9d5316e2010-06-24 19:30:36 -0700193
Romain Guy7ae7ac42010-06-25 13:46:18 -0700194 return !bounds.isEmpty();
Romain Guy9d5316e2010-06-24 19:30:36 -0700195}
196
Romain Guyf6a11b82010-06-23 17:47:49 -0700197// ----------------------------------------------------------------------------
198// Transforms
199// ----------------------------------------------------------------------------
200
Romain Guyce0537b2010-06-29 21:05:21 -0700201static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700202 OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700203 renderer->translate(dx, dy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700204}
205
Romain Guyce0537b2010-06-29 21:05:21 -0700206static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700207 OpenGLRenderer* renderer, jfloat degrees) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700208 renderer->rotate(degrees);
Romain Guyf6a11b82010-06-23 17:47:49 -0700209}
210
Romain Guyce0537b2010-06-29 21:05:21 -0700211static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700212 OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700213 renderer->scale(sx, sy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700214}
215
Romain Guyce0537b2010-06-29 21:05:21 -0700216static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700217 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700218 renderer->setMatrix(matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700219}
220
Romain Guyce0537b2010-06-29 21:05:21 -0700221static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700222 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700223 renderer->getMatrix(matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700224}
225
Romain Guyce0537b2010-06-29 21:05:21 -0700226static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas,
Romain Guyf6a11b82010-06-23 17:47:49 -0700227 OpenGLRenderer* renderer, SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700228 renderer->concatMatrix(matrix);
Romain Guybb9524b2010-06-22 18:56:38 -0700229}
230
231// ----------------------------------------------------------------------------
232// Drawing
Romain Guy85bf02f2010-06-22 13:11:24 -0700233// ----------------------------------------------------------------------------
234
Romain Guyce0537b2010-06-29 21:05:21 -0700235static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject canvas,
Romain Guydbd77cd2010-07-09 10:36:05 -0700236 OpenGLRenderer* renderer, SkBitmap* bitmap, float left, float top, SkPaint* paint) {
237 renderer->drawBitmap(bitmap, left, top, paint);
Romain Guy85bf02f2010-06-22 13:11:24 -0700238}
239
Romain Guyce0537b2010-06-29 21:05:21 -0700240static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject canvas,
241 OpenGLRenderer* renderer, SkBitmap* bitmap,
242 float srcLeft, float srcTop, float srcRight, float srcBottom,
Romain Guydbd77cd2010-07-09 10:36:05 -0700243 float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) {
244 renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
245 dstLeft, dstTop, dstRight, dstBottom, paint);
Romain Guyf86ef572010-07-01 11:05:42 -0700246}
Romain Guy8ba548f2010-06-30 19:21:21 -0700247
Romain Guyf86ef572010-07-01 11:05:42 -0700248static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject canvas,
Romain Guydbd77cd2010-07-09 10:36:05 -0700249 OpenGLRenderer* renderer, SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
250 renderer->drawBitmap(bitmap, matrix, paint);
Romain Guyce0537b2010-06-29 21:05:21 -0700251}
252
Romain Guydeba7852010-07-07 17:54:48 -0700253static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas,
254 OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray chunks,
Romain Guydbd77cd2010-07-09 10:36:05 -0700255 float left, float top, float right, float bottom, SkPaint* paint) {
Romain Guydeba7852010-07-07 17:54:48 -0700256 jbyte* storage = env->GetByteArrayElements(chunks, NULL);
257 Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage);
258 Res_png_9patch::deserialize(patch);
259
Romain Guy4aa90572010-09-26 18:40:37 -0700260 renderer->drawPatch(bitmap, &patch->xDivs[0], &patch->yDivs[0],
261 patch->numXDivs, patch->numYDivs, left, top, right, bottom, paint);
Romain Guydeba7852010-07-07 17:54:48 -0700262
Romain Guydeba7852010-07-07 17:54:48 -0700263 env->ReleaseByteArrayElements(chunks, storage, 0);
264}
265
Romain Guyce0537b2010-06-29 21:05:21 -0700266static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject canvas,
267 OpenGLRenderer* renderer, jint color, SkXfermode::Mode mode) {
268 renderer->drawColor(color, mode);
269}
270
271static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
Romain Guyc7d53492010-06-25 13:41:57 -0700272 OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
273 SkPaint* paint) {
274 renderer->drawRect(left, top, right, bottom, paint);
275}
276
Romain Guya48a1a82010-08-10 14:59:15 -0700277static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
278 OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
279 SkRegion::Iterator it(*region);
280 while (!it.done()) {
281 const SkIRect& r = it.rect();
282 renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
283 it.next();
284 }
285}
286
Romain Guy7fbcc042010-08-04 15:40:07 -0700287static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject canvas,
288 OpenGLRenderer* renderer, SkPath* path, SkPaint* paint) {
289 renderer->drawPath(path, paint);
290}
291
Romain Guy759ea802010-09-16 20:49:46 -0700292static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject canvas,
293 OpenGLRenderer* renderer, jfloatArray points, jint offset, jint count, SkPaint* paint) {
294 jfloat* storage = env->GetFloatArrayElements(points, NULL);
295
296 renderer->drawLines(storage + offset, count, paint);
297
298 env->ReleaseFloatArrayElements(points, storage, 0);
299}
300
Romain Guy85bf02f2010-06-22 13:11:24 -0700301// ----------------------------------------------------------------------------
Romain Guydb1938e2010-08-02 18:50:22 -0700302// Shaders and color filters
Romain Guyd27977d2010-07-14 19:18:51 -0700303// ----------------------------------------------------------------------------
304
Romain Guydb1938e2010-08-02 18:50:22 -0700305static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject canvas,
Romain Guyd27977d2010-07-14 19:18:51 -0700306 OpenGLRenderer* renderer) {
307 renderer->resetShader();
Romain Guydb1938e2010-08-02 18:50:22 -0700308 renderer->resetColorFilter();
Romain Guy1e45aae2010-08-13 19:39:53 -0700309 renderer->resetShadow();
Romain Guyd27977d2010-07-14 19:18:51 -0700310}
311
Romain Guy06f96e22010-07-30 19:18:16 -0700312static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas,
313 OpenGLRenderer* renderer, SkiaShader* shader) {
314 renderer->setupShader(shader);
Romain Guy7fac2e12010-07-16 17:10:13 -0700315}
316
Romain Guydb1938e2010-08-02 18:50:22 -0700317static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject canvas,
318 OpenGLRenderer* renderer, SkiaColorFilter* filter) {
319 renderer->setupColorFilter(filter);
320}
321
Romain Guy1e45aae2010-08-13 19:39:53 -0700322static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject canvas,
323 OpenGLRenderer* renderer, jfloat radius, jfloat dx, jfloat dy, jint color) {
324 renderer->setupShadow(radius, dx, dy, color);
325}
326
Romain Guyd27977d2010-07-14 19:18:51 -0700327// ----------------------------------------------------------------------------
Romain Guya1db5742010-07-20 13:09:13 -0700328// Text
329// ----------------------------------------------------------------------------
330
Romain Guye8e62a42010-07-23 18:55:21 -0700331static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
332 jfloat x, jfloat y, int flags, SkPaint* paint) {
333 const jchar *workText;
Romain Guy92262982010-07-26 11:17:54 -0700334 jchar* buffer = NULL;
Romain Guye8e62a42010-07-23 18:55:21 -0700335 int32_t workBytes;
Romain Guy92262982010-07-26 11:17:54 -0700336 if (TextLayout::prepareText(paint, text, count, flags, &workText, &workBytes, &buffer)) {
Romain Guye8e62a42010-07-23 18:55:21 -0700337 renderer->drawText((const char*) workText, workBytes, count, x, y, paint);
Romain Guy92262982010-07-26 11:17:54 -0700338 free(buffer);
Romain Guye8e62a42010-07-23 18:55:21 -0700339 }
340}
341
Romain Guy61c8c9c2010-08-09 20:48:09 -0700342static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
343 jint start, jint count, jint contextCount, jfloat x, jfloat y,
344 int flags, SkPaint* paint) {
345 uint8_t rtl = flags & 0x1;
346 if (rtl) {
347 SkAutoSTMalloc<80, jchar> buffer(contextCount);
348 jchar* shaped = buffer.get();
349 if (TextLayout::prepareRtlTextRun(text, start, count, contextCount, shaped)) {
350 renderer->drawText((const char*) shaped, count << 1, count, x, y, paint);
351 } else {
352 LOGW("drawTextRun error");
353 }
354 } else {
355 renderer->drawText((const char*) (text + start), count << 1, count, x, y, paint);
356 }
357}
358
Romain Guya1db5742010-07-20 13:09:13 -0700359static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas,
360 OpenGLRenderer* renderer, jcharArray text, int index, int count,
361 jfloat x, jfloat y, int flags, SkPaint* paint) {
362 jchar* textArray = env->GetCharArrayElements(text, NULL);
Romain Guye8e62a42010-07-23 18:55:21 -0700363 renderText(renderer, textArray + index, count, x, y, flags, paint);
Romain Guya1db5742010-07-20 13:09:13 -0700364 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
365}
366
367static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas,
368 OpenGLRenderer* renderer, jstring text, int start, int end,
369 jfloat x, jfloat y, int flags, SkPaint* paint) {
370 const jchar* textArray = env->GetStringChars(text, NULL);
Romain Guye8e62a42010-07-23 18:55:21 -0700371 renderText(renderer, textArray + start, end - start, x, y, flags, paint);
Romain Guya1db5742010-07-20 13:09:13 -0700372 env->ReleaseStringChars(text, textArray);
373}
374
Romain Guy61c8c9c2010-08-09 20:48:09 -0700375static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject canvas,
376 OpenGLRenderer* renderer, jcharArray text, int index, int count,
377 int contextIndex, int contextCount, jfloat x, jfloat y, int dirFlags,
378 SkPaint* paint) {
379 jchar* textArray = env->GetCharArrayElements(text, NULL);
380 renderTextRun(renderer, textArray + contextIndex, index - contextIndex,
381 count, contextCount, x, y, dirFlags, paint);
382 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
383 }
384
385static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject canvas,
386 OpenGLRenderer* renderer, jstring text, int start, int end,
387 int contextStart, int contextEnd, jfloat x, jfloat y, int dirFlags,
388 SkPaint* paint) {
389 const jchar* textArray = env->GetStringChars(text, NULL);
390 jint count = end - start;
391 jint contextCount = contextEnd - contextStart;
392 renderTextRun(renderer, textArray + contextStart, start - contextStart,
393 count, contextCount, x, y, dirFlags, paint);
394 env->ReleaseStringChars(text, textArray);
395}
396
Romain Guyb051e892010-09-28 19:09:36 -0700397// ----------------------------------------------------------------------------
398// Display lists
399// ----------------------------------------------------------------------------
400
401static OpenGLRenderer* android_view_GLES20Canvas_createDisplayListRenderer(
402 JNIEnv* env, jobject canvas) {
403 return new DisplayListRenderer;
404}
405
406static DisplayList* android_view_GLES20Canvas_createDisplayList(JNIEnv* env,
407 jobject canvas, DisplayListRenderer* renderer) {
408 return renderer->getDisplayList();
409}
410
411static void android_view_GLES20Canvas_destroyDisplayList(JNIEnv* env,
412 jobject canvas, DisplayList* displayList) {
413 delete displayList;
414}
415
416static void android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
417 jobject canvas, OpenGLRenderer* renderer, DisplayList* displayList) {
418 displayList->replay(*renderer);
419}
420
Romain Guy16393512010-08-08 00:14:31 -0700421#endif // USE_OPENGL_RENDERER
422
423// ----------------------------------------------------------------------------
424// Common
425// ----------------------------------------------------------------------------
426
427static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz) {
428#ifdef USE_OPENGL_RENDERER
429 return JNI_TRUE;
430#else
431 return JNI_FALSE;
432#endif
433}
434
Romain Guya1db5742010-07-20 13:09:13 -0700435// ----------------------------------------------------------------------------
Romain Guye4d01122010-06-16 18:44:05 -0700436// JNI Glue
437// ----------------------------------------------------------------------------
438
439const char* const kClassPathName = "android/view/GLES20Canvas";
440
441static JNINativeMethod gMethods[] = {
Romain Guy61c8c9c2010-08-09 20:48:09 -0700442 { "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable },
443
Romain Guy16393512010-08-08 00:14:31 -0700444#ifdef USE_OPENGL_RENDERER
Romain Guy61c8c9c2010-08-09 20:48:09 -0700445 { "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer },
446 { "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer },
447 { "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport },
448 { "nPrepare", "(I)V", (void*) android_view_GLES20Canvas_prepare },
Romain Guyb025b9c2010-09-16 14:16:48 -0700449 { "nFinish", "(I)V", (void*) android_view_GLES20Canvas_finish },
Romain Guyda8532c2010-08-31 11:50:35 -0700450 { "nAcquireContext", "(I)V", (void*) android_view_GLES20Canvas_acquireContext },
451 { "nReleaseContext", "(I)V", (void*) android_view_GLES20Canvas_releaseContext },
Romain Guy16393512010-08-08 00:14:31 -0700452
Romain Guy61c8c9c2010-08-09 20:48:09 -0700453 { "nSave", "(II)I", (void*) android_view_GLES20Canvas_save },
454 { "nRestore", "(I)V", (void*) android_view_GLES20Canvas_restore },
455 { "nRestoreToCount", "(II)V", (void*) android_view_GLES20Canvas_restoreToCount },
456 { "nGetSaveCount", "(I)I", (void*) android_view_GLES20Canvas_getSaveCount },
Romain Guy85bf02f2010-06-22 13:11:24 -0700457
Romain Guy61c8c9c2010-08-09 20:48:09 -0700458 { "nSaveLayer", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayer },
459 { "nSaveLayerAlpha", "(IFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha },
Romain Guybb9524b2010-06-22 18:56:38 -0700460
Romain Guy61c8c9c2010-08-09 20:48:09 -0700461 { "nQuickReject", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_quickReject },
462 { "nClipRect", "(IFFFFI)Z", (void*) android_view_GLES20Canvas_clipRectF },
463 { "nClipRect", "(IIIIII)Z", (void*) android_view_GLES20Canvas_clipRect },
Romain Guyc7d53492010-06-25 13:41:57 -0700464
Romain Guy61c8c9c2010-08-09 20:48:09 -0700465 { "nTranslate", "(IFF)V", (void*) android_view_GLES20Canvas_translate },
466 { "nRotate", "(IF)V", (void*) android_view_GLES20Canvas_rotate },
467 { "nScale", "(IFF)V", (void*) android_view_GLES20Canvas_scale },
Romain Guyc7d53492010-06-25 13:41:57 -0700468
Romain Guy61c8c9c2010-08-09 20:48:09 -0700469 { "nSetMatrix", "(II)V", (void*) android_view_GLES20Canvas_setMatrix },
470 { "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix },
471 { "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix },
Romain Guyc7d53492010-06-25 13:41:57 -0700472
Romain Guy61c8c9c2010-08-09 20:48:09 -0700473 { "nDrawBitmap", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawBitmap },
474 { "nDrawBitmap", "(IIFFFFFFFFI)V", (void*) android_view_GLES20Canvas_drawBitmapRect },
475 { "nDrawBitmap", "(IIII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
476 { "nDrawPatch", "(II[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch },
477 { "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
478 { "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
Romain Guya48a1a82010-08-10 14:59:15 -0700479 { "nDrawRects", "(III)V", (void*) android_view_GLES20Canvas_drawRects },
Romain Guy61c8c9c2010-08-09 20:48:09 -0700480 { "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath },
Romain Guy759ea802010-09-16 20:49:46 -0700481 { "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines },
Romain Guybd6b79b2010-06-26 00:13:53 -0700482
Romain Guy61c8c9c2010-08-09 20:48:09 -0700483 { "nResetModifiers", "(I)V", (void*) android_view_GLES20Canvas_resetModifiers },
484 { "nSetupShader", "(II)V", (void*) android_view_GLES20Canvas_setupShader },
485 { "nSetupColorFilter", "(II)V", (void*) android_view_GLES20Canvas_setupColorFilter },
Romain Guy1e45aae2010-08-13 19:39:53 -0700486 { "nSetupShadow", "(IFFFI)V", (void*) android_view_GLES20Canvas_setupShadow },
Romain Guybb9524b2010-06-22 18:56:38 -0700487
Romain Guy61c8c9c2010-08-09 20:48:09 -0700488 { "nDrawText", "(I[CIIFFII)V", (void*) android_view_GLES20Canvas_drawTextArray },
489 { "nDrawText", "(ILjava/lang/String;IIFFII)V",
Romain Guya1db5742010-07-20 13:09:13 -0700490 (void*) android_view_GLES20Canvas_drawText },
491
Romain Guy61c8c9c2010-08-09 20:48:09 -0700492 { "nDrawTextRun", "(I[CIIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
493 { "nDrawTextRun", "(ILjava/lang/String;IIIIFFII)V",
494 (void*) android_view_GLES20Canvas_drawTextRun },
495
Romain Guyfb8b7632010-08-23 21:05:08 -0700496 { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z",
Romain Guyce0537b2010-06-29 21:05:21 -0700497 (void*) android_view_GLES20Canvas_getClipBounds },
Romain Guyb051e892010-09-28 19:09:36 -0700498
499 { "nCreateDisplayListRenderer", "()I", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
500 { "nCreateDisplayList", "(I)I", (void*) android_view_GLES20Canvas_createDisplayList },
501 { "nDestroyDisplayList", "(I)V", (void*) android_view_GLES20Canvas_destroyDisplayList },
502 { "nDrawDisplayList", "(II)V", (void*) android_view_GLES20Canvas_drawDisplayList },
503
Romain Guy16393512010-08-08 00:14:31 -0700504#endif
Romain Guye4d01122010-06-16 18:44:05 -0700505};
506
Romain Guy16393512010-08-08 00:14:31 -0700507#ifdef USE_OPENGL_RENDERER
508 #define FIND_CLASS(var, className) \
509 var = env->FindClass(className); \
510 LOG_FATAL_IF(! var, "Unable to find class " className); \
511 var = jclass(env->NewGlobalRef(var));
512
513 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
514 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
515 LOG_FATAL_IF(! var, "Unable to find method " methodName);
516#else
517 #define FIND_CLASS(var, className)
518 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
519#endif
Romain Guy9d5316e2010-06-24 19:30:36 -0700520
Romain Guye4d01122010-06-16 18:44:05 -0700521int register_android_view_GLES20Canvas(JNIEnv* env) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700522 FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
523 GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");
Romain Guy9d5316e2010-06-24 19:30:36 -0700524
Romain Guye4d01122010-06-16 18:44:05 -0700525 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
526}
527
528};