blob: cadfd3d89a2a0809872f7ee4a009e70ecef2a247 [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>
Romain Guy65549432012-03-26 16:45:05 -070024
John Reckcd1c3eb2016-04-14 10:38:54 -070025#include <utils/Looper.h>
Romain Guy65549432012-03-26 16:45:05 -070026#include <cutils/properties.h>
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>
John Reck0e89e2b2014-10-31 14:49:06 -070036#include <renderthread/RenderProxy.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070037
Andreas Gampe987f79f2014-11-18 17:29:46 -080038#include "core_jni_helpers.h"
39
Romain Guye4d01122010-06-16 18:44:05 -070040namespace android {
41
Romain Guy9d5316e2010-06-24 19:30:36 -070042using namespace uirenderer;
43
John Reckcd1c3eb2016-04-14 10:38:54 -070044jmethodID gRunnableMethodId;
45
46static JNIEnv* jnienv(JavaVM* vm) {
47 JNIEnv* env;
48 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
49 LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
50 }
51 return env;
52}
53
54class InvokeRunnableMessage : public MessageHandler {
55public:
56 InvokeRunnableMessage(JNIEnv* env, jobject runnable) {
57 mRunnable = env->NewGlobalRef(runnable);
58 env->GetJavaVM(&mVm);
59 }
60
61 virtual ~InvokeRunnableMessage() {
62 jnienv(mVm)->DeleteGlobalRef(mRunnable);
63 }
64
65 virtual void handleMessage(const Message&) {
66 jnienv(mVm)->CallVoidMethod(mRunnable, gRunnableMethodId);
67 }
68
69private:
70 JavaVM* mVm;
71 jobject mRunnable;
72};
73
74class GlFunctorReleasedCallbackBridge : public GlFunctorLifecycleListener {
75public:
76 GlFunctorReleasedCallbackBridge(JNIEnv* env, jobject javaCallback) {
77 mLooper = Looper::getForThread();
78 mMessage = new InvokeRunnableMessage(env, javaCallback);
79 }
80
81 virtual void onGlFunctorReleased(Functor* functor) override {
82 mLooper->sendMessage(mMessage, 0);
83 }
84
85private:
86 sp<Looper> mLooper;
87 sp<InvokeRunnableMessage> mMessage;
88};
89
Romain Guy244ada12012-03-28 16:41:26 -070090// ----------------------------------------------------------------------------
Romain Guye4d01122010-06-16 18:44:05 -070091// Setup
92// ----------------------------------------------------------------------------
93
Chris Craikc9070eb2015-03-09 18:50:14 -070094static void android_view_DisplayListCanvas_insertReorderBarrier(JNIEnv* env, jobject clazz,
Chris Craik86c03ca2015-08-21 10:44:56 -070095 jlong canvasPtr, jboolean reorderEnable) {
Derek Sollenberger6f485562015-07-30 10:00:39 -040096 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Chris Craik86c03ca2015-08-21 10:44:56 -070097 canvas->insertReorderBarrier(reorderEnable);
Chris Craik8afd0f22014-08-21 17:41:57 -070098}
99
Romain Guy530041d2012-01-25 18:56:29 -0800100// ----------------------------------------------------------------------------
101// Functor
102// ----------------------------------------------------------------------------
103
Chris Craikc9070eb2015-03-09 18:50:14 -0700104static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
John Reckcd1c3eb2016-04-14 10:38:54 -0700105 jlong canvasPtr, jlong functorPtr, jobject releasedCallback) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400106 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Chris Craik9f66ea02013-12-27 15:15:55 -0800107 Functor* functor = reinterpret_cast<Functor*>(functorPtr);
John Reckcd1c3eb2016-04-14 10:38:54 -0700108 sp<GlFunctorReleasedCallbackBridge> bridge(new GlFunctorReleasedCallbackBridge(
109 env, releasedCallback));
110 canvas->callDrawGLFunction(functor, bridge.get());
Chet Haasedaf98e92011-01-10 14:10:36 -0800111}
112
Romain Guy8f3b8e32012-03-27 16:33:45 -0700113// ----------------------------------------------------------------------------
114// Misc
115// ----------------------------------------------------------------------------
116
Chris Craikc9070eb2015-03-09 18:50:14 -0700117static jint android_view_DisplayListCanvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) {
Thomas Buhotc0a0e1a2016-01-18 10:31:58 +0100118 if (!Caches::hasInstance()) {
119 android::uirenderer::renderthread::RenderProxy::staticFence();
120 }
Romain Guyf61970fc2011-07-07 14:10:06 -0700121 return Caches::getInstance().maxTextureSize;
122}
123
Chris Craikc9070eb2015-03-09 18:50:14 -0700124static jint android_view_DisplayListCanvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) {
Thomas Buhotc0a0e1a2016-01-18 10:31:58 +0100125 if (!Caches::hasInstance()) {
126 android::uirenderer::renderthread::RenderProxy::staticFence();
127 }
Romain Guyf61970fc2011-07-07 14:10:06 -0700128 return Caches::getInstance().maxTextureSize;
129}
130
Romain Guye4d01122010-06-16 18:44:05 -0700131// ----------------------------------------------------------------------------
Romain Guybb9524b2010-06-22 18:56:38 -0700132// Drawing
Romain Guy85bf02f2010-06-22 13:11:24 -0700133// ----------------------------------------------------------------------------
134
Chris Craikc9070eb2015-03-09 18:50:14 -0700135static void android_view_DisplayListCanvas_drawRoundRectProps(JNIEnv* env, jobject clazz,
Chris Craik86c03ca2015-08-21 10:44:56 -0700136 jlong canvasPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
Jorim Jaggi072707d2014-09-15 17:20:08 +0200137 jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400138 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Jorim Jaggi072707d2014-09-15 17:20:08 +0200139 CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
140 CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
141 CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
142 CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr);
143 CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr);
144 CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr);
145 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
Chris Craik86c03ca2015-08-21 10:44:56 -0700146 canvas->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
Jorim Jaggi072707d2014-09-15 17:20:08 +0200147}
148
Chris Craikc9070eb2015-03-09 18:50:14 -0700149static void android_view_DisplayListCanvas_drawCircleProps(JNIEnv* env, jobject clazz,
Chris Craik86c03ca2015-08-21 10:44:56 -0700150 jlong canvasPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400151 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
John Reck52244ff2014-05-01 21:27:37 -0700152 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
153 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
154 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
155 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
Chris Craik86c03ca2015-08-21 10:44:56 -0700156 canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
John Reck52244ff2014-05-01 21:27:37 -0700157}
158
Romain Guyb051e892010-09-28 19:09:36 -0700159// ----------------------------------------------------------------------------
160// Display lists
161// ----------------------------------------------------------------------------
162
Chris Craikc9070eb2015-03-09 18:50:14 -0700163static jlong android_view_DisplayListCanvas_finishRecording(JNIEnv* env,
Chris Craik86c03ca2015-08-21 10:44:56 -0700164 jobject clazz, jlong canvasPtr) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400165 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Chris Craik86c03ca2015-08-21 10:44:56 -0700166 return reinterpret_cast<jlong>(canvas->finishRecording());
John Reck44fd8d22014-02-26 11:00:11 -0800167}
168
Derek Sollenbergercc882b62015-07-09 15:51:20 -0400169static jlong android_view_DisplayListCanvas_createDisplayListCanvas(JNIEnv* env, jobject clazz,
170 jint width, jint height) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400171 return reinterpret_cast<jlong>(Canvas::create_recording_canvas(width, height));
Chet Haase5977baa2011-01-05 18:01:22 -0800172}
173
Derek Sollenbergercc882b62015-07-09 15:51:20 -0400174static void android_view_DisplayListCanvas_resetDisplayListCanvas(JNIEnv* env, jobject clazz,
Chris Craik86c03ca2015-08-21 10:44:56 -0700175 jlong canvasPtr, jint width, jint height) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400176 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
177 canvas->resetRecording(width, height);
Derek Sollenbergercc882b62015-07-09 15:51:20 -0400178}
179
180
Chris Craikc9070eb2015-03-09 18:50:14 -0700181static void android_view_DisplayListCanvas_drawRenderNode(JNIEnv* env,
Chris Craik86c03ca2015-08-21 10:44:56 -0700182 jobject clazz, jlong canvasPtr, jlong renderNodePtr) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400183 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
Chris Craika7090e02014-06-20 16:01:00 -0700184 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
Chris Craik86c03ca2015-08-21 10:44:56 -0700185 canvas->drawRenderNode(renderNode);
Romain Guyb051e892010-09-28 19:09:36 -0700186}
187
Romain Guy6c319ca2011-01-11 14:29:25 -0800188// ----------------------------------------------------------------------------
189// Layers
190// ----------------------------------------------------------------------------
191
Chris Craikc9070eb2015-03-09 18:50:14 -0700192static void android_view_DisplayListCanvas_drawLayer(JNIEnv* env, jobject clazz,
Chris Craik86c03ca2015-08-21 10:44:56 -0700193 jlong canvasPtr, jlong layerPtr) {
Derek Sollenberger6f485562015-07-30 10:00:39 -0400194 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
John Reck12f5e342014-11-07 07:53:43 -0800195 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
Chris Craik86c03ca2015-08-21 10:44:56 -0700196 canvas->drawLayer(layer);
Romain Guy6c319ca2011-01-11 14:29:25 -0800197}
198
Romain Guy16393512010-08-08 00:14:31 -0700199// ----------------------------------------------------------------------------
200// Common
201// ----------------------------------------------------------------------------
202
Chris Craikc9070eb2015-03-09 18:50:14 -0700203static jboolean android_view_DisplayListCanvas_isAvailable(JNIEnv* env, jobject clazz) {
John Reck069fb3a2015-11-03 20:39:51 +0000204 char prop[PROPERTY_VALUE_MAX];
205 if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
206 // not in the emulator
207 return JNI_TRUE;
Jesse Hall44063452011-12-01 11:27:45 -0800208 }
Nicolas Capensac465ce2015-11-03 17:18:35 -0500209 // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
John Reck069fb3a2015-11-03 20:39:51 +0000210 // enabled, 0 otherwise. On old emulator versions it will be undefined.
bohub73396b2016-02-19 17:09:00 -0800211 property_get("qemu.gles", prop, "0");
Nicolas Capensac465ce2015-11-03 17:18:35 -0500212 return atoi(prop) > 0 ? JNI_TRUE : JNI_FALSE;
Romain Guy16393512010-08-08 00:14:31 -0700213}
214
Romain Guya1db5742010-07-20 13:09:13 -0700215// ----------------------------------------------------------------------------
Chet Haase9c1e23b2011-03-24 10:51:31 -0700216// Logging
217// ----------------------------------------------------------------------------
218
Chet Haase9c1e23b2011-03-24 10:51:31 -0700219static void
Romain Guy65b345f2011-07-27 18:51:50 -0700220android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
John Recka2732a22014-12-18 13:52:33 -0800221 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
Chris Craik2ae07332015-01-21 14:22:39 -0800222 android::uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd);
Chet Haase9c1e23b2011-03-24 10:51:31 -0700223}
224
225// ----------------------------------------------------------------------------
Romain Guye4d01122010-06-16 18:44:05 -0700226// JNI Glue
227// ----------------------------------------------------------------------------
228
Chris Craikc9070eb2015-03-09 18:50:14 -0700229const char* const kClassPathName = "android/view/DisplayListCanvas";
Romain Guye4d01122010-06-16 18:44:05 -0700230
231static JNINativeMethod gMethods[] = {
John Reck0dba1f62015-10-05 11:15:36 -0700232 { "nIsAvailable", "!()Z", (void*) android_view_DisplayListCanvas_isAvailable },
233 { "nInsertReorderBarrier","!(JZ)V", (void*) android_view_DisplayListCanvas_insertReorderBarrier },
Romain Guy16393512010-08-08 00:14:31 -0700234
John Reckcd1c3eb2016-04-14 10:38:54 -0700235 { "nCallDrawGLFunction", "!(JJLjava/lang/Runnable;)V",
236 (void*) android_view_DisplayListCanvas_callDrawGLFunction },
Romain Guy7d7b5492011-01-24 16:33:45 -0800237
John Reck0dba1f62015-10-05 11:15:36 -0700238 { "nDrawRoundRect", "!(JJJJJJJJ)V", (void*) android_view_DisplayListCanvas_drawRoundRectProps },
239 { "nDrawCircle", "!(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps },
Romain Guyb051e892010-09-28 19:09:36 -0700240
John Reck0dba1f62015-10-05 11:15:36 -0700241 { "nFinishRecording", "!(J)J", (void*) android_view_DisplayListCanvas_finishRecording },
242 { "nDrawRenderNode", "!(JJ)V", (void*) android_view_DisplayListCanvas_drawRenderNode },
Romain Guy13631f32012-01-30 17:41:55 -0800243
John Reck0dba1f62015-10-05 11:15:36 -0700244 { "nCreateDisplayListCanvas", "!(II)J", (void*) android_view_DisplayListCanvas_createDisplayListCanvas },
245 { "nResetDisplayListCanvas", "!(JII)V", (void*) android_view_DisplayListCanvas_resetDisplayListCanvas },
Romain Guy13631f32012-01-30 17:41:55 -0800246
John Reck0dba1f62015-10-05 11:15:36 -0700247 { "nDrawLayer", "!(JJ)V", (void*) android_view_DisplayListCanvas_drawLayer },
Romain Guyb051e892010-09-28 19:09:36 -0700248
John Reck0dba1f62015-10-05 11:15:36 -0700249 { "nGetMaximumTextureWidth", "!()I", (void*) android_view_DisplayListCanvas_getMaxTextureWidth },
250 { "nGetMaximumTextureHeight", "!()I", (void*) android_view_DisplayListCanvas_getMaxTextureHeight },
Romain Guye4d01122010-06-16 18:44:05 -0700251};
252
Chet Haase9c1e23b2011-03-24 10:51:31 -0700253static JNINativeMethod gActivityThreadMethods[] = {
254 { "dumpGraphicsInfo", "(Ljava/io/FileDescriptor;)V",
255 (void*) android_app_ActivityThread_dumpGraphics }
256};
257
Chris Craikc9070eb2015-03-09 18:50:14 -0700258int register_android_view_DisplayListCanvas(JNIEnv* env) {
John Reckcd1c3eb2016-04-14 10:38:54 -0700259 jclass runnableClass = FindClassOrDie(env, "java/lang/Runnable");
260 gRunnableMethodId = GetMethodIDOrDie(env, runnableClass, "run", "()V");
261
Andreas Gampe987f79f2014-11-18 17:29:46 -0800262 return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
Romain Guye4d01122010-06-16 18:44:05 -0700263}
264
Romain Guy6be3d552011-07-14 18:08:37 -0700265int register_android_app_ActivityThread(JNIEnv* env) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800266 return RegisterMethodsOrDie(env, "android/app/ActivityThread",
Chet Haase9c1e23b2011-03-24 10:51:31 -0700267 gActivityThreadMethods, NELEM(gActivityThreadMethods));
268}
269
Romain Guye4d01122010-06-16 18:44:05 -0700270};