android_view_GLES20Canvas.cpp revision 1fc0fa87d42ce9268ece76b85b9edc834593e53a
1e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/*
2e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Copyright (C) 2010 The Android Open Source Project
3e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
4e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * you may not use this file except in compliance with the License.
6e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * You may obtain a copy of the License at
7e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
8e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy *
10e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Unless required by applicable law or agreed to in writing, software
11e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * See the License for the specific language governing permissions and
14e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * limitations under the License.
15e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */
16e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
17a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy#define LOG_TAG "OpenGLRenderer"
18a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy
19e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include "jni.h"
20e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy#include "GraphicsJNI.h"
21e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <nativehelper/JNIHelp.h>
226554943a1dd6854c0f4976900956e556767b49e1Romain Guy
233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "android_view_GraphicBuffer.h"
243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
25e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <android_runtime/AndroidRuntime.h>
26e5e0c50f7dfaccc220725c5595080e921ffda1e4Romain Guy#include <android_runtime/android_graphics_SurfaceTexture.h>
276554943a1dd6854c0f4976900956e556767b49e1Romain Guy
28b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/ResourceTypes.h>
29e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <gui/GLConsumer.h>
313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
326554943a1dd6854c0f4976900956e556767b49e1Romain Guy#include <private/hwui/DrawGlInfo.h>
336554943a1dd6854c0f4976900956e556767b49e1Romain Guy
346554943a1dd6854c0f4976900956e556767b49e1Romain Guy#include <cutils/properties.h>
358f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
36ce0537b80087a6225273040a987414b1dd081aa0Romain Guy#include <SkBitmap.h>
37c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy#include <SkCanvas.h>
38f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy#include <SkMatrix.h>
39c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy#include <SkPaint.h>
40079ba2c85b15e882629b8d188f5fbdb42f7f8eeaRomain Guy#include <SkRegion.h>
41a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy#include <SkScalerContext.h>
4261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy#include <SkTemplates.h>
4385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <SkXfermode.h>
44e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
45b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy#include <DisplayListRenderer.h>
466c319ca1275c8db892c39b48fc54864c949f9171Romain Guy#include <LayerRenderer.h>
4785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <OpenGLRenderer.h>
480baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy#include <Stencil.h>
499d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <Rect.h>
50113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include <RenderNode.h>
5152244fff29042926e21fa897ef5ab11148e35299John Reck#include <CanvasProperty.h>
5285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
531a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#ifdef USE_MINIKIN
541a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include <minikin/Layout.h>
551a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "MinikinSkia.h"
561a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "MinikinUtils.h"
571a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#endif
581a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
59d1d4bb70704e8f37d0823837eacdae21ebe0ed05Romain Guy#include <TextLayout.h>
60b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio#include <TextLayoutCache.h>
61e8e62a4a032a80409114a37908b5f18ab0080848Romain Guy
62e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guynamespace android {
63e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
649d5316e3f56d138504565ff311145ac01621dff4Romain Guyusing namespace uirenderer;
659d5316e3f56d138504565ff311145ac01621dff4Romain Guy
66163935113919a184122b8b3bd672ef08c8df65dcRomain Guy/**
67163935113919a184122b8b3bd672ef08c8df65dcRomain Guy * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
68163935113919a184122b8b3bd672ef08c8df65dcRomain Guy *       devices. This means all the logic must be compiled only when the
69163935113919a184122b8b3bd672ef08c8df65dcRomain Guy *       preprocessor variable USE_OPENGL_RENDERER is defined.
70163935113919a184122b8b3bd672ef08c8df65dcRomain Guy */
71163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER
72163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
73244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ----------------------------------------------------------------------------
74bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy// Defines
75244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy// ----------------------------------------------------------------------------
76bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy
77bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy// Debug
78e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy#define DEBUG_RENDERER 0
79bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy
80bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy// Debug
81bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy#if DEBUG_RENDERER
825baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__)
83bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy#else
84bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy    #define RENDERER_LOGD(...)
85bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy#endif
86e2d345ea67e2960b37bfdc0fc8626d1bfa747404Romain Guy
879d5316e3f56d138504565ff311145ac01621dff4Romain Guy// ----------------------------------------------------------------------------
889d5316e3f56d138504565ff311145ac01621dff4Romain Guy
899d5316e3f56d138504565ff311145ac01621dff4Romain Guystatic struct {
907ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    jmethodID set;
919d5316e3f56d138504565ff311145ac01621dff4Romain Guy} gRectClassInfo;
929d5316e3f56d138504565ff311145ac01621dff4Romain Guy
93e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
94e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// Constructors
95e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
96e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
975c13d89c1332fcc499379b9064b891187b75ca32Chet Haasestatic void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz,
9836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
999f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
100bdb801ca993bcccbf2a4c2401d1720c3fa523777Romain Guy    RENDERER_LOGD("Destroy OpenGLRenderer");
101f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    delete renderer;
102e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
103e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
104e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
105e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// Setup
106e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
107e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
1087d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz,
10936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint width, jint height) {
1109f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
111f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    renderer->setViewport(width, height);
112e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
113e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
11444b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haasestatic int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
11536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jboolean opaque) {
1169f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
11744b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase    return renderer->prepare(opaque);
118e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
119e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
12044b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haasestatic int android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
12136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint left, jint top, jint right, jint bottom,
1227d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy        jboolean opaque) {
1239f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
12444b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase    return renderer->prepareDirty(left, top, right, bottom, opaque);
1257d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy}
1267d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy
1277d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
12836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
1299f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
130b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy    renderer->finish();
131b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy}
132b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy
133ba9b613437c34873fa95800a25fc51720638267cChris Craikstatic void android_view_GLES20Canvas_setProperty(JNIEnv* env,
134ba9b613437c34873fa95800a25fc51720638267cChris Craik        jobject clazz, jstring name, jstring value) {
135ba9b613437c34873fa95800a25fc51720638267cChris Craik    if (!Caches::hasInstance()) {
136ba9b613437c34873fa95800a25fc51720638267cChris Craik        ALOGW("can't set property, no Caches instance");
137ba9b613437c34873fa95800a25fc51720638267cChris Craik        return;
138ba9b613437c34873fa95800a25fc51720638267cChris Craik    }
139ba9b613437c34873fa95800a25fc51720638267cChris Craik
140ba9b613437c34873fa95800a25fc51720638267cChris Craik    if (name == NULL || value == NULL) {
141ba9b613437c34873fa95800a25fc51720638267cChris Craik        ALOGW("can't set prop, null passed");
142ba9b613437c34873fa95800a25fc51720638267cChris Craik    }
143ba9b613437c34873fa95800a25fc51720638267cChris Craik
144ba9b613437c34873fa95800a25fc51720638267cChris Craik    const char* nameCharArray = env->GetStringUTFChars(name, NULL);
145ba9b613437c34873fa95800a25fc51720638267cChris Craik    const char* valueCharArray = env->GetStringUTFChars(value, NULL);
146ba9b613437c34873fa95800a25fc51720638267cChris Craik    Caches::getInstance().setTempProperty(nameCharArray, valueCharArray);
147ba9b613437c34873fa95800a25fc51720638267cChris Craik    env->ReleaseStringUTFChars(name, nameCharArray);
148ba9b613437c34873fa95800a25fc51720638267cChris Craik    env->ReleaseStringUTFChars(name, valueCharArray);
149ba9b613437c34873fa95800a25fc51720638267cChris Craik}
150ba9b613437c34873fa95800a25fc51720638267cChris Craik
151530041d3191ce817832a0108514617768e43cda6Romain Guy// ----------------------------------------------------------------------------
152530041d3191ce817832a0108514617768e43cda6Romain Guy// Functor
153530041d3191ce817832a0108514617768e43cda6Romain Guy// ----------------------------------------------------------------------------
154530041d3191ce817832a0108514617768e43cda6Romain Guy
1556554943a1dd6854c0f4976900956e556767b49e1Romain Guystatic jint android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
15636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong functorPtr) {
1579f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
1589f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    Functor* functor = reinterpret_cast<Functor*>(functorPtr);
159cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    android::uirenderer::Rect dirty;
160cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    return renderer->callDrawGLFunction(functor, dirty);
161daf98e941e140e8739458126640183b9f296a2abChet Haase}
162daf98e941e140e8739458126640183b9f296a2abChet Haase
1638f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy// ----------------------------------------------------------------------------
1648f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy// Misc
1658f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy// ----------------------------------------------------------------------------
1668f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy
167f61970fc79e9c5cf340fa942597628242361864aRomain Guystatic jint android_view_GLES20Canvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) {
168f61970fc79e9c5cf340fa942597628242361864aRomain Guy    return Caches::getInstance().maxTextureSize;
169f61970fc79e9c5cf340fa942597628242361864aRomain Guy}
170f61970fc79e9c5cf340fa942597628242361864aRomain Guy
171f61970fc79e9c5cf340fa942597628242361864aRomain Guystatic jint android_view_GLES20Canvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) {
172f61970fc79e9c5cf340fa942597628242361864aRomain Guy    return Caches::getInstance().maxTextureSize;
173f61970fc79e9c5cf340fa942597628242361864aRomain Guy}
174f61970fc79e9c5cf340fa942597628242361864aRomain Guy
175e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
176bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// State
177bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// ----------------------------------------------------------------------------
178bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
17936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, jlong rendererPtr,
180bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy        jint flags) {
1819f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
182f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    return renderer->save(flags);
183f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
184bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1857d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz,
18636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
1879f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
188f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    return renderer->getSaveCount();
189bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
190bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1917d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz,
19236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
1939f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
194f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    renderer->restore();
195bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
196bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
1977d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz,
19836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint saveCount) {
1999f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
200f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy    renderer->restoreToCount(saveCount);
201bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
202bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
203f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// ----------------------------------------------------------------------------
204bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy// Layers
205bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy// ----------------------------------------------------------------------------
206bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
2077d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz,
20836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
20936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong paintPtr, jint saveFlags) {
2109f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
2119f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
212bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
213bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy}
214bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
215189887e0ae171c1b7601991442104a30e56c50abRomain Guystatic jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz,
21636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong paintPtr, jint saveFlags) {
2179f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
2189f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
2193f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik    const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
220189887e0ae171c1b7601991442104a30e56c50abRomain Guy    return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
221189887e0ae171c1b7601991442104a30e56c50abRomain Guy            paint, saveFlags);
222189887e0ae171c1b7601991442104a30e56c50abRomain Guy}
223189887e0ae171c1b7601991442104a30e56c50abRomain Guy
2247d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz,
22536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
226bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy        jint alpha, jint saveFlags) {
2279f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
228bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy    return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
229bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy}
230bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy
231189887e0ae171c1b7601991442104a30e56c50abRomain Guystatic jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz,
23236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint alpha, jint saveFlags) {
2339f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
2343f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik    const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
235189887e0ae171c1b7601991442104a30e56c50abRomain Guy    return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
236189887e0ae171c1b7601991442104a30e56c50abRomain Guy            alpha, saveFlags);
237189887e0ae171c1b7601991442104a30e56c50abRomain Guy}
238189887e0ae171c1b7601991442104a30e56c50abRomain Guy
239bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy// ----------------------------------------------------------------------------
240f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Clipping
241f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// ----------------------------------------------------------------------------
242f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
24336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
24436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom) {
2459f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
24636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->quickRejectConservative(left, top, right, bottom);
24736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
248c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy}
249c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
25036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
25136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
25236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jint op) {
2539f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
25436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->clipRect(left, top, right, bottom,
25536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                           static_cast<SkRegion::Op>(op));
25636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
257f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
258bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
25936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz,
26036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint left, jint top, jint right, jint bottom,
26136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jint op) {
2629f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
26336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->clipRect(float(left), float(top), float(right),
26436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                           float(bottom),
26536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                           static_cast<SkRegion::Op>(op));
26636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
267bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
268bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
26936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_clipPath(JNIEnv* env, jobject clazz,
27036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong pathPtr, jint op) {
2719f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
2729f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
27336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->clipPath(path, static_cast<SkRegion::Op>(op));
27436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
275735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy}
276735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
27736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz,
27836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong regionPtr, jint op) {
2799f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
2809f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
28136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    const bool result = renderer->clipRegion(region, static_cast<SkRegion::Op>(op));
28236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return result ? JNI_TRUE : JNI_FALSE;
283735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy}
284735738c4ddf3229caa5f6e634bf591953ac29944Romain Guy
28536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhatstatic jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
28636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jobject rect) {
2879f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
2883f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik    const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
2899d5316e3f56d138504565ff311145ac01621dff4Romain Guy
2907ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    env->CallVoidMethod(rect, gRectClassInfo.set,
2917ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy            int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
2929d5316e3f56d138504565ff311145ac01621dff4Romain Guy
29336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    return !bounds.isEmpty() ? JNI_TRUE : JNI_FALSE;
2949d5316e3f56d138504565ff311145ac01621dff4Romain Guy}
2959d5316e3f56d138504565ff311145ac01621dff4Romain Guy
296bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// ----------------------------------------------------------------------------
297f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Transforms
298bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// ----------------------------------------------------------------------------
299bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3007d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz,
30136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat dx, jfloat dy) {
3029f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3037ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    renderer->translate(dx, dy);
304f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
305bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3067d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz,
30736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat degrees) {
3089f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3097ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    renderer->rotate(degrees);
310bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
311bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3127d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz,
31336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat sx, jfloat sy) {
3149f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3157ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    renderer->scale(sx, sy);
316f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
317bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
3187d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz,
31936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat sx, jfloat sy) {
3209f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
321807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy    renderer->skew(sx, sy);
322807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy}
323807daf7df615b60ce6fc41355aabe3aa353cebabRomain Guy
3247d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz,
32536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong matrixPtr) {
3269f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3279f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
328139088228faa7f3c446af7387e017933998a5570Derek Sollenberger    renderer->setMatrix(matrix ? *matrix : SkMatrix::I());
329f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
330f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
3317d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz,
33236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong matrixPtr) {
3339f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3349f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
3357ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy    renderer->getMatrix(matrix);
336f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy}
337f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy
3387d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
33936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong matrixPtr) {
3409f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3419f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
342139088228faa7f3c446af7387e017933998a5570Derek Sollenberger    renderer->concatMatrix(*matrix);
343bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
344bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
345bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// ----------------------------------------------------------------------------
346bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy// Drawing
34785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy// ----------------------------------------------------------------------------
34885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
3497d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
35036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
35136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloat left, jfloat top, jlong paintPtr) {
3529f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
3530c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    // This object allows the renderer to allocate a global JNI ref to the buffer object.
3540c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
3550c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
3569f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3579f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
358dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy    renderer->drawBitmap(bitmap, left, top, paint);
359ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
360ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
3617d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
36236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
363ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        float srcLeft, float srcTop, float srcRight, float srcBottom,
36436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) {
3659f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
3660c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    // This object allows the renderer to allocate a global JNI ref to the buffer object.
3670c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
3680c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
3699f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3709f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
371dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy    renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
372dbd77cd444f89d94ec5333223c1bc17dbe0c90cdRomain Guy            dstLeft, dstTop, dstRight, dstBottom, paint);
373f86ef57f8bcd8ba43ce222ec6a8b4f67d3600640Romain Guy}
3748ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy
3757d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
37636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
37736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong matrixPtr, jlong paintPtr) {
3789f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
3790c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    // This object allows the renderer to allocate a global JNI ref to the buffer object.
3800c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
3810c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
3829f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
3839f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
3849f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
385139088228faa7f3c446af7387e017933998a5570Derek Sollenberger    renderer->drawBitmap(bitmap, *matrix, paint);
386ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
387ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
388e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guystatic void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
38936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jintArray colors, jint offset, jint stride,
39036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) {
39149c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    SkBitmap* bitmap = new SkBitmap;
39249c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    bitmap->setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config : SkBitmap::kRGB_565_Config,
39349c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy            width, height);
394e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy
39549c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    if (!bitmap->allocPixels()) {
39649c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy        delete bitmap;
397e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy        return;
398e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy    }
399e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy
4001abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap, true)) {
40149c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy        delete bitmap;
402e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy        return;
403e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy    }
404e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy
4059f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
4069f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
40749c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    renderer->drawBitmapData(bitmap, left, top, paint);
40849c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy
40949c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    // If the renderer is a deferred renderer it will own the bitmap
410b458942bb6e6cf13c68341dda35ef5cee060f5aeChris Craik    if (!renderer->isRecording()) {
41149c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy        delete bitmap;
41249c5fc0b9e850497233e189ff9dcc71a78ebe6e7Romain Guy    }
413e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy}
414e651cc6239616a202f6e96ebc2ed93b4b8b3627cRomain Guy
4157d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
41636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
4170c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik        jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors,
41836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jint colorOffset, jlong paintPtr) {
4199f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
4200c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    // This object allows the renderer to allocate a global JNI ref to the buffer object.
4210c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
4220c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
4235a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
4245a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
4255a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
4269f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
4279f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
4285a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint);
4295a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
4305a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0);
4315a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy    if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0);
4325a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy}
4335a7b466a2b4b7ced739bd5c31e022de61650545aRomain Guy
4347d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
43536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr,
43636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        float left, float top, float right, float bottom, jlong paintPtr) {
4379f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
4380c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    // This object allows the renderer to allocate a global JNI ref to the buffer object.
4390c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik    JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
4400c20c3898a533b7b76f60827cb6ea02e17c5953dChris Craik
4419f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
4429f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr);
4439f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
4443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
445deba785f122a47915756ffd991f5540d952cf937Romain Guy}
446deba785f122a47915756ffd991f5540d952cf937Romain Guy
4477d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz,
44836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint color, jint mode) {
4499f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
45036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    renderer->drawColor(color, static_cast<SkXfermode::Mode>(mode));
45185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy}
45285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
4537d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz,
45436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
45536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong paintPtr) {
4569f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
4579f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
458c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy    renderer->drawRect(left, top, right, bottom, paint);
459c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy}
460c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy
4617d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz,
46236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
46336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloat rx, jfloat ry, jlong paintPtr) {
4649f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
4659f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
46601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
46701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
46801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
4697d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
47036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) {
4719f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
4729f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
47301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    renderer->drawCircle(x, y, radius, paint);
47401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
47501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
47652244fff29042926e21fa897ef5ab11148e35299John Reckstatic void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz,
47752244fff29042926e21fa897ef5ab11148e35299John Reck        jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
47852244fff29042926e21fa897ef5ab11148e35299John Reck    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
47952244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
48052244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
48152244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
48252244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
48352244fff29042926e21fa897ef5ab11148e35299John Reck    renderer->drawCircle(xProp, yProp, radiusProp, paintProp);
48452244fff29042926e21fa897ef5ab11148e35299John Reck}
48552244fff29042926e21fa897ef5ab11148e35299John Reck
4867d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz,
48736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
48836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong paintPtr) {
4899f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
4909f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
491c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    renderer->drawOval(left, top, right, bottom, paint);
492c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}
493c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
4947d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz,
49536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
49636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) {
4979f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
4989f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
4998b2f5267f16c295f12faab810527cd6311997e34Romain Guy    renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
5008b2f5267f16c295f12faab810527cd6311997e34Romain Guy}
5018b2f5267f16c295f12faab810527cd6311997e34Romain Guy
502672433d90fab7383cd28beac9d4485b566a90940Romain Guystatic void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz,
50336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong regionPtr, jlong paintPtr) {
5049f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
5059f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
5069f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
507672433d90fab7383cd28beac9d4485b566a90940Romain Guy    if (paint->getStyle() != SkPaint::kFill_Style ||
508672433d90fab7383cd28beac9d4485b566a90940Romain Guy            (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) {
509672433d90fab7383cd28beac9d4485b566a90940Romain Guy        SkRegion::Iterator it(*region);
510672433d90fab7383cd28beac9d4485b566a90940Romain Guy        while (!it.done()) {
511672433d90fab7383cd28beac9d4485b566a90940Romain Guy            const SkIRect& r = it.rect();
512672433d90fab7383cd28beac9d4485b566a90940Romain Guy            renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
513672433d90fab7383cd28beac9d4485b566a90940Romain Guy            it.next();
514672433d90fab7383cd28beac9d4485b566a90940Romain Guy        }
515672433d90fab7383cd28beac9d4485b566a90940Romain Guy    } else {
516672433d90fab7383cd28beac9d4485b566a90940Romain Guy        int count = 0;
517672433d90fab7383cd28beac9d4485b566a90940Romain Guy        Vector<float> rects;
518672433d90fab7383cd28beac9d4485b566a90940Romain Guy        SkRegion::Iterator it(*region);
519672433d90fab7383cd28beac9d4485b566a90940Romain Guy        while (!it.done()) {
520672433d90fab7383cd28beac9d4485b566a90940Romain Guy            const SkIRect& r = it.rect();
521672433d90fab7383cd28beac9d4485b566a90940Romain Guy            rects.push(r.fLeft);
522672433d90fab7383cd28beac9d4485b566a90940Romain Guy            rects.push(r.fTop);
523672433d90fab7383cd28beac9d4485b566a90940Romain Guy            rects.push(r.fRight);
524672433d90fab7383cd28beac9d4485b566a90940Romain Guy            rects.push(r.fBottom);
5252af4635e4a9e448a65ff541252f8f94bc6ac48e0Chris Craik            count += 4;
526672433d90fab7383cd28beac9d4485b566a90940Romain Guy            it.next();
527672433d90fab7383cd28beac9d4485b566a90940Romain Guy        }
528672433d90fab7383cd28beac9d4485b566a90940Romain Guy        renderer->drawRects(rects.array(), count, paint);
529a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy    }
530a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy}
531a48a1a87ba17f20f7006eaab21dcedf86c015c13Romain Guy
532ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guystatic void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz,
53336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
5349f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
535ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy    jfloat* storage = env->GetFloatArrayElements(points, NULL);
5369f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
537ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy    renderer->drawPoints(storage + offset, count, paint);
538ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy    env->ReleaseFloatArrayElements(points, storage, 0);
539ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy}
540ed6fcb034b44d9a6ac2fc72fee6030417811f234Romain Guy
5417d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
54236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong pathPtr, jlong paintPtr) {
5439f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
5449f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
5459f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
5467fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy    renderer->drawPath(path, paint);
5477fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy}
5487fbcc0492fca03857e3c45064f4aa040af817d55Romain Guy
5497d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
55036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
5519f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
552759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    jfloat* storage = env->GetFloatArrayElements(points, NULL);
5539f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
554759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    renderer->drawLines(storage + offset, count, paint);
555759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy    env->ReleaseFloatArrayElements(points, storage, 0);
556759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy}
557759ea80dca64ad652110a129e0d8bf93fea79f61Romain Guy
55885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy// ----------------------------------------------------------------------------
5595ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy// Draw filters
5605ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy// ----------------------------------------------------------------------------
5615ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy
5625ff9df658230d49e42c43586997a02d8e4dd417eRomain Guystatic void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz,
56336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jint clearBits, jint setBits) {
5649f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
5655ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy    renderer->setupPaintFilter(clearBits, setBits);
5665ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy}
5675ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy
5685ff9df658230d49e42c43586997a02d8e4dd417eRomain Guystatic void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz,
56936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr) {
5709f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
5715ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy    renderer->resetPaintFilter();
5725ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy}
5735ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy
5745ff9df658230d49e42c43586997a02d8e4dd417eRomain Guy// ----------------------------------------------------------------------------
575a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy// Text
576a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy// ----------------------------------------------------------------------------
577a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy
578f2114d5646194100242206b267ddd6e7194b7da9Raph Levien// TODO: this is moving to MinikinUtils, remove with USE_MINIKIN ifdef
57941541825bc90dac740e424cdd41a8c997e15cdb7Chris Craikstatic float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) {
58041541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    switch (paint->getTextAlign()) {
58141541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik        case SkPaint::kCenter_Align:
58241541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik            return -totalAdvance / 2.0f;
58341541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik            break;
58441541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik        case SkPaint::kRight_Align:
58541541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik            return -totalAdvance;
58641541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik            break;
58741541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik        default:
58841541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik            break;
58941541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    }
59041541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    return 0;
59141541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik}
59241541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik
5931a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#ifdef USE_MINIKIN
594f2114d5646194100242206b267ddd6e7194b7da9Raph Levien
595f2114d5646194100242206b267ddd6e7194b7da9Raph Levienclass RenderTextFunctor {
596f2114d5646194100242206b267ddd6e7194b7da9Raph Levienpublic:
597f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    RenderTextFunctor(const Layout& layout, OpenGLRenderer* renderer, jfloat x, jfloat y,
598f2114d5646194100242206b267ddd6e7194b7da9Raph Levien                SkPaint* paint, uint16_t* glyphs, float* pos, float totalAdvance,
599f2114d5646194100242206b267ddd6e7194b7da9Raph Levien                uirenderer::Rect& bounds)
600f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            : layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs),
601f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            pos(pos), totalAdvance(totalAdvance), bounds(bounds) { }
6021fc0fa87d42ce9268ece76b85b9edc834593e53aRaph Levien    void operator()(size_t start, size_t end) {
603f2114d5646194100242206b267ddd6e7194b7da9Raph Levien        for (size_t i = start; i < end; i++) {
604f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            glyphs[i] = layout.getGlyphId(i);
605f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            pos[2 * i] = layout.getX(i);
606f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            pos[2 * i + 1] = layout.getY(i);
607f2114d5646194100242206b267ddd6e7194b7da9Raph Levien        }
608f2114d5646194100242206b267ddd6e7194b7da9Raph Levien        size_t glyphsCount = end - start;
609f2114d5646194100242206b267ddd6e7194b7da9Raph Levien        int bytesCount = glyphsCount * sizeof(jchar);
610f2114d5646194100242206b267ddd6e7194b7da9Raph Levien        renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
611f2114d5646194100242206b267ddd6e7194b7da9Raph Levien            x, y, pos + 2 * start, paint, totalAdvance, bounds);
612f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    }
613f2114d5646194100242206b267ddd6e7194b7da9Raph Levienprivate:
614f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    const Layout& layout;
615f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    OpenGLRenderer* renderer;
616f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    jfloat x;
617f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    jfloat y;
618f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    SkPaint* paint;
619f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    uint16_t* glyphs;
620f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    float* pos;
621f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    float totalAdvance;
622f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    uirenderer::Rect& bounds;
623f2114d5646194100242206b267ddd6e7194b7da9Raph Levien};
624f2114d5646194100242206b267ddd6e7194b7da9Raph Levien
6251a73f732f91e97c9c66b808c245ddda36a10e987Raph Levienstatic void renderTextLayout(OpenGLRenderer* renderer, Layout* layout,
6261a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    jfloat x, jfloat y, SkPaint* paint) {
6271a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    size_t nGlyphs = layout->nGlyphs();
6281a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    float* pos = new float[nGlyphs * 2];
6291a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    uint16_t* glyphs = new uint16_t[nGlyphs];
6301a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    MinikinRect b;
6311a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    layout->getBounds(&b);
6321a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    android::uirenderer::Rect bounds(b.mLeft, b.mTop, b.mRight, b.mBottom);
6331a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    bounds.translate(x, y);
6341a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    float totalAdvance = layout->getAdvance();
6351a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
636f2114d5646194100242206b267ddd6e7194b7da9Raph Levien    RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds);
6371fc0fa87d42ce9268ece76b85b9edc834593e53aRaph Levien    MinikinUtils::forFontRun(*layout, paint, f);
6381a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    delete[] glyphs;
6391a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    delete[] pos;
6401a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien}
6411a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#endif
6421a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien
643e8e62a4a032a80409114a37908b5f18ab0080848Romain Guystatic void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
6441a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien        jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) {
6451a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#ifdef USE_MINIKIN
6461a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    Layout layout;
6476bfd7e7df3a9f9ea2f9e57a3552eed7f518be711Raph Levien    std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
6486bfd7e7df3a9f9ea2f9e57a3552eed7f518be711Raph Levien    layout.doLayout(text, 0, count, count, css);
6491a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    x += xOffsetForTextAlign(paint, layout.getAdvance());
6501a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    renderTextLayout(renderer, &layout, x, y, paint);
6511a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#else
652a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
653da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            text, 0, count, count, flags);
6542ea75880142152b3a9993cb245754d73c05749a7Fabrice Di Meglio    if (value == NULL) {
655b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio        return;
6562ea75880142152b3a9993cb245754d73c05749a7Fabrice Di Meglio    }
6575c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    const jchar* glyphs = value->getGlyphs();
6585c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    size_t glyphsCount = value->getGlyphsCount();
659996e57c84368058be793897ebc355b917a59abc2Raph Levien    jfloat totalAdvance = value->getTotalAdvance();
660b15b446f420b3ec69424dabcbcbc8cf019d6c8d6Romain Guy    x += xOffsetForTextAlign(paint, totalAdvance);
661996e57c84368058be793897ebc355b917a59abc2Raph Levien    const float* positions = value->getPos();
66279df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio    int bytesCount = glyphsCount * sizeof(jchar);
66341541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    const SkRect& r = value->getBounds();
66441541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
665f09b746acb266a849f3421df1604ebec161bb93dChris Craik    bounds.translate(x, y);
66641541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik
66741541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
668b15b446f420b3ec69424dabcbcbc8cf019d6c8d6Romain Guy            x, y, positions, paint, totalAdvance, bounds);
6691a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#endif
670e8e62a4a032a80409114a37908b5f18ab0080848Romain Guy}
671e8e62a4a032a80409114a37908b5f18ab0080848Romain Guy
672325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guystatic void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
673da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio        SkPath* path, jfloat hOffset, jfloat vOffset, int flags, SkPaint* paint) {
674325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
675da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            text, 0, count, count, flags);
676325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    if (value == NULL) {
677325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy        return;
678325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    }
679325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    const jchar* glyphs = value->getGlyphs();
680325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    size_t glyphsCount = value->getGlyphsCount();
681325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    int bytesCount = glyphsCount * sizeof(jchar);
682325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    renderer->drawTextOnPath((const char*) glyphs, bytesCount, glyphsCount, path,
683325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy            hOffset, vOffset, paint);
684325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy}
685325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy
68661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guystatic void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
68761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy        jint start, jint count, jint contextCount, jfloat x, jfloat y,
6881a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien        int flags, SkPaint* paint, TypefaceImpl* typeface) {
6891a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#ifdef USE_MINIKIN
6901a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    Layout layout;
6916bfd7e7df3a9f9ea2f9e57a3552eed7f518be711Raph Levien    std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
6926bfd7e7df3a9f9ea2f9e57a3552eed7f518be711Raph Levien    layout.doLayout(text, start, count, contextCount, css);
6931a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    x += xOffsetForTextAlign(paint, layout.getAdvance());
6941a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    renderTextLayout(renderer, &layout, x, y, paint);
6951a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#else
696a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
697da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            text, start, count, contextCount, flags);
6982ea75880142152b3a9993cb245754d73c05749a7Fabrice Di Meglio    if (value == NULL) {
699b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio        return;
7002ea75880142152b3a9993cb245754d73c05749a7Fabrice Di Meglio    }
7015c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    const jchar* glyphs = value->getGlyphs();
7025c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    size_t glyphsCount = value->getGlyphsCount();
703996e57c84368058be793897ebc355b917a59abc2Raph Levien    jfloat totalAdvance = value->getTotalAdvance();
704b15b446f420b3ec69424dabcbcbc8cf019d6c8d6Romain Guy    x += xOffsetForTextAlign(paint, totalAdvance);
705996e57c84368058be793897ebc355b917a59abc2Raph Levien    const float* positions = value->getPos();
70679df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio    int bytesCount = glyphsCount * sizeof(jchar);
70741541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    const SkRect& r = value->getBounds();
70841541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
709f09b746acb266a849f3421df1604ebec161bb93dChris Craik    bounds.translate(x, y);
71041541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik
71141541825bc90dac740e424cdd41a8c997e15cdb7Chris Craik    renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
712b15b446f420b3ec69424dabcbcbc8cf019d6c8d6Romain Guy            x, y, positions, paint, totalAdvance, bounds);
7131a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#endif
71461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy}
71561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
7167d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
71736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jcharArray text, jint index, jint count,
7181a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien        jfloat x, jfloat y, jint flags, jlong paintPtr, jlong typefacePtr) {
7199f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
720a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy    jchar* textArray = env->GetCharArrayElements(text, NULL);
7219f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
7221a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
7239f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik
7241a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    renderText(renderer, textArray + index, count, x, y, flags, paint, typeface);
725a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy    env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
726a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy}
727a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy
7287d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
72936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jstring text, jint start, jint end,
7301a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien        jfloat x, jfloat y, jint flags, jlong paintPtr, jlong typefacePtr) {
7319f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
732a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy    const jchar* textArray = env->GetStringChars(text, NULL);
7339f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
7341a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
7359f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik
7361a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    renderText(renderer, textArray + start, end - start, x, y, flags, paint, typeface);
737a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy    env->ReleaseStringChars(text, textArray);
738a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy}
739a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy
740325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guystatic void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz,
74136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jcharArray text, jint index, jint count,
74236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong pathPtr, jfloat hOffset, jfloat vOffset, jint flags, jlong paintPtr) {
7439f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
744325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    jchar* textArray = env->GetCharArrayElements(text, NULL);
7459f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
7469f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
7479f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik
748325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    renderTextOnPath(renderer, textArray + index, count, path,
749da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            hOffset, vOffset, flags, paint);
750325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
751325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy}
752325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy
753325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guystatic void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz,
75436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jstring text, jint start, jint end,
75536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong pathPtr, jfloat hOffset, jfloat vOffset, jint flags, jlong paintPtr) {
7569f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
757325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    const jchar* textArray = env->GetStringChars(text, NULL);
7589f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
7599f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
7609f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik
761325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    renderTextOnPath(renderer, textArray + start, end - start, path,
762da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            hOffset, vOffset, flags, paint);
763325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy    env->ReleaseStringChars(text, textArray);
764325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy}
765325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy
7667d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
76736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jcharArray text, jint index, jint count,
768da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio        jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
7691a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien        jlong paintPtr, jlong typefacePtr) {
7709f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
77161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    jchar* textArray = env->GetCharArrayElements(text, NULL);
7729f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
7731a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
7749f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik
77561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    renderTextRun(renderer, textArray + contextIndex, index - contextIndex,
7761a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien            count, contextCount, x, y, dirFlags, paint, typeface);
77761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
77861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy }
77961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
7807d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
78136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jstring text, jint start, jint end,
782da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio        jint contextStart, int contextEnd, jfloat x, jfloat y, jint dirFlags,
7831a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien        jlong paintPtr, jlong typefacePtr) {
7849f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
78561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    const jchar* textArray = env->GetStringChars(text, NULL);
78661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    jint count = end - start;
78761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    jint contextCount = contextEnd - contextStart;
7889f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
7891a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
7909f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik
79161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    renderTextRun(renderer, textArray + contextStart, start - contextStart,
7921a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien            count, contextCount, x, y, dirFlags, paint, typeface);
79361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    env->ReleaseStringChars(text, textArray);
79461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy}
79561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
796eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guystatic void renderPosText(OpenGLRenderer* renderer, const jchar* text, int count,
797da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio        const jfloat* positions, jint dirFlags, SkPaint* paint) {
798a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
799da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            text, 0, count, count, dirFlags);
800eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    if (value == NULL) {
801eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy        return;
802eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    }
803eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    const jchar* glyphs = value->getGlyphs();
804eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    size_t glyphsCount = value->getGlyphsCount();
805671d6cf460531825a321edb200523d0faa7792c9Romain Guy    if (count < int(glyphsCount)) glyphsCount = count;
806eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    int bytesCount = glyphsCount * sizeof(jchar);
807eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
808671d6cf460531825a321edb200523d0faa7792c9Romain Guy    renderer->drawPosText((const char*) glyphs, bytesCount, glyphsCount, positions, paint);
809eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy}
810eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
811eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guystatic void android_view_GLES20Canvas_drawPosTextArray(JNIEnv* env, jobject clazz,
81236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jcharArray text, jint index, jint count,
81336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloatArray pos, jlong paintPtr) {
8149f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
815eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    jchar* textArray = env->GetCharArrayElements(text, NULL);
816eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    jfloat* positions = env->GetFloatArrayElements(pos, NULL);
8179f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
818eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
819da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio    renderPosText(renderer, textArray + index, count, positions, kBidi_LTR, paint);
820eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
821eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    env->ReleaseFloatArrayElements(pos, positions, JNI_ABORT);
822eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
823eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy}
824eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
825eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guystatic void android_view_GLES20Canvas_drawPosText(JNIEnv* env, jobject clazz,
82636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jstring text, jint start, jint end,
82736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jfloatArray pos, jlong paintPtr) {
8289f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
829eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    const jchar* textArray = env->GetStringChars(text, NULL);
830eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    jfloat* positions = env->GetFloatArrayElements(pos, NULL);
8319f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
832eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
833da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio    renderPosText(renderer, textArray + start, end - start, positions, kBidi_LTR, paint);
834eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
835eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    env->ReleaseFloatArrayElements(pos, positions, JNI_ABORT);
836eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy    env->ReleaseStringChars(text, textArray);
837eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy}
838eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
839b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy// ----------------------------------------------------------------------------
840b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy// Display lists
841b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy// ----------------------------------------------------------------------------
842b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
84344fd8d24f761f82d21e9b00932648a1b6bf91449John Reckstatic jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env,
84444fd8d24f761f82d21e9b00932648a1b6bf91449John Reck        jobject clazz, jlong rendererPtr) {
8459f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
84644fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    return reinterpret_cast<jlong>(renderer->finishRecording());
847162a0217563f4665da6eb183dfce0fef740f641fJeff Brown}
848162a0217563f4665da6eb183dfce0fef740f641fJeff Brown
8493f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craikstatic jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env, jobject clazz) {
85044fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    return reinterpret_cast<jlong>(new DisplayListRenderer);
8515977baa1fa24125c148a72699b53e62abaf08960Chet Haase}
8525977baa1fa24125c148a72699b53e62abaf08960Chet Haase
8536554943a1dd6854c0f4976900956e556767b49e1Romain Guystatic jint android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
85436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jobject clazz, jlong rendererPtr, jlong displayListPtr,
8551271e2cc80b01d577e9db339459ef0222bb9320dChet Haase        jobject dirty, jint flags) {
8569f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
857e18264b079481a244b30e3f71012c53bbd861f92John Reck    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
858cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    android::uirenderer::Rect bounds;
8591271e2cc80b01d577e9db339459ef0222bb9320dChet Haase    status_t status = renderer->drawDisplayList(displayList, bounds, flags);
8606554943a1dd6854c0f4976900956e556767b49e1Romain Guy    if (status != DrawGlInfo::kStatusDone && dirty != NULL) {
861cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy        env->CallVoidMethod(dirty, gRectClassInfo.set,
862cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy                int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
863cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy    }
8646554943a1dd6854c0f4976900956e556767b49e1Romain Guy    return status;
865b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy}
866b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
8676c319ca1275c8db892c39b48fc54864c949f9171Romain Guy// ----------------------------------------------------------------------------
8686c319ca1275c8db892c39b48fc54864c949f9171Romain Guy// Layers
8696c319ca1275c8db892c39b48fc54864c949f9171Romain Guy// ----------------------------------------------------------------------------
8706c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
8717d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guystatic void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
87236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) {
8739f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
8749f66ea06ace80f60e049e3e7e778a8552cebe5b3Chris Craik    Layer* layer = reinterpret_cast<Layer*>(layerPtr);
875a08f95cfeca7217f9c533b03663bf0dceedd259aChris Craik    renderer->drawLayer(layer, x, y);
8766c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}
8776c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
878163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif // USE_OPENGL_RENDERER
879163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
880163935113919a184122b8b3bd672ef08c8df65dcRomain Guy// ----------------------------------------------------------------------------
881163935113919a184122b8b3bd672ef08c8df65dcRomain Guy// Common
882163935113919a184122b8b3bd672ef08c8df65dcRomain Guy// ----------------------------------------------------------------------------
883163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
884163935113919a184122b8b3bd672ef08c8df65dcRomain Guystatic jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz) {
885163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER
8864406345cd62d3687ce590c357854472f7f906e6cJesse Hall    char prop[PROPERTY_VALUE_MAX];
8874406345cd62d3687ce590c357854472f7f906e6cJesse Hall    if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
8884406345cd62d3687ce590c357854472f7f906e6cJesse Hall        // not in the emulator
8894406345cd62d3687ce590c357854472f7f906e6cJesse Hall        return JNI_TRUE;
8904406345cd62d3687ce590c357854472f7f906e6cJesse Hall    }
8914406345cd62d3687ce590c357854472f7f906e6cJesse Hall    // In the emulator this property will be set to 1 when hardware GLES is
8924406345cd62d3687ce590c357854472f7f906e6cJesse Hall    // enabled, 0 otherwise. On old emulator versions it will be undefined.
8934406345cd62d3687ce590c357854472f7f906e6cJesse Hall    property_get("ro.kernel.qemu.gles", prop, "0");
8944406345cd62d3687ce590c357854472f7f906e6cJesse Hall    return atoi(prop) == 1 ? JNI_TRUE : JNI_FALSE;
895163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else
896163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    return JNI_FALSE;
897163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif
898163935113919a184122b8b3bd672ef08c8df65dcRomain Guy}
899163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
900a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy// ----------------------------------------------------------------------------
9019c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase// Logging
9029c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase// ----------------------------------------------------------------------------
9039c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
9049c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haasestatic void
90565b345fa22b878e141b8fd8ece9c208df00fa40fRomain Guyandroid_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
906905787a7c91d23daa4efc3d16bd8cbf1a683e779Chet Haase#ifdef USE_OPENGL_RENDERER
907a3804cf77f0edd93f6247a055cdafb856b117eecElliott Hughes    int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
908e18264b079481a244b30e3f71012c53bbd861f92John Reck    android::uirenderer::RenderNode::outputLogBuffer(fd);
909905787a7c91d23daa4efc3d16bd8cbf1a683e779Chet Haase#endif // USE_OPENGL_RENDERER
9109c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase}
9119c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
9129c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase// ----------------------------------------------------------------------------
913e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// JNI Glue
914e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy// ----------------------------------------------------------------------------
915e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
916e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyconst char* const kClassPathName = "android/view/GLES20Canvas";
917e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
918e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guystatic JNINativeMethod gMethods[] = {
91961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy    { "nIsAvailable",       "()Z",             (void*) android_view_GLES20Canvas_isAvailable },
920163935113919a184122b8b3bd672ef08c8df65dcRomain Guy
92161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy#ifdef USE_OPENGL_RENDERER
9227d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy
92336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDestroyRenderer",   "(J)V",            (void*) android_view_GLES20Canvas_destroyRenderer },
92436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSetViewport",       "(JII)V",          (void*) android_view_GLES20Canvas_setViewport },
92536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nPrepare",           "(JZ)I",           (void*) android_view_GLES20Canvas_prepare },
92636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nPrepareDirty",      "(JIIIIZ)I",       (void*) android_view_GLES20Canvas_prepareDirty },
92736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nFinish",            "(J)V",            (void*) android_view_GLES20Canvas_finish },
928ba9b613437c34873fa95800a25fc51720638267cChris Craik    { "nSetProperty",           "(Ljava/lang/String;Ljava/lang/String;)V",
929ba9b613437c34873fa95800a25fc51720638267cChris Craik            (void*) android_view_GLES20Canvas_setProperty },
93061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
93136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nCallDrawGLFunction", "(JJ)I",          (void*) android_view_GLES20Canvas_callDrawGLFunction },
9327d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy
93336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSave",              "(JI)I",           (void*) android_view_GLES20Canvas_save },
93436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nRestore",           "(J)V",            (void*) android_view_GLES20Canvas_restore },
93536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nRestoreToCount",    "(JI)V",           (void*) android_view_GLES20Canvas_restoreToCount },
93636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nGetSaveCount",      "(J)I",            (void*) android_view_GLES20Canvas_getSaveCount },
93736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
93836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSaveLayer",         "(JFFFFJI)I",      (void*) android_view_GLES20Canvas_saveLayer },
93936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSaveLayer",         "(JJI)I",          (void*) android_view_GLES20Canvas_saveLayerClip },
94036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSaveLayerAlpha",    "(JFFFFII)I",      (void*) android_view_GLES20Canvas_saveLayerAlpha },
94136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSaveLayerAlpha",    "(JII)I",          (void*) android_view_GLES20Canvas_saveLayerAlphaClip },
94236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
94336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nQuickReject",       "(JFFFF)Z",        (void*) android_view_GLES20Canvas_quickReject },
94436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nClipRect",          "(JFFFFI)Z",       (void*) android_view_GLES20Canvas_clipRectF },
94536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nClipRect",          "(JIIIII)Z",       (void*) android_view_GLES20Canvas_clipRect },
94636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nClipPath",          "(JJI)Z",          (void*) android_view_GLES20Canvas_clipPath },
94736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nClipRegion",        "(JJI)Z",          (void*) android_view_GLES20Canvas_clipRegion },
94836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
94936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nTranslate",         "(JFF)V",          (void*) android_view_GLES20Canvas_translate },
95036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nRotate",            "(JF)V",           (void*) android_view_GLES20Canvas_rotate },
95136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nScale",             "(JFF)V",          (void*) android_view_GLES20Canvas_scale },
95236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSkew",              "(JFF)V",          (void*) android_view_GLES20Canvas_skew },
95336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
95436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSetMatrix",         "(JJ)V",           (void*) android_view_GLES20Canvas_setMatrix },
95536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nGetMatrix",         "(JJ)V",           (void*) android_view_GLES20Canvas_getMatrix },
95636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nConcatMatrix",      "(JJ)V",           (void*) android_view_GLES20Canvas_concatMatrix },
95736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
95836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawBitmap",        "(JJ[BFFJ)V",      (void*) android_view_GLES20Canvas_drawBitmap },
95936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawBitmap",        "(JJ[BFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
96036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawBitmap",        "(JJ[BJJ)V",       (void*) android_view_GLES20Canvas_drawBitmapMatrix },
96136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawBitmap",        "(J[IIIFFIIZJ)V",  (void*) android_view_GLES20Canvas_drawBitmapData },
96236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
96336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawBitmapMesh",    "(JJ[BII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
96436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
96536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawPatch",         "(JJ[BJFFFFJ)V",   (void*) android_view_GLES20Canvas_drawPatch },
96636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
96736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawColor",         "(JII)V",          (void*) android_view_GLES20Canvas_drawColor },
96836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawRect",          "(JFFFFJ)V",       (void*) android_view_GLES20Canvas_drawRect },
96936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawRects",         "(JJJ)V",          (void*) android_view_GLES20Canvas_drawRegionAsRects },
97036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawRoundRect",     "(JFFFFFFJ)V",     (void*) android_view_GLES20Canvas_drawRoundRect },
97136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawCircle",        "(JFFFJ)V",        (void*) android_view_GLES20Canvas_drawCircle },
97252244fff29042926e21fa897ef5ab11148e35299John Reck    { "nDrawCircle",        "(JJJJJ)V",        (void*) android_view_GLES20Canvas_drawCircleProps },
97336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawOval",          "(JFFFFJ)V",       (void*) android_view_GLES20Canvas_drawOval },
97436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawArc",           "(JFFFFFFZJ)V",    (void*) android_view_GLES20Canvas_drawArc },
97536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawPoints",        "(J[FIIJ)V",       (void*) android_view_GLES20Canvas_drawPoints },
97636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
97736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawPath",          "(JJJ)V",          (void*) android_view_GLES20Canvas_drawPath },
97836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawLines",         "(J[FIIJ)V",       (void*) android_view_GLES20Canvas_drawLines },
97936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
98036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nSetupPaintFilter",  "(JII)V",          (void*) android_view_GLES20Canvas_setupPaintFilter },
98136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nResetPaintFilter",  "(J)V",            (void*) android_view_GLES20Canvas_resetPaintFilter },
98236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
9831a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    { "nDrawText",          "(J[CIIFFIJJ)V",   (void*) android_view_GLES20Canvas_drawTextArray },
9841a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    { "nDrawText",          "(JLjava/lang/String;IIFFIJJ)V",
985a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy            (void*) android_view_GLES20Canvas_drawText },
986a1db574036c9bc2d397b69f8200594027e1fff16Romain Guy
98736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawTextOnPath",    "(J[CIIJFFIJ)V",   (void*) android_view_GLES20Canvas_drawTextArrayOnPath },
98836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawTextOnPath",    "(JLjava/lang/String;IIJFFIJ)V",
989325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy            (void*) android_view_GLES20Canvas_drawTextOnPath },
990325740fb444af8fc7fb0119b2e30ce322c2ae134Romain Guy
9911a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    { "nDrawTextRun",       "(J[CIIIIFFIJJ)V",  (void*) android_view_GLES20Canvas_drawTextRunArray },
9921a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien    { "nDrawTextRun",       "(JLjava/lang/String;IIIIFFIJJ)V",
99361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy            (void*) android_view_GLES20Canvas_drawTextRun },
99461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy
99536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawPosText",       "(J[CII[FJ)V",     (void*) android_view_GLES20Canvas_drawPosTextArray },
99636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawPosText",       "(JLjava/lang/String;II[FJ)V",
997eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy            (void*) android_view_GLES20Canvas_drawPosText },
998eb9a5367e8f0e970db8509ffb2584f5376bc62edRomain Guy
99936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nGetClipBounds",     "(JLandroid/graphics/Rect;)Z",
1000ce0537b80087a6225273040a987414b1dd081aa0Romain Guy            (void*) android_view_GLES20Canvas_getClipBounds },
1001b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy
100244fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    { "nFinishRecording",        "(J)J",      (void*) android_view_GLES20Canvas_finishRecording },
100336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawDisplayList",        "(JJLandroid/graphics/Rect;I)I",
10048f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy            (void*) android_view_GLES20Canvas_drawDisplayList },
100513631f3da855f200a151e7837ed9f6b079622b58Romain Guy
100636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nCreateDisplayListRenderer", "()J",     (void*) android_view_GLES20Canvas_createDisplayListRenderer },
100713631f3da855f200a151e7837ed9f6b079622b58Romain Guy
100836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    { "nDrawLayer",              "(JJFF)V",    (void*) android_view_GLES20Canvas_drawLayer },
100936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat
1010f61970fc79e9c5cf340fa942597628242361864aRomain Guy    { "nGetMaximumTextureWidth",  "()I",       (void*) android_view_GLES20Canvas_getMaxTextureWidth },
1011f61970fc79e9c5cf340fa942597628242361864aRomain Guy    { "nGetMaximumTextureHeight", "()I",       (void*) android_view_GLES20Canvas_getMaxTextureHeight },
1012f61970fc79e9c5cf340fa942597628242361864aRomain Guy
1013163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif
1014e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy};
1015e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
10169c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haasestatic JNINativeMethod gActivityThreadMethods[] = {
10179c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase    { "dumpGraphicsInfo",        "(Ljava/io/FileDescriptor;)V",
10189c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase                                               (void*) android_app_ActivityThread_dumpGraphics }
10199c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase};
10209c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
10219c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
1022163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER
1023163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    #define FIND_CLASS(var, className) \
1024163935113919a184122b8b3bd672ef08c8df65dcRomain Guy            var = env->FindClass(className); \
102517cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro            LOG_FATAL_IF(! var, "Unable to find class " className);
102617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro
1027163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1028163935113919a184122b8b3bd672ef08c8df65dcRomain Guy            var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1029163935113919a184122b8b3bd672ef08c8df65dcRomain Guy            LOG_FATAL_IF(! var, "Unable to find method " methodName);
1030163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else
1031163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    #define FIND_CLASS(var, className)
1032163935113919a184122b8b3bd672ef08c8df65dcRomain Guy    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
1033163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif
10349d5316e3f56d138504565ff311145ac01621dff4Romain Guy
1035e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guyint register_android_view_GLES20Canvas(JNIEnv* env) {
103617cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    jclass clazz;
103717cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    FIND_CLASS(clazz, "android/graphics/Rect");
103817cc33a35729733aaa0a7706f38b1c45f0b1590aCarl Shapiro    GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
10399d5316e3f56d138504565ff311145ac01621dff4Romain Guy
1040e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
1041e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
1042e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
10439c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haaseconst char* const kActivityThreadPathName = "android/app/ActivityThread";
10449c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
10456be3d5561cbeccf0a8257a4acb155657f868e548Romain Guyint register_android_app_ActivityThread(JNIEnv* env) {
10466be3d5561cbeccf0a8257a4acb155657f868e548Romain Guy    return AndroidRuntime::registerNativeMethods(env, kActivityThreadPathName,
10479c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase            gActivityThreadMethods, NELEM(gActivityThreadMethods));
10489c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase}
10499c1e23baf5bfbebd1aebbd6d9a18c225325567ceChet Haase
1050e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy};
1051