blob: 9907da5a2e68b7b5b5de27208308b6fef255e938 [file] [log] [blame]
Romain Guye4d01122010-06-16 18:44:05 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Romain Guya1db5742010-07-20 13:09:13 -070017#define LOG_TAG "OpenGLRenderer"
18
Romain Guye4d01122010-06-16 18:44:05 -070019#include "jni.h"
Patrick Dubroye4ac2d62010-12-01 11:23:13 -080020#include "GraphicsJNI.h"
Romain Guye4d01122010-06-16 18:44:05 -070021#include <nativehelper/JNIHelp.h>
Romain Guy65549432012-03-26 16:45:05 -070022
Romain Guye4d01122010-06-16 18:44:05 -070023#include <android_runtime/AndroidRuntime.h>
Fedor Kudasov86bd2142019-06-18 15:51:57 +010024#ifdef __ANDROID__ // Layoutlib does not support Looper and device properties
John Reckcd1c3eb2016-04-14 10:38:54 -070025#include <utils/Looper.h>
Fedor Kudasov86bd2142019-06-18 15:51:57 +010026#endif
Romain Guy8f0095c2011-05-02 17:24:22 -070027
Romain Guyce0537b2010-06-29 21:05:21 -070028#include <SkBitmap.h>
Romain Guy079ba2c2010-07-16 14:12:24 -070029#include <SkRegion.h>
Romain Guye4d01122010-06-16 18:44:05 -070030
Romain Guy9d5316e2010-06-24 19:30:36 -070031#include <Rect.h>
John Reck113e0822014-03-18 09:22:59 -070032#include <RenderNode.h>
John Reck52244ff2014-05-01 21:27:37 -070033#include <CanvasProperty.h>
sergeyvdccca442016-03-21 15:38:21 -070034#include <hwui/Canvas.h>
35#include <hwui/Paint.h>
Seigo Nonaka2d464422017-08-23 13:49:51 -070036#include <minikin/Layout.h>
Fedor Kudasov86bd2142019-06-18 15:51:57 +010037#ifdef __ANDROID__ // Layoutlib does not support RenderThread
John Reck0e89e2b2014-10-31 14:49:06 -070038#include <renderthread/RenderProxy.h>
Fedor Kudasov86bd2142019-06-18 15:51:57 +010039#endif
Romain Guy85bf02f2010-06-22 13:11:24 -070040
Andreas Gampe987f79f2014-11-18 17:29:46 -080041#include "core_jni_helpers.h"
42
Romain Guye4d01122010-06-16 18:44:05 -070043namespace android {
44
Romain Guy9d5316e2010-06-24 19:30:36 -070045using namespace uirenderer;
46
John Reckcd1c3eb2016-04-14 10:38:54 -070047jmethodID gRunnableMethodId;
48
49static JNIEnv* jnienv(JavaVM* vm) {
50 JNIEnv* env;
51 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
52 LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
53 }
54 return env;
55}
56
Fedor Kudasov86bd2142019-06-18 15:51:57 +010057#ifdef __ANDROID__ // Layoutlib does not support GL, Looper
John Reckcd1c3eb2016-04-14 10:38:54 -070058class InvokeRunnableMessage : public MessageHandler {
59public:
60 InvokeRunnableMessage(JNIEnv* env, jobject runnable) {
61 mRunnable = env->NewGlobalRef(runnable);
62 env->GetJavaVM(&mVm);
63 }
64
65 virtual ~InvokeRunnableMessage() {
66 jnienv(mVm)->DeleteGlobalRef(mRunnable);
67 }
68
69 virtual void handleMessage(const Message&) {
70 jnienv(mVm)->CallVoidMethod(mRunnable, gRunnableMethodId);
71 }
72
73private:
74 JavaVM* mVm;
75 jobject mRunnable;
76};
77
78class GlFunctorReleasedCallbackBridge : public GlFunctorLifecycleListener {
79public:
80 GlFunctorReleasedCallbackBridge(JNIEnv* env, jobject javaCallback) {
81 mLooper = Looper::getForThread();
82 mMessage = new InvokeRunnableMessage(env, javaCallback);
83 }
84
85 virtual void onGlFunctorReleased(Functor* functor) override {
86 mLooper->sendMessage(mMessage, 0);
87 }
88
89private:
90 sp<Looper> mLooper;
91 sp<InvokeRunnableMessage> mMessage;
92};
Fedor Kudasov86bd2142019-06-18 15:51:57 +010093#endif
John Reckcd1c3eb2016-04-14 10:38:54 -070094
Chris Craikfc294242016-12-13 18:10:46 -080095// ---------------- @FastNative -----------------------------
Romain Guy530041d2012-01-25 18:56:29 -080096
Chris Craikc9070eb2015-03-09 18:50:14 -070097static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
John Reckcd1c3eb2016-04-14 10:38:54 -070098 jlong canvasPtr, jlong functorPtr, jobject releasedCallback) {
Fedor Kudasov86bd2142019-06-18 15:51:57 +010099#ifdef __ANDROID__ // Layoutlib does not support GL
Derek Sollenberger6f485562015-07-30 10:00:39 -0400100 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Chris Craik9f66ea02013-12-27 15:15:55 -0800101 Functor* functor = reinterpret_cast<Functor*>(functorPtr);
John Reck4afbed12016-04-18 09:29:36 -0700102 sp<GlFunctorReleasedCallbackBridge> bridge;
103 if (releasedCallback) {
104 bridge = new GlFunctorReleasedCallbackBridge(env, releasedCallback);
105 }
John Reckcd1c3eb2016-04-14 10:38:54 -0700106 canvas->callDrawGLFunction(functor, bridge.get());
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100107#endif
Chet Haasedaf98e92011-01-10 14:10:36 -0800108}
109
Romain Guy8f3b8e32012-03-27 16:33:45 -0700110
Chris Craikfc294242016-12-13 18:10:46 -0800111// ---------------- @CriticalNative -------------------------
112
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100113static jlong android_view_DisplayListCanvas_createDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
Chris Craikfc294242016-12-13 18:10:46 -0800114 jint width, jint height) {
115 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
116 return reinterpret_cast<jlong>(Canvas::create_recording_canvas(width, height, renderNode));
117}
118
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100119static void android_view_DisplayListCanvas_resetDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
Chris Craikfc294242016-12-13 18:10:46 -0800120 jlong renderNodePtr, jint width, jint height) {
121 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
122 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
123 canvas->resetRecording(width, height, renderNode);
124}
125
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100126static jint android_view_DisplayListCanvas_getMaxTextureSize(CRITICAL_JNI_PARAMS) {
127#ifdef __ANDROID__ // Layoutlib does not support RenderProxy (RenderThread)
John Recke4c1e6c2018-05-24 16:27:35 -0700128 return android::uirenderer::renderthread::RenderProxy::maxTextureSize();
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100129#else
130 return 4096;
131#endif
Romain Guyf61970fc2011-07-07 14:10:06 -0700132}
133
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100134static void android_view_DisplayListCanvas_insertReorderBarrier(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
Chris Craikfc294242016-12-13 18:10:46 -0800135 jboolean reorderEnable) {
136 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
137 canvas->insertReorderBarrier(reorderEnable);
138}
Romain Guy85bf02f2010-06-22 13:11:24 -0700139
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100140static jlong android_view_DisplayListCanvas_finishRecording(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr) {
Chris Craikfc294242016-12-13 18:10:46 -0800141 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
142 return reinterpret_cast<jlong>(canvas->finishRecording());
143}
144
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100145static void android_view_DisplayListCanvas_drawRenderNode(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong renderNodePtr) {
Chris Craikfc294242016-12-13 18:10:46 -0800146 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
147 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
148 canvas->drawRenderNode(renderNode);
149}
150
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100151static void android_view_DisplayListCanvas_drawTextureLayer(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong layerPtr) {
Chris Craikfc294242016-12-13 18:10:46 -0800152 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
153 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
154 canvas->drawLayer(layer);
155}
156
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100157static void android_view_DisplayListCanvas_drawRoundRectProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
Chris Craikfc294242016-12-13 18:10:46 -0800158 jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr, jlong bottomPropPtr,
159 jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400160 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Jorim Jaggi072707d2014-09-15 17:20:08 +0200161 CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
162 CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
163 CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
164 CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr);
165 CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr);
166 CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr);
167 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
Chris Craik86c03ca2015-08-21 10:44:56 -0700168 canvas->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
Jorim Jaggi072707d2014-09-15 17:20:08 +0200169}
170
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100171static void android_view_DisplayListCanvas_drawCircleProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
Chris Craikfc294242016-12-13 18:10:46 -0800172 jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400173 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
John Reck52244ff2014-05-01 21:27:37 -0700174 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
175 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
176 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
177 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
Chris Craik86c03ca2015-08-21 10:44:56 -0700178 canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
John Reck52244ff2014-05-01 21:27:37 -0700179}
180
Fedor Kudasov86bd2142019-06-18 15:51:57 +0100181static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jint functor) {
John Reck283bb462018-12-13 16:40:14 -0800182 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
183 canvas->drawWebViewFunctor(functor);
184}
185
Romain Guyb051e892010-09-28 19:09:36 -0700186// ----------------------------------------------------------------------------
Romain Guye4d01122010-06-16 18:44:05 -0700187// JNI Glue
188// ----------------------------------------------------------------------------
189
John Reck32f140aa62018-10-04 15:08:24 -0700190const char* const kClassPathName = "android/graphics/RecordingCanvas";
Romain Guye4d01122010-06-16 18:44:05 -0700191
192static JNINativeMethod gMethods[] = {
Romain Guy16393512010-08-08 00:14:31 -0700193
John Reck5cb74bc2016-10-07 11:24:44 -0700194 // ------------ @FastNative ------------------
195
John Reck5cb74bc2016-10-07 11:24:44 -0700196 { "nCallDrawGLFunction", "(JJLjava/lang/Runnable;)V",
John Reckcd1c3eb2016-04-14 10:38:54 -0700197 (void*) android_view_DisplayListCanvas_callDrawGLFunction },
Romain Guy7d7b5492011-01-24 16:33:45 -0800198
Chris Craikfc294242016-12-13 18:10:46 -0800199 // ------------ @CriticalNative --------------
Stan Ilievc0e7a902016-10-13 17:07:09 -0400200 { "nCreateDisplayListCanvas", "(JII)J", (void*) android_view_DisplayListCanvas_createDisplayListCanvas },
Chris Craikfc294242016-12-13 18:10:46 -0800201 { "nResetDisplayListCanvas", "(JJII)V", (void*) android_view_DisplayListCanvas_resetDisplayListCanvas },
John Recke4c1e6c2018-05-24 16:27:35 -0700202 { "nGetMaximumTextureWidth", "()I", (void*) android_view_DisplayListCanvas_getMaxTextureSize },
203 { "nGetMaximumTextureHeight", "()I", (void*) android_view_DisplayListCanvas_getMaxTextureSize },
Chris Craikfc294242016-12-13 18:10:46 -0800204 { "nInsertReorderBarrier", "(JZ)V", (void*) android_view_DisplayListCanvas_insertReorderBarrier },
205 { "nFinishRecording", "(J)J", (void*) android_view_DisplayListCanvas_finishRecording },
206 { "nDrawRenderNode", "(JJ)V", (void*) android_view_DisplayListCanvas_drawRenderNode },
John Reck9d8d99d2018-02-21 12:55:41 -0800207 { "nDrawTextureLayer", "(JJ)V", (void*) android_view_DisplayListCanvas_drawTextureLayer },
Chris Craikfc294242016-12-13 18:10:46 -0800208 { "nDrawCircle", "(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps },
209 { "nDrawRoundRect", "(JJJJJJJJ)V",(void*) android_view_DisplayListCanvas_drawRoundRectProps },
John Reck283bb462018-12-13 16:40:14 -0800210 { "nDrawWebViewFunctor", "(JI)V", (void*) android_view_DisplayListCanvas_drawWebViewFunctor },
Romain Guye4d01122010-06-16 18:44:05 -0700211};
212
Chris Craikc9070eb2015-03-09 18:50:14 -0700213int register_android_view_DisplayListCanvas(JNIEnv* env) {
John Reckcd1c3eb2016-04-14 10:38:54 -0700214 jclass runnableClass = FindClassOrDie(env, "java/lang/Runnable");
215 gRunnableMethodId = GetMethodIDOrDie(env, runnableClass, "run", "()V");
216
Andreas Gampe987f79f2014-11-18 17:29:46 -0800217 return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
Romain Guye4d01122010-06-16 18:44:05 -0700218}
219
Romain Guye4d01122010-06-16 18:44:05 -0700220};