blob: 329e371e9f1f70467bc2f80b363194483f6824e7 [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"
Patrick Dubroye4ac2d62010-12-01 11:23:13 -080020#include "GraphicsJNI.h"
Romain Guye4d01122010-06-16 18:44:05 -070021#include <nativehelper/JNIHelp.h>
Romain Guy65549432012-03-26 16:45:05 -070022
Romain Guy3b748a42013-04-17 18:54:38 -070023#include "android_view_GraphicBuffer.h"
24
Romain Guye4d01122010-06-16 18:44:05 -070025#include <android_runtime/AndroidRuntime.h>
Romain Guye5e0c502011-06-15 15:18:31 -070026#include <android_runtime/android_graphics_SurfaceTexture.h>
Romain Guy65549432012-03-26 16:45:05 -070027
Mathias Agopianb13b9bd2012-02-17 18:27:36 -080028#include <androidfw/ResourceTypes.h>
Romain Guye4d01122010-06-16 18:44:05 -070029
Romain Guy3b748a42013-04-17 18:54:38 -070030#include <gui/GLConsumer.h>
31
Romain Guy65549432012-03-26 16:45:05 -070032#include <private/hwui/DrawGlInfo.h>
33
34#include <cutils/properties.h>
Romain Guy8f0095c2011-05-02 17:24:22 -070035
Romain Guyce0537b2010-06-29 21:05:21 -070036#include <SkBitmap.h>
Romain Guyc7d53492010-06-25 13:41:57 -070037#include <SkCanvas.h>
Romain Guyf6a11b82010-06-23 17:47:49 -070038#include <SkMatrix.h>
Romain Guyc7d53492010-06-25 13:41:57 -070039#include <SkPaint.h>
Romain Guy079ba2c2010-07-16 14:12:24 -070040#include <SkRegion.h>
Romain Guya1db5742010-07-20 13:09:13 -070041#include <SkScalerContext.h>
Romain Guy61c8c9c2010-08-09 20:48:09 -070042#include <SkTemplates.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070043#include <SkXfermode.h>
Romain Guye4d01122010-06-16 18:44:05 -070044
Romain Guyb051e892010-09-28 19:09:36 -070045#include <DisplayListRenderer.h>
Romain Guy6c319ca2011-01-11 14:29:25 -080046#include <LayerRenderer.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070047#include <OpenGLRenderer.h>
Romain Guy0baaac52012-08-31 20:31:01 -070048#include <Stencil.h>
Romain Guy9d5316e2010-06-24 19:30:36 -070049#include <Rect.h>
John Reck113e0822014-03-18 09:22:59 -070050#include <RenderNode.h>
John Reck52244ff2014-05-01 21:27:37 -070051#include <CanvasProperty.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070052
Raph Levien1a73f7322014-01-30 16:06:28 -080053#ifdef USE_MINIKIN
54#include <minikin/Layout.h>
55#include "MinikinSkia.h"
56#include "MinikinUtils.h"
57#endif
58
Romain Guyd1d4bb72012-01-17 17:31:27 -080059#include <TextLayout.h>
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -080060#include <TextLayoutCache.h>
Romain Guye8e62a42010-07-23 18:55:21 -070061
Romain Guye4d01122010-06-16 18:44:05 -070062namespace android {
63
Romain Guy9d5316e2010-06-24 19:30:36 -070064using namespace uirenderer;
65
Romain Guy16393512010-08-08 00:14:31 -070066/**
67 * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
68 * devices. This means all the logic must be compiled only when the
69 * preprocessor variable USE_OPENGL_RENDERER is defined.
70 */
71#ifdef USE_OPENGL_RENDERER
72
Romain Guy244ada12012-03-28 16:41:26 -070073// ----------------------------------------------------------------------------
Romain Guybdb801ca2010-10-04 17:22:29 -070074// Defines
Romain Guy244ada12012-03-28 16:41:26 -070075// ----------------------------------------------------------------------------
Romain Guybdb801ca2010-10-04 17:22:29 -070076
77// Debug
Romain Guye2d345e2010-09-24 18:39:22 -070078#define DEBUG_RENDERER 0
Romain Guybdb801ca2010-10-04 17:22:29 -070079
80// Debug
81#if DEBUG_RENDERER
Steve Block5baa3a62011-12-20 16:23:08 +000082 #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__)
Romain Guybdb801ca2010-10-04 17:22:29 -070083#else
84 #define RENDERER_LOGD(...)
85#endif
Romain Guye2d345e2010-09-24 18:39:22 -070086
Romain Guy9d5316e2010-06-24 19:30:36 -070087// ----------------------------------------------------------------------------
Romain Guy9d5316e2010-06-24 19:30:36 -070088
89static struct {
Romain Guy7ae7ac42010-06-25 13:46:18 -070090 jmethodID set;
Romain Guy9d5316e2010-06-24 19:30:36 -070091} gRectClassInfo;
92
Romain Guye4d01122010-06-16 18:44:05 -070093// ----------------------------------------------------------------------------
94// Constructors
95// ----------------------------------------------------------------------------
96
Chet Haase5c13d892010-10-08 08:37:55 -070097static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +000098 jlong rendererPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -080099 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guybdb801ca2010-10-04 17:22:29 -0700100 RENDERER_LOGD("Destroy OpenGLRenderer");
Romain Guyf6a11b82010-06-23 17:47:49 -0700101 delete renderer;
Romain Guye4d01122010-06-16 18:44:05 -0700102}
103
104// ----------------------------------------------------------------------------
105// Setup
106// ----------------------------------------------------------------------------
107
Romain Guy7d7b5492011-01-24 16:33:45 -0800108static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000109 jlong rendererPtr, jint width, jint height) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800110 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guyf6a11b82010-06-23 17:47:49 -0700111 renderer->setViewport(width, height);
Romain Guye4d01122010-06-16 18:44:05 -0700112}
113
Chet Haase44b2fe32012-06-06 19:03:58 -0700114static int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000115 jlong rendererPtr, jboolean opaque) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800116 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Chet Haase44b2fe32012-06-06 19:03:58 -0700117 return renderer->prepare(opaque);
Romain Guye4d01122010-06-16 18:44:05 -0700118}
119
Chet Haase44b2fe32012-06-06 19:03:58 -0700120static int android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000121 jlong rendererPtr, jint left, jint top, jint right, jint bottom,
Romain Guy7d7b5492011-01-24 16:33:45 -0800122 jboolean opaque) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800123 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Chet Haase44b2fe32012-06-06 19:03:58 -0700124 return renderer->prepareDirty(left, top, right, bottom, opaque);
Romain Guy7d7b5492011-01-24 16:33:45 -0800125}
126
127static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000128 jlong rendererPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800129 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guyb025b9c2010-09-16 14:16:48 -0700130 renderer->finish();
131}
132
Chris Craikba9b6132013-12-15 17:10:19 -0800133static void android_view_GLES20Canvas_setProperty(JNIEnv* env,
134 jobject clazz, jstring name, jstring value) {
135 if (!Caches::hasInstance()) {
136 ALOGW("can't set property, no Caches instance");
137 return;
138 }
139
140 if (name == NULL || value == NULL) {
141 ALOGW("can't set prop, null passed");
142 }
143
144 const char* nameCharArray = env->GetStringUTFChars(name, NULL);
145 const char* valueCharArray = env->GetStringUTFChars(value, NULL);
146 Caches::getInstance().setTempProperty(nameCharArray, valueCharArray);
147 env->ReleaseStringUTFChars(name, nameCharArray);
148 env->ReleaseStringUTFChars(name, valueCharArray);
149}
150
Romain Guy530041d2012-01-25 18:56:29 -0800151// ----------------------------------------------------------------------------
152// Functor
153// ----------------------------------------------------------------------------
154
Romain Guy65549432012-03-26 16:45:05 -0700155static jint android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000156 jlong rendererPtr, jlong functorPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800157 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
158 Functor* functor = reinterpret_cast<Functor*>(functorPtr);
Romain Guycabfcc12011-03-07 18:06:46 -0800159 android::uirenderer::Rect dirty;
160 return renderer->callDrawGLFunction(functor, dirty);
Chet Haasedaf98e92011-01-10 14:10:36 -0800161}
162
Romain Guy8f3b8e32012-03-27 16:33:45 -0700163// ----------------------------------------------------------------------------
164// Misc
165// ----------------------------------------------------------------------------
166
Romain Guyf61970fc2011-07-07 14:10:06 -0700167static jint android_view_GLES20Canvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) {
168 return Caches::getInstance().maxTextureSize;
169}
170
171static jint android_view_GLES20Canvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) {
172 return Caches::getInstance().maxTextureSize;
173}
174
Romain Guye4d01122010-06-16 18:44:05 -0700175// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -0700176// State
177// ----------------------------------------------------------------------------
178
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000179static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, jlong rendererPtr,
Romain Guybb9524b2010-06-22 18:56:38 -0700180 jint flags) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800181 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guyf6a11b82010-06-23 17:47:49 -0700182 return renderer->save(flags);
Romain Guybb9524b2010-06-22 18:56:38 -0700183}
184
Romain Guy7d7b5492011-01-24 16:33:45 -0800185static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000186 jlong rendererPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800187 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guyf6a11b82010-06-23 17:47:49 -0700188 return renderer->getSaveCount();
Romain Guybb9524b2010-06-22 18:56:38 -0700189}
190
Romain Guy7d7b5492011-01-24 16:33:45 -0800191static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000192 jlong rendererPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800193 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guyf6a11b82010-06-23 17:47:49 -0700194 renderer->restore();
Romain Guybb9524b2010-06-22 18:56:38 -0700195}
196
Romain Guy7d7b5492011-01-24 16:33:45 -0800197static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000198 jlong rendererPtr, jint saveCount) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800199 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guyf6a11b82010-06-23 17:47:49 -0700200 renderer->restoreToCount(saveCount);
Romain Guybb9524b2010-06-22 18:56:38 -0700201}
202
203// ----------------------------------------------------------------------------
Romain Guybd6b79b2010-06-26 00:13:53 -0700204// Layers
205// ----------------------------------------------------------------------------
206
Romain Guy7d7b5492011-01-24 16:33:45 -0800207static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000208 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
209 jlong paintPtr, jint saveFlags) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800210 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
211 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guybd6b79b2010-06-26 00:13:53 -0700212 return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
213}
214
Romain Guy189887e2011-08-25 11:45:13 -0700215static jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000216 jlong rendererPtr, jlong paintPtr, jint saveFlags) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800217 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
218 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Chris Craik3f0854292014-04-15 16:18:08 -0700219 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
Romain Guy189887e2011-08-25 11:45:13 -0700220 return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
221 paint, saveFlags);
222}
223
Romain Guy7d7b5492011-01-24 16:33:45 -0800224static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000225 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
Romain Guybd6b79b2010-06-26 00:13:53 -0700226 jint alpha, jint saveFlags) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800227 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guybd6b79b2010-06-26 00:13:53 -0700228 return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
229}
230
Romain Guy189887e2011-08-25 11:45:13 -0700231static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000232 jlong rendererPtr, jint alpha, jint saveFlags) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800233 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Chris Craik3f0854292014-04-15 16:18:08 -0700234 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
Romain Guy189887e2011-08-25 11:45:13 -0700235 return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
236 alpha, saveFlags);
237}
238
Romain Guybd6b79b2010-06-26 00:13:53 -0700239// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -0700240// Clipping
241// ----------------------------------------------------------------------------
242
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000243static jboolean android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
244 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800245 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000246 const bool result = renderer->quickRejectConservative(left, top, right, bottom);
247 return result ? JNI_TRUE : JNI_FALSE;
Romain Guyc7d53492010-06-25 13:41:57 -0700248}
249
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000250static jboolean android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
251 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
252 jint op) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800253 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000254 const bool result = renderer->clipRect(left, top, right, bottom,
255 static_cast<SkRegion::Op>(op));
256 return result ? JNI_TRUE : JNI_FALSE;
Romain Guybb9524b2010-06-22 18:56:38 -0700257}
258
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000259static jboolean android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz,
260 jlong rendererPtr, jint left, jint top, jint right, jint bottom,
261 jint op) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800262 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000263 const bool result = renderer->clipRect(float(left), float(top), float(right),
264 float(bottom),
265 static_cast<SkRegion::Op>(op));
266 return result ? JNI_TRUE : JNI_FALSE;
Romain Guyf6a11b82010-06-23 17:47:49 -0700267}
Romain Guybb9524b2010-06-22 18:56:38 -0700268
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000269static jboolean android_view_GLES20Canvas_clipPath(JNIEnv* env, jobject clazz,
270 jlong rendererPtr, jlong pathPtr, jint op) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800271 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
272 SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000273 const bool result = renderer->clipPath(path, static_cast<SkRegion::Op>(op));
274 return result ? JNI_TRUE : JNI_FALSE;
Romain Guy735738c2012-12-03 12:34:51 -0800275}
276
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000277static jboolean android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz,
278 jlong rendererPtr, jlong regionPtr, jint op) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800279 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
280 SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000281 const bool result = renderer->clipRegion(region, static_cast<SkRegion::Op>(op));
282 return result ? JNI_TRUE : JNI_FALSE;
Romain Guy735738c2012-12-03 12:34:51 -0800283}
284
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000285static jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
286 jlong rendererPtr, jobject rect) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800287 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Chris Craik3f0854292014-04-15 16:18:08 -0700288 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
Romain Guy9d5316e2010-06-24 19:30:36 -0700289
Romain Guy7ae7ac42010-06-25 13:46:18 -0700290 env->CallVoidMethod(rect, gRectClassInfo.set,
291 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
Romain Guy9d5316e2010-06-24 19:30:36 -0700292
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000293 return !bounds.isEmpty() ? JNI_TRUE : JNI_FALSE;
Romain Guy9d5316e2010-06-24 19:30:36 -0700294}
295
Romain Guyf6a11b82010-06-23 17:47:49 -0700296// ----------------------------------------------------------------------------
297// Transforms
298// ----------------------------------------------------------------------------
299
Romain Guy7d7b5492011-01-24 16:33:45 -0800300static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000301 jlong rendererPtr, jfloat dx, jfloat dy) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800302 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy7ae7ac42010-06-25 13:46:18 -0700303 renderer->translate(dx, dy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700304}
305
Romain Guy7d7b5492011-01-24 16:33:45 -0800306static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000307 jlong rendererPtr, jfloat degrees) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800308 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy7ae7ac42010-06-25 13:46:18 -0700309 renderer->rotate(degrees);
Romain Guyf6a11b82010-06-23 17:47:49 -0700310}
311
Romain Guy7d7b5492011-01-24 16:33:45 -0800312static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000313 jlong rendererPtr, jfloat sx, jfloat sy) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800314 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy7ae7ac42010-06-25 13:46:18 -0700315 renderer->scale(sx, sy);
Romain Guyf6a11b82010-06-23 17:47:49 -0700316}
317
Romain Guy7d7b5492011-01-24 16:33:45 -0800318static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000319 jlong rendererPtr, jfloat sx, jfloat sy) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800320 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy807daf72011-01-18 11:19:19 -0800321 renderer->skew(sx, sy);
322}
323
Romain Guy7d7b5492011-01-24 16:33:45 -0800324static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000325 jlong rendererPtr, jlong matrixPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800326 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
327 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
Derek Sollenberger13908822013-12-10 12:28:58 -0500328 renderer->setMatrix(matrix ? *matrix : SkMatrix::I());
Romain Guyf6a11b82010-06-23 17:47:49 -0700329}
330
Romain Guy7d7b5492011-01-24 16:33:45 -0800331static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000332 jlong rendererPtr, jlong matrixPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800333 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
334 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
Romain Guy7ae7ac42010-06-25 13:46:18 -0700335 renderer->getMatrix(matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700336}
337
Romain Guy7d7b5492011-01-24 16:33:45 -0800338static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000339 jlong rendererPtr, jlong matrixPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800340 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
341 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
Derek Sollenberger13908822013-12-10 12:28:58 -0500342 renderer->concatMatrix(*matrix);
Romain Guybb9524b2010-06-22 18:56:38 -0700343}
344
345// ----------------------------------------------------------------------------
346// Drawing
Romain Guy85bf02f2010-06-22 13:11:24 -0700347// ----------------------------------------------------------------------------
348
Romain Guy7d7b5492011-01-24 16:33:45 -0800349static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000350 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
351 jfloat left, jfloat top, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800352 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
Chris Craik0c20c382013-07-02 10:48:54 -0700353 // This object allows the renderer to allocate a global JNI ref to the buffer object.
354 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
355
Chris Craik9f66ea02013-12-27 15:15:55 -0800356 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
357 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guydbd77cd2010-07-09 10:36:05 -0700358 renderer->drawBitmap(bitmap, left, top, paint);
Romain Guy85bf02f2010-06-22 13:11:24 -0700359}
360
Romain Guy7d7b5492011-01-24 16:33:45 -0800361static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000362 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
Romain Guyce0537b2010-06-29 21:05:21 -0700363 float srcLeft, float srcTop, float srcRight, float srcBottom,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000364 float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800365 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
Chris Craik0c20c382013-07-02 10:48:54 -0700366 // This object allows the renderer to allocate a global JNI ref to the buffer object.
367 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
368
Chris Craik9f66ea02013-12-27 15:15:55 -0800369 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
370 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guydbd77cd2010-07-09 10:36:05 -0700371 renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
372 dstLeft, dstTop, dstRight, dstBottom, paint);
Romain Guyf86ef572010-07-01 11:05:42 -0700373}
Romain Guy8ba548f2010-06-30 19:21:21 -0700374
Romain Guy7d7b5492011-01-24 16:33:45 -0800375static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000376 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
377 jlong matrixPtr, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800378 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
Chris Craik0c20c382013-07-02 10:48:54 -0700379 // This object allows the renderer to allocate a global JNI ref to the buffer object.
380 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
381
Chris Craik9f66ea02013-12-27 15:15:55 -0800382 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
383 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
384 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Derek Sollenberger13908822013-12-10 12:28:58 -0500385 renderer->drawBitmap(bitmap, *matrix, paint);
Romain Guyce0537b2010-06-29 21:05:21 -0700386}
387
Romain Guye651cc62012-05-14 19:44:40 -0700388static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000389 jlong rendererPtr, jintArray colors, jint offset, jint stride,
390 jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) {
Mike Reedb9330552014-06-16 17:31:48 -0400391 const SkImageInfo info = SkImageInfo::Make(width, height,
392 hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType,
393 kPremul_SkAlphaType);
Romain Guy49c5fc02012-05-15 11:10:01 -0700394 SkBitmap* bitmap = new SkBitmap;
Mike Reedb9330552014-06-16 17:31:48 -0400395 if (!bitmap->allocPixels(info)) {
Romain Guy49c5fc02012-05-15 11:10:01 -0700396 delete bitmap;
Romain Guye651cc62012-05-14 19:44:40 -0700397 return;
398 }
399
Chris Craik1abf5d62013-08-16 12:47:03 -0700400 if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap, true)) {
Romain Guy49c5fc02012-05-15 11:10:01 -0700401 delete bitmap;
Romain Guye651cc62012-05-14 19:44:40 -0700402 return;
403 }
404
Chris Craik9f66ea02013-12-27 15:15:55 -0800405 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
406 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy49c5fc02012-05-15 11:10:01 -0700407 renderer->drawBitmapData(bitmap, left, top, paint);
408
409 // If the renderer is a deferred renderer it will own the bitmap
Chris Craikb4589422013-12-26 15:13:13 -0800410 if (!renderer->isRecording()) {
Romain Guy49c5fc02012-05-15 11:10:01 -0700411 delete bitmap;
412 }
Romain Guye651cc62012-05-14 19:44:40 -0700413}
414
Romain Guy7d7b5492011-01-24 16:33:45 -0800415static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000416 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
Chris Craik0c20c382013-07-02 10:48:54 -0700417 jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000418 jint colorOffset, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800419 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
Chris Craik0c20c382013-07-02 10:48:54 -0700420 // This object allows the renderer to allocate a global JNI ref to the buffer object.
421 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
422
Romain Guy5a7b4662011-01-20 19:09:30 -0800423 jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
424 jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
425
Chris Craik9f66ea02013-12-27 15:15:55 -0800426 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
427 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy5a7b4662011-01-20 19:09:30 -0800428 renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint);
429
430 if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0);
431 if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0);
432}
433
Romain Guy7d7b5492011-01-24 16:33:45 -0800434static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000435 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr,
436 float left, float top, float right, float bottom, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800437 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
Chris Craik0c20c382013-07-02 10:48:54 -0700438 // This object allows the renderer to allocate a global JNI ref to the buffer object.
439 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
440
Chris Craik9f66ea02013-12-27 15:15:55 -0800441 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
442 Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr);
443 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy3b748a42013-04-17 18:54:38 -0700444 renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
Romain Guydeba7852010-07-07 17:54:48 -0700445}
446
Romain Guy7d7b5492011-01-24 16:33:45 -0800447static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000448 jlong rendererPtr, jint color, jint mode) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800449 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000450 renderer->drawColor(color, static_cast<SkXfermode::Mode>(mode));
Romain Guyce0537b2010-06-29 21:05:21 -0700451}
452
Romain Guy7d7b5492011-01-24 16:33:45 -0800453static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000454 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
455 jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800456 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
457 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guyc7d53492010-06-25 13:41:57 -0700458 renderer->drawRect(left, top, right, bottom, paint);
459}
460
Romain Guy7d7b5492011-01-24 16:33:45 -0800461static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000462 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
463 jfloat rx, jfloat ry, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800464 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
465 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy01d58e42011-01-19 21:54:02 -0800466 renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
467}
468
Romain Guy7d7b5492011-01-24 16:33:45 -0800469static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000470 jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800471 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
472 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy01d58e42011-01-19 21:54:02 -0800473 renderer->drawCircle(x, y, radius, paint);
474}
475
John Reck52244ff2014-05-01 21:27:37 -0700476static void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz,
477 jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
478 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
479 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
480 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
481 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
482 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
483 renderer->drawCircle(xProp, yProp, radiusProp, paintProp);
484}
485
Romain Guy7d7b5492011-01-24 16:33:45 -0800486static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000487 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
488 jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800489 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
490 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guyc1cd9ba32011-01-23 14:18:41 -0800491 renderer->drawOval(left, top, right, bottom, paint);
492}
493
Romain Guy7d7b5492011-01-24 16:33:45 -0800494static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000495 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
496 jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800497 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
498 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy8b2f5262011-01-23 16:15:02 -0800499 renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
500}
501
Romain Guy672433d2013-01-04 19:05:13 -0800502static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000503 jlong rendererPtr, jlong regionPtr, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800504 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
505 SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
506 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy672433d2013-01-04 19:05:13 -0800507 if (paint->getStyle() != SkPaint::kFill_Style ||
508 (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) {
509 SkRegion::Iterator it(*region);
510 while (!it.done()) {
511 const SkIRect& r = it.rect();
512 renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
513 it.next();
514 }
515 } else {
516 int count = 0;
517 Vector<float> rects;
518 SkRegion::Iterator it(*region);
519 while (!it.done()) {
520 const SkIRect& r = it.rect();
521 rects.push(r.fLeft);
522 rects.push(r.fTop);
523 rects.push(r.fRight);
524 rects.push(r.fBottom);
Chris Craik2af46352012-11-26 18:30:17 -0800525 count += 4;
Romain Guy672433d2013-01-04 19:05:13 -0800526 it.next();
527 }
528 renderer->drawRects(rects.array(), count, paint);
Romain Guya48a1a82010-08-10 14:59:15 -0700529 }
530}
531
Romain Guyed6fcb02011-03-21 13:11:28 -0700532static void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000533 jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800534 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guyed6fcb02011-03-21 13:11:28 -0700535 jfloat* storage = env->GetFloatArrayElements(points, NULL);
Chris Craik9f66ea02013-12-27 15:15:55 -0800536 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guyed6fcb02011-03-21 13:11:28 -0700537 renderer->drawPoints(storage + offset, count, paint);
538 env->ReleaseFloatArrayElements(points, storage, 0);
539}
540
Romain Guy7d7b5492011-01-24 16:33:45 -0800541static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000542 jlong rendererPtr, jlong pathPtr, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800543 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
544 SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
545 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy7fbcc042010-08-04 15:40:07 -0700546 renderer->drawPath(path, paint);
547}
548
Romain Guy7d7b5492011-01-24 16:33:45 -0800549static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000550 jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800551 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy759ea802010-09-16 20:49:46 -0700552 jfloat* storage = env->GetFloatArrayElements(points, NULL);
Chris Craik9f66ea02013-12-27 15:15:55 -0800553 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Romain Guy759ea802010-09-16 20:49:46 -0700554 renderer->drawLines(storage + offset, count, paint);
Romain Guy759ea802010-09-16 20:49:46 -0700555 env->ReleaseFloatArrayElements(points, storage, 0);
556}
557
Romain Guy85bf02f2010-06-22 13:11:24 -0700558// ----------------------------------------------------------------------------
Romain Guy5ff9df62012-01-23 17:09:05 -0800559// Draw filters
560// ----------------------------------------------------------------------------
561
562static void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000563 jlong rendererPtr, jint clearBits, jint setBits) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800564 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy5ff9df62012-01-23 17:09:05 -0800565 renderer->setupPaintFilter(clearBits, setBits);
566}
567
568static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000569 jlong rendererPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800570 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy5ff9df62012-01-23 17:09:05 -0800571 renderer->resetPaintFilter();
572}
573
574// ----------------------------------------------------------------------------
Romain Guya1db5742010-07-20 13:09:13 -0700575// Text
576// ----------------------------------------------------------------------------
577
Raph Levienf2114d52014-06-01 15:54:47 -0700578// TODO: this is moving to MinikinUtils, remove with USE_MINIKIN ifdef
Chris Craik41541822013-05-03 16:35:54 -0700579static float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) {
580 switch (paint->getTextAlign()) {
581 case SkPaint::kCenter_Align:
582 return -totalAdvance / 2.0f;
583 break;
584 case SkPaint::kRight_Align:
585 return -totalAdvance;
586 break;
587 default:
588 break;
589 }
590 return 0;
591}
592
Raph Levien1a73f7322014-01-30 16:06:28 -0800593#ifdef USE_MINIKIN
Raph Levienf2114d52014-06-01 15:54:47 -0700594
595class RenderTextFunctor {
596public:
597 RenderTextFunctor(const Layout& layout, OpenGLRenderer* renderer, jfloat x, jfloat y,
598 SkPaint* paint, uint16_t* glyphs, float* pos, float totalAdvance,
599 uirenderer::Rect& bounds)
600 : layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs),
601 pos(pos), totalAdvance(totalAdvance), bounds(bounds) { }
Raph Levien1fc0fa82014-06-06 18:05:22 -0700602 void operator()(size_t start, size_t end) {
Raph Levienf2114d52014-06-01 15:54:47 -0700603 for (size_t i = start; i < end; i++) {
604 glyphs[i] = layout.getGlyphId(i);
605 pos[2 * i] = layout.getX(i);
606 pos[2 * i + 1] = layout.getY(i);
607 }
Raph Levienf2114d52014-06-01 15:54:47 -0700608 size_t glyphsCount = end - start;
609 int bytesCount = glyphsCount * sizeof(jchar);
610 renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
611 x, y, pos + 2 * start, paint, totalAdvance, bounds);
612 }
613private:
614 const Layout& layout;
615 OpenGLRenderer* renderer;
616 jfloat x;
617 jfloat y;
618 SkPaint* paint;
619 uint16_t* glyphs;
620 float* pos;
621 float totalAdvance;
622 uirenderer::Rect& bounds;
623};
624
Raph Levien1a73f7322014-01-30 16:06:28 -0800625static void renderTextLayout(OpenGLRenderer* renderer, Layout* layout,
626 jfloat x, jfloat y, SkPaint* paint) {
627 size_t nGlyphs = layout->nGlyphs();
628 float* pos = new float[nGlyphs * 2];
629 uint16_t* glyphs = new uint16_t[nGlyphs];
Raph Levien1a73f7322014-01-30 16:06:28 -0800630 MinikinRect b;
631 layout->getBounds(&b);
632 android::uirenderer::Rect bounds(b.mLeft, b.mTop, b.mRight, b.mBottom);
633 bounds.translate(x, y);
634 float totalAdvance = layout->getAdvance();
635
Raph Levienf2114d52014-06-01 15:54:47 -0700636 RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds);
Raph Levien1fc0fa82014-06-06 18:05:22 -0700637 MinikinUtils::forFontRun(*layout, paint, f);
Raph Levien1a73f7322014-01-30 16:06:28 -0800638 delete[] glyphs;
639 delete[] pos;
640}
641#endif
642
Romain Guye8e62a42010-07-23 18:55:21 -0700643static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
Raph Levien051910b2014-06-15 18:25:29 -0700644 jfloat x, jfloat y, int bidiFlags, SkPaint* paint, TypefaceImpl* typeface) {
Raph Levien1a73f7322014-01-30 16:06:28 -0800645#ifdef USE_MINIKIN
646 Layout layout;
Raph Levien051910b2014-06-15 18:25:29 -0700647 std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
Raph Levien6bfd7e72014-06-04 14:48:02 -0700648 layout.doLayout(text, 0, count, count, css);
Raph Levien1a73f7322014-01-30 16:06:28 -0800649 x += xOffsetForTextAlign(paint, layout.getAdvance());
650 renderTextLayout(renderer, &layout, x, y, paint);
651#else
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800652 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
Raph Levien051910b2014-06-15 18:25:29 -0700653 text, 0, count, count, bidiFlags);
Fabrice Di Meglio2ea758802011-05-12 17:42:06 -0700654 if (value == NULL) {
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800655 return;
Fabrice Di Meglio2ea758802011-05-12 17:42:06 -0700656 }
Fabrice Di Meglio5c863f72011-10-05 18:11:59 -0700657 const jchar* glyphs = value->getGlyphs();
658 size_t glyphsCount = value->getGlyphsCount();
Raph Levien996e57c2012-07-23 15:22:52 -0700659 jfloat totalAdvance = value->getTotalAdvance();
Romain Guyb15b4462013-08-12 13:25:29 -0700660 x += xOffsetForTextAlign(paint, totalAdvance);
Raph Levien996e57c2012-07-23 15:22:52 -0700661 const float* positions = value->getPos();
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700662 int bytesCount = glyphsCount * sizeof(jchar);
Chris Craik41541822013-05-03 16:35:54 -0700663 const SkRect& r = value->getBounds();
664 android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
Chris Craikf09b7462013-06-17 15:17:11 -0700665 bounds.translate(x, y);
Chris Craik41541822013-05-03 16:35:54 -0700666
667 renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
Romain Guyb15b4462013-08-12 13:25:29 -0700668 x, y, positions, paint, totalAdvance, bounds);
Raph Levien1a73f7322014-01-30 16:06:28 -0800669#endif
Romain Guye8e62a42010-07-23 18:55:21 -0700670}
671
Raph Levien9d2b5e12014-06-15 23:53:57 -0700672#ifdef USE_MINIKIN
673class RenderTextOnPathFunctor {
674public:
675 RenderTextOnPathFunctor(const Layout& layout, OpenGLRenderer* renderer, float hOffset,
676 float vOffset, SkPaint* paint, SkPath* path)
677 : layout(layout), renderer(renderer), hOffset(hOffset), vOffset(vOffset),
678 paint(paint), path(path) {
679 }
680 void operator()(size_t start, size_t end) {
681 uint16_t glyphs[1];
682 for (size_t i = start; i < end; i++) {
683 glyphs[0] = layout.getGlyphId(i);
684 float x = hOffset + layout.getX(i);
685 float y = vOffset + layout.getY(i);
686 renderer->drawTextOnPath((const char*) glyphs, sizeof(glyphs), 1, path, x, y, paint);
687 }
688 }
689private:
690 const Layout& layout;
691 OpenGLRenderer* renderer;
692 float hOffset;
693 float vOffset;
694 SkPaint* paint;
695 SkPath* path;
696};
697#endif
698
Romain Guy325740f2012-02-24 16:48:34 -0800699static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700700 SkPath* path, jfloat hOffset, jfloat vOffset, int bidiFlags, SkPaint* paint,
701 TypefaceImpl* typeface) {
702#ifdef USE_MINIKIN
703 Layout layout;
704 std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
705 layout.doLayout(text, 0, count, count, css);
706 hOffset += MinikinUtils::hOffsetForTextAlign(paint, layout, *path);
707 SkPaint::Align align = paint->getTextAlign();
708 paint->setTextAlign(SkPaint::kLeft_Align);
709
710 RenderTextOnPathFunctor f(layout, renderer, hOffset, vOffset, paint, path);
711 MinikinUtils::forFontRun(layout, paint, f);
712 paint->setTextAlign(align);
713#else
Romain Guy325740f2012-02-24 16:48:34 -0800714 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
Raph Levien051910b2014-06-15 18:25:29 -0700715 text, 0, count, count, bidiFlags);
Romain Guy325740f2012-02-24 16:48:34 -0800716 if (value == NULL) {
717 return;
718 }
719 const jchar* glyphs = value->getGlyphs();
720 size_t glyphsCount = value->getGlyphsCount();
721 int bytesCount = glyphsCount * sizeof(jchar);
722 renderer->drawTextOnPath((const char*) glyphs, bytesCount, glyphsCount, path,
723 hOffset, vOffset, paint);
Raph Levien9d2b5e12014-06-15 23:53:57 -0700724#endif
Romain Guy325740f2012-02-24 16:48:34 -0800725}
726
Romain Guy61c8c9c2010-08-09 20:48:09 -0700727static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
728 jint start, jint count, jint contextCount, jfloat x, jfloat y,
Raph Levien051910b2014-06-15 18:25:29 -0700729 int bidiFlags, SkPaint* paint, TypefaceImpl* typeface) {
Raph Levien1a73f7322014-01-30 16:06:28 -0800730#ifdef USE_MINIKIN
731 Layout layout;
Raph Levien051910b2014-06-15 18:25:29 -0700732 std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
Raph Levien6bfd7e72014-06-04 14:48:02 -0700733 layout.doLayout(text, start, count, contextCount, css);
Raph Levien1a73f7322014-01-30 16:06:28 -0800734 x += xOffsetForTextAlign(paint, layout.getAdvance());
735 renderTextLayout(renderer, &layout, x, y, paint);
736#else
Fabrice Di Meglioa731b082012-01-23 18:18:45 -0800737 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
Raph Levien051910b2014-06-15 18:25:29 -0700738 text, start, count, contextCount, bidiFlags);
Fabrice Di Meglio2ea758802011-05-12 17:42:06 -0700739 if (value == NULL) {
Fabrice Di Megliob02d0ca2011-12-08 14:05:44 -0800740 return;
Fabrice Di Meglio2ea758802011-05-12 17:42:06 -0700741 }
Fabrice Di Meglio5c863f72011-10-05 18:11:59 -0700742 const jchar* glyphs = value->getGlyphs();
743 size_t glyphsCount = value->getGlyphsCount();
Raph Levien996e57c2012-07-23 15:22:52 -0700744 jfloat totalAdvance = value->getTotalAdvance();
Romain Guyb15b4462013-08-12 13:25:29 -0700745 x += xOffsetForTextAlign(paint, totalAdvance);
Raph Levien996e57c2012-07-23 15:22:52 -0700746 const float* positions = value->getPos();
Fabrice Di Meglio79df5322011-09-19 15:17:56 -0700747 int bytesCount = glyphsCount * sizeof(jchar);
Chris Craik41541822013-05-03 16:35:54 -0700748 const SkRect& r = value->getBounds();
749 android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
Chris Craikf09b7462013-06-17 15:17:11 -0700750 bounds.translate(x, y);
Chris Craik41541822013-05-03 16:35:54 -0700751
752 renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
Romain Guyb15b4462013-08-12 13:25:29 -0700753 x, y, positions, paint, totalAdvance, bounds);
Raph Levien1a73f7322014-01-30 16:06:28 -0800754#endif
Romain Guy61c8c9c2010-08-09 20:48:09 -0700755}
756
Romain Guy7d7b5492011-01-24 16:33:45 -0800757static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000758 jlong rendererPtr, jcharArray text, jint index, jint count,
Raph Levien051910b2014-06-15 18:25:29 -0700759 jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800760 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guya1db5742010-07-20 13:09:13 -0700761 jchar* textArray = env->GetCharArrayElements(text, NULL);
Chris Craik9f66ea02013-12-27 15:15:55 -0800762 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Raph Levien1a73f7322014-01-30 16:06:28 -0800763 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
Chris Craik9f66ea02013-12-27 15:15:55 -0800764
Raph Levien051910b2014-06-15 18:25:29 -0700765 renderText(renderer, textArray + index, count, x, y, bidiFlags, paint, typeface);
Romain Guya1db5742010-07-20 13:09:13 -0700766 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
767}
768
Romain Guy7d7b5492011-01-24 16:33:45 -0800769static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000770 jlong rendererPtr, jstring text, jint start, jint end,
Raph Levien051910b2014-06-15 18:25:29 -0700771 jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800772 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guya1db5742010-07-20 13:09:13 -0700773 const jchar* textArray = env->GetStringChars(text, NULL);
Chris Craik9f66ea02013-12-27 15:15:55 -0800774 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Raph Levien1a73f7322014-01-30 16:06:28 -0800775 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
Chris Craik9f66ea02013-12-27 15:15:55 -0800776
Raph Levien051910b2014-06-15 18:25:29 -0700777 renderText(renderer, textArray + start, end - start, x, y, bidiFlags, paint, typeface);
Romain Guya1db5742010-07-20 13:09:13 -0700778 env->ReleaseStringChars(text, textArray);
779}
780
Romain Guy325740f2012-02-24 16:48:34 -0800781static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000782 jlong rendererPtr, jcharArray text, jint index, jint count,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700783 jlong pathPtr, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintPtr,
784 jlong typefacePtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800785 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy325740f2012-02-24 16:48:34 -0800786 jchar* textArray = env->GetCharArrayElements(text, NULL);
Chris Craik9f66ea02013-12-27 15:15:55 -0800787 SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
788 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Raph Levien9d2b5e12014-06-15 23:53:57 -0700789 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
Chris Craik9f66ea02013-12-27 15:15:55 -0800790
Romain Guy325740f2012-02-24 16:48:34 -0800791 renderTextOnPath(renderer, textArray + index, count, path,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700792 hOffset, vOffset, bidiFlags, paint, typeface);
Romain Guy325740f2012-02-24 16:48:34 -0800793 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
794}
795
796static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000797 jlong rendererPtr, jstring text, jint start, jint end,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700798 jlong pathPtr, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintPtr,
799 jlong typefacePtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800800 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy325740f2012-02-24 16:48:34 -0800801 const jchar* textArray = env->GetStringChars(text, NULL);
Chris Craik9f66ea02013-12-27 15:15:55 -0800802 SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
803 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Raph Levien9d2b5e12014-06-15 23:53:57 -0700804 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
Chris Craik9f66ea02013-12-27 15:15:55 -0800805
Romain Guy325740f2012-02-24 16:48:34 -0800806 renderTextOnPath(renderer, textArray + start, end - start, path,
Raph Levien9d2b5e12014-06-15 23:53:57 -0700807 hOffset, vOffset, bidiFlags, paint, typeface);
Romain Guy325740f2012-02-24 16:48:34 -0800808 env->ReleaseStringChars(text, textArray);
809}
810
Romain Guy7d7b5492011-01-24 16:33:45 -0800811static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000812 jlong rendererPtr, jcharArray text, jint index, jint count,
Raph Levien051910b2014-06-15 18:25:29 -0700813 jint contextIndex, jint contextCount, jfloat x, jfloat y, jboolean isRtl,
Raph Levien1a73f7322014-01-30 16:06:28 -0800814 jlong paintPtr, jlong typefacePtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800815 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700816 jchar* textArray = env->GetCharArrayElements(text, NULL);
Chris Craik9f66ea02013-12-27 15:15:55 -0800817 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Raph Levien1a73f7322014-01-30 16:06:28 -0800818 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
Chris Craik9f66ea02013-12-27 15:15:55 -0800819
Raph Levien051910b2014-06-15 18:25:29 -0700820 int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
Romain Guy61c8c9c2010-08-09 20:48:09 -0700821 renderTextRun(renderer, textArray + contextIndex, index - contextIndex,
Raph Levien051910b2014-06-15 18:25:29 -0700822 count, contextCount, x, y, bidiFlags, paint, typeface);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700823 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
824 }
825
Romain Guy7d7b5492011-01-24 16:33:45 -0800826static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000827 jlong rendererPtr, jstring text, jint start, jint end,
Raph Levien051910b2014-06-15 18:25:29 -0700828 jint contextStart, int contextEnd, jfloat x, jfloat y, jboolean isRtl,
Raph Levien1a73f7322014-01-30 16:06:28 -0800829 jlong paintPtr, jlong typefacePtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800830 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700831 const jchar* textArray = env->GetStringChars(text, NULL);
832 jint count = end - start;
833 jint contextCount = contextEnd - contextStart;
Chris Craik9f66ea02013-12-27 15:15:55 -0800834 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
Raph Levien1a73f7322014-01-30 16:06:28 -0800835 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
Chris Craik9f66ea02013-12-27 15:15:55 -0800836
Raph Levien051910b2014-06-15 18:25:29 -0700837 int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
Romain Guy61c8c9c2010-08-09 20:48:09 -0700838 renderTextRun(renderer, textArray + contextStart, start - contextStart,
Raph Levien051910b2014-06-15 18:25:29 -0700839 count, contextCount, x, y, bidiFlags, paint, typeface);
Romain Guy61c8c9c2010-08-09 20:48:09 -0700840 env->ReleaseStringChars(text, textArray);
841}
842
Romain Guyb051e892010-09-28 19:09:36 -0700843// ----------------------------------------------------------------------------
844// Display lists
845// ----------------------------------------------------------------------------
846
John Reck44fd8d22014-02-26 11:00:11 -0800847static jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000848 jobject clazz, jlong rendererPtr) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800849 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
John Reck44fd8d22014-02-26 11:00:11 -0800850 return reinterpret_cast<jlong>(renderer->finishRecording());
851}
852
Chris Craik3f0854292014-04-15 16:18:08 -0700853static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env, jobject clazz) {
John Reck44fd8d22014-02-26 11:00:11 -0800854 return reinterpret_cast<jlong>(new DisplayListRenderer);
Chet Haase5977baa2011-01-05 18:01:22 -0800855}
856
Chris Craika7090e02014-06-20 16:01:00 -0700857static jint android_view_GLES20Canvas_drawRenderNode(JNIEnv* env,
858 jobject clazz, jlong rendererPtr, jlong renderNodePtr,
Chet Haase1271e2c2012-04-20 09:54:27 -0700859 jobject dirty, jint flags) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800860 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
Chris Craika7090e02014-06-20 16:01:00 -0700861 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
Romain Guycabfcc12011-03-07 18:06:46 -0800862 android::uirenderer::Rect bounds;
Chris Craika7090e02014-06-20 16:01:00 -0700863 status_t status = renderer->drawRenderNode(renderNode, bounds, flags);
Romain Guy65549432012-03-26 16:45:05 -0700864 if (status != DrawGlInfo::kStatusDone && dirty != NULL) {
Romain Guycabfcc12011-03-07 18:06:46 -0800865 env->CallVoidMethod(dirty, gRectClassInfo.set,
866 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
867 }
Romain Guy65549432012-03-26 16:45:05 -0700868 return status;
Romain Guyb051e892010-09-28 19:09:36 -0700869}
870
Romain Guy6c319ca2011-01-11 14:29:25 -0800871// ----------------------------------------------------------------------------
872// Layers
873// ----------------------------------------------------------------------------
874
Romain Guy7d7b5492011-01-24 16:33:45 -0800875static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000876 jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) {
Chris Craik9f66ea02013-12-27 15:15:55 -0800877 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
878 Layer* layer = reinterpret_cast<Layer*>(layerPtr);
Chris Craika08f95c2013-03-15 17:24:33 -0700879 renderer->drawLayer(layer, x, y);
Romain Guy6c319ca2011-01-11 14:29:25 -0800880}
881
Romain Guy16393512010-08-08 00:14:31 -0700882#endif // USE_OPENGL_RENDERER
883
884// ----------------------------------------------------------------------------
885// Common
886// ----------------------------------------------------------------------------
887
888static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz) {
889#ifdef USE_OPENGL_RENDERER
Jesse Hall44063452011-12-01 11:27:45 -0800890 char prop[PROPERTY_VALUE_MAX];
891 if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
892 // not in the emulator
893 return JNI_TRUE;
894 }
895 // In the emulator this property will be set to 1 when hardware GLES is
896 // enabled, 0 otherwise. On old emulator versions it will be undefined.
897 property_get("ro.kernel.qemu.gles", prop, "0");
898 return atoi(prop) == 1 ? JNI_TRUE : JNI_FALSE;
Romain Guy16393512010-08-08 00:14:31 -0700899#else
900 return JNI_FALSE;
901#endif
902}
903
Romain Guya1db5742010-07-20 13:09:13 -0700904// ----------------------------------------------------------------------------
Chet Haase9c1e23b2011-03-24 10:51:31 -0700905// Logging
906// ----------------------------------------------------------------------------
907
Chet Haase9c1e23b2011-03-24 10:51:31 -0700908static void
Romain Guy65b345f2011-07-27 18:51:50 -0700909android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
Chet Haase905787a2011-04-01 14:33:02 -0700910#ifdef USE_OPENGL_RENDERER
Elliott Hughesa3804cf2011-04-11 16:50:19 -0700911 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
John Recke18264b2014-03-12 13:56:30 -0700912 android::uirenderer::RenderNode::outputLogBuffer(fd);
Chet Haase905787a2011-04-01 14:33:02 -0700913#endif // USE_OPENGL_RENDERER
Chet Haase9c1e23b2011-03-24 10:51:31 -0700914}
915
916// ----------------------------------------------------------------------------
Romain Guye4d01122010-06-16 18:44:05 -0700917// JNI Glue
918// ----------------------------------------------------------------------------
919
920const char* const kClassPathName = "android/view/GLES20Canvas";
921
922static JNINativeMethod gMethods[] = {
Romain Guy61c8c9c2010-08-09 20:48:09 -0700923 { "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable },
924
Romain Guy16393512010-08-08 00:14:31 -0700925#ifdef USE_OPENGL_RENDERER
Romain Guy7d7b5492011-01-24 16:33:45 -0800926
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000927 { "nDestroyRenderer", "(J)V", (void*) android_view_GLES20Canvas_destroyRenderer },
928 { "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport },
929 { "nPrepare", "(JZ)I", (void*) android_view_GLES20Canvas_prepare },
930 { "nPrepareDirty", "(JIIIIZ)I", (void*) android_view_GLES20Canvas_prepareDirty },
931 { "nFinish", "(J)V", (void*) android_view_GLES20Canvas_finish },
Chris Craikba9b6132013-12-15 17:10:19 -0800932 { "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V",
933 (void*) android_view_GLES20Canvas_setProperty },
Romain Guy16393512010-08-08 00:14:31 -0700934
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000935 { "nCallDrawGLFunction", "(JJ)I", (void*) android_view_GLES20Canvas_callDrawGLFunction },
Romain Guy7d7b5492011-01-24 16:33:45 -0800936
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000937 { "nSave", "(JI)I", (void*) android_view_GLES20Canvas_save },
938 { "nRestore", "(J)V", (void*) android_view_GLES20Canvas_restore },
939 { "nRestoreToCount", "(JI)V", (void*) android_view_GLES20Canvas_restoreToCount },
940 { "nGetSaveCount", "(J)I", (void*) android_view_GLES20Canvas_getSaveCount },
Romain Guy85bf02f2010-06-22 13:11:24 -0700941
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000942 { "nSaveLayer", "(JFFFFJI)I", (void*) android_view_GLES20Canvas_saveLayer },
943 { "nSaveLayer", "(JJI)I", (void*) android_view_GLES20Canvas_saveLayerClip },
944 { "nSaveLayerAlpha", "(JFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha },
945 { "nSaveLayerAlpha", "(JII)I", (void*) android_view_GLES20Canvas_saveLayerAlphaClip },
Romain Guybb9524b2010-06-22 18:56:38 -0700946
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000947 { "nQuickReject", "(JFFFF)Z", (void*) android_view_GLES20Canvas_quickReject },
948 { "nClipRect", "(JFFFFI)Z", (void*) android_view_GLES20Canvas_clipRectF },
949 { "nClipRect", "(JIIIII)Z", (void*) android_view_GLES20Canvas_clipRect },
950 { "nClipPath", "(JJI)Z", (void*) android_view_GLES20Canvas_clipPath },
951 { "nClipRegion", "(JJI)Z", (void*) android_view_GLES20Canvas_clipRegion },
Romain Guyc7d53492010-06-25 13:41:57 -0700952
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000953 { "nTranslate", "(JFF)V", (void*) android_view_GLES20Canvas_translate },
954 { "nRotate", "(JF)V", (void*) android_view_GLES20Canvas_rotate },
955 { "nScale", "(JFF)V", (void*) android_view_GLES20Canvas_scale },
956 { "nSkew", "(JFF)V", (void*) android_view_GLES20Canvas_skew },
Romain Guyc7d53492010-06-25 13:41:57 -0700957
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000958 { "nSetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_setMatrix },
959 { "nGetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_getMatrix },
960 { "nConcatMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_concatMatrix },
Romain Guyc7d53492010-06-25 13:41:57 -0700961
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000962 { "nDrawBitmap", "(JJ[BFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap },
963 { "nDrawBitmap", "(JJ[BFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
964 { "nDrawBitmap", "(JJ[BJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
965 { "nDrawBitmap", "(J[IIIFFIIZJ)V", (void*) android_view_GLES20Canvas_drawBitmapData },
Romain Guy5a7b4662011-01-20 19:09:30 -0800966
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000967 { "nDrawBitmapMesh", "(JJ[BII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
Romain Guy5a7b4662011-01-20 19:09:30 -0800968
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000969 { "nDrawPatch", "(JJ[BJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch },
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800970
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000971 { "nDrawColor", "(JII)V", (void*) android_view_GLES20Canvas_drawColor },
972 { "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect },
973 { "nDrawRects", "(JJJ)V", (void*) android_view_GLES20Canvas_drawRegionAsRects },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000974 { "nDrawRoundRect", "(JFFFFFFJ)V", (void*) android_view_GLES20Canvas_drawRoundRect },
975 { "nDrawCircle", "(JFFFJ)V", (void*) android_view_GLES20Canvas_drawCircle },
John Reck52244ff2014-05-01 21:27:37 -0700976 { "nDrawCircle", "(JJJJJ)V", (void*) android_view_GLES20Canvas_drawCircleProps },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000977 { "nDrawOval", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawOval },
978 { "nDrawArc", "(JFFFFFFZJ)V", (void*) android_view_GLES20Canvas_drawArc },
979 { "nDrawPoints", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawPoints },
Romain Guy8b2f5262011-01-23 16:15:02 -0800980
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000981 { "nDrawPath", "(JJJ)V", (void*) android_view_GLES20Canvas_drawPath },
982 { "nDrawLines", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawLines },
Romain Guybd6b79b2010-06-26 00:13:53 -0700983
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000984 { "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter },
985 { "nResetPaintFilter", "(J)V", (void*) android_view_GLES20Canvas_resetPaintFilter },
Romain Guy5ff9df62012-01-23 17:09:05 -0800986
Raph Levien1a73f7322014-01-30 16:06:28 -0800987 { "nDrawText", "(J[CIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArray },
988 { "nDrawText", "(JLjava/lang/String;IIFFIJJ)V",
Romain Guya1db5742010-07-20 13:09:13 -0700989 (void*) android_view_GLES20Canvas_drawText },
990
Raph Levien9d2b5e12014-06-15 23:53:57 -0700991 { "nDrawTextOnPath", "(J[CIIJFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath },
992 { "nDrawTextOnPath", "(JLjava/lang/String;IIJFFIJJ)V",
Romain Guy325740f2012-02-24 16:48:34 -0800993 (void*) android_view_GLES20Canvas_drawTextOnPath },
994
Raph Levien051910b2014-06-15 18:25:29 -0700995 { "nDrawTextRun", "(J[CIIIIFFZJJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
996 { "nDrawTextRun", "(JLjava/lang/String;IIIIFFZJJ)V",
Romain Guy61c8c9c2010-08-09 20:48:09 -0700997 (void*) android_view_GLES20Canvas_drawTextRun },
998
Chris Craika7090e02014-06-20 16:01:00 -0700999 { "nGetClipBounds", "(JLandroid/graphics/Rect;)Z", (void*) android_view_GLES20Canvas_getClipBounds },
Romain Guyb051e892010-09-28 19:09:36 -07001000
Chris Craika7090e02014-06-20 16:01:00 -07001001 { "nFinishRecording", "(J)J", (void*) android_view_GLES20Canvas_finishRecording },
1002 { "nDrawRenderNode", "(JJLandroid/graphics/Rect;I)I", (void*) android_view_GLES20Canvas_drawRenderNode },
Romain Guy13631f32012-01-30 17:41:55 -08001003
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001004 { "nCreateDisplayListRenderer", "()J", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
Romain Guy13631f32012-01-30 17:41:55 -08001005
Ashok Bhat36bef0b2014-01-20 20:08:01 +00001006 { "nDrawLayer", "(JJFF)V", (void*) android_view_GLES20Canvas_drawLayer },
Romain Guyb051e892010-09-28 19:09:36 -07001007
Romain Guyf61970fc2011-07-07 14:10:06 -07001008 { "nGetMaximumTextureWidth", "()I", (void*) android_view_GLES20Canvas_getMaxTextureWidth },
1009 { "nGetMaximumTextureHeight", "()I", (void*) android_view_GLES20Canvas_getMaxTextureHeight },
1010
Romain Guy16393512010-08-08 00:14:31 -07001011#endif
Romain Guye4d01122010-06-16 18:44:05 -07001012};
1013
Chet Haase9c1e23b2011-03-24 10:51:31 -07001014static JNINativeMethod gActivityThreadMethods[] = {
1015 { "dumpGraphicsInfo", "(Ljava/io/FileDescriptor;)V",
1016 (void*) android_app_ActivityThread_dumpGraphics }
1017};
1018
1019
Romain Guy16393512010-08-08 00:14:31 -07001020#ifdef USE_OPENGL_RENDERER
1021 #define FIND_CLASS(var, className) \
1022 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001023 LOG_FATAL_IF(! var, "Unable to find class " className);
1024
Romain Guy16393512010-08-08 00:14:31 -07001025 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1026 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1027 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1028#else
1029 #define FIND_CLASS(var, className)
1030 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
1031#endif
Romain Guy9d5316e2010-06-24 19:30:36 -07001032
Romain Guye4d01122010-06-16 18:44:05 -07001033int register_android_view_GLES20Canvas(JNIEnv* env) {
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001034 jclass clazz;
1035 FIND_CLASS(clazz, "android/graphics/Rect");
1036 GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
Romain Guy9d5316e2010-06-24 19:30:36 -07001037
Romain Guye4d01122010-06-16 18:44:05 -07001038 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
1039}
1040
Chet Haase9c1e23b2011-03-24 10:51:31 -07001041const char* const kActivityThreadPathName = "android/app/ActivityThread";
1042
Romain Guy6be3d552011-07-14 18:08:37 -07001043int register_android_app_ActivityThread(JNIEnv* env) {
1044 return AndroidRuntime::registerNativeMethods(env, kActivityThreadPathName,
Chet Haase9c1e23b2011-03-24 10:51:31 -07001045 gActivityThreadMethods, NELEM(gActivityThreadMethods));
1046}
1047
Romain Guye4d01122010-06-16 18:44:05 -07001048};