1 /*
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
17 #include "GraphicsJNI.h"
18
19 #ifdef __ANDROID__ // Layoutlib does not support Looper and device properties
20 #include <utils/Looper.h>
21 #endif
22
23 #include <SkRegion.h>
24 #include <SkRuntimeEffect.h>
25
26 #include <Rect.h>
27 #include <RenderNode.h>
28 #include <CanvasProperty.h>
29 #include <hwui/Canvas.h>
30 #include <hwui/Paint.h>
31 #include <minikin/Layout.h>
32 #ifdef __ANDROID__ // Layoutlib does not support RenderThread
33 #include <renderthread/RenderProxy.h>
34 #endif
35
36 namespace android {
37
38 using namespace uirenderer;
39
40 jmethodID gRunnableMethodId;
41
jnienv(JavaVM * vm)42 static JNIEnv* jnienv(JavaVM* vm) {
43 JNIEnv* env;
44 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
45 LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
46 }
47 return env;
48 }
49
50 #ifdef __ANDROID__ // Layoutlib does not support GL, Looper
51 class InvokeRunnableMessage : public MessageHandler {
52 public:
InvokeRunnableMessage(JNIEnv * env,jobject runnable)53 InvokeRunnableMessage(JNIEnv* env, jobject runnable) {
54 mRunnable = env->NewGlobalRef(runnable);
55 env->GetJavaVM(&mVm);
56 }
57
~InvokeRunnableMessage()58 virtual ~InvokeRunnableMessage() {
59 jnienv(mVm)->DeleteGlobalRef(mRunnable);
60 }
61
handleMessage(const Message &)62 virtual void handleMessage(const Message&) {
63 jnienv(mVm)->CallVoidMethod(mRunnable, gRunnableMethodId);
64 }
65
66 private:
67 JavaVM* mVm;
68 jobject mRunnable;
69 };
70 #endif
71
72 // ---------------- @CriticalNative -------------------------
73
android_view_DisplayListCanvas_createDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,jint width,jint height)74 static jlong android_view_DisplayListCanvas_createDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
75 jint width, jint height) {
76 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
77 return reinterpret_cast<jlong>(Canvas::create_recording_canvas(width, height, renderNode));
78 }
79
android_view_DisplayListCanvas_resetDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jlong renderNodePtr,jint width,jint height)80 static void android_view_DisplayListCanvas_resetDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
81 jlong renderNodePtr, jint width, jint height) {
82 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
83 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
84 canvas->resetRecording(width, height, renderNode);
85 }
86
android_view_DisplayListCanvas_getMaxTextureSize(CRITICAL_JNI_PARAMS)87 static jint android_view_DisplayListCanvas_getMaxTextureSize(CRITICAL_JNI_PARAMS) {
88 #ifdef __ANDROID__ // Layoutlib does not support RenderProxy (RenderThread)
89 return android::uirenderer::renderthread::RenderProxy::maxTextureSize();
90 #else
91 return 4096;
92 #endif
93 }
94
android_view_DisplayListCanvas_enableZ(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jboolean reorderEnable)95 static void android_view_DisplayListCanvas_enableZ(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
96 jboolean reorderEnable) {
97 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
98 canvas->enableZ(reorderEnable);
99 }
100
android_view_DisplayListCanvas_finishRecording(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jlong renderNodePtr)101 static void android_view_DisplayListCanvas_finishRecording(
102 CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong renderNodePtr) {
103 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
104 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
105 canvas->finishRecording(renderNode);
106 }
107
android_view_DisplayListCanvas_drawRenderNode(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jlong renderNodePtr)108 static void android_view_DisplayListCanvas_drawRenderNode(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong renderNodePtr) {
109 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
110 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
111 canvas->drawRenderNode(renderNode);
112 }
113
android_view_DisplayListCanvas_drawTextureLayer(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jlong layerPtr)114 static void android_view_DisplayListCanvas_drawTextureLayer(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong layerPtr) {
115 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
116 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
117 canvas->drawLayer(layer);
118 }
119
android_view_DisplayListCanvas_drawRoundRectProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jlong leftPropPtr,jlong topPropPtr,jlong rightPropPtr,jlong bottomPropPtr,jlong rxPropPtr,jlong ryPropPtr,jlong paintPropPtr)120 static void android_view_DisplayListCanvas_drawRoundRectProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
121 jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr, jlong bottomPropPtr,
122 jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
123 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
124 CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
125 CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
126 CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
127 CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr);
128 CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr);
129 CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr);
130 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
131 canvas->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
132 }
133
android_view_DisplayListCanvas_drawCircleProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jlong xPropPtr,jlong yPropPtr,jlong radiusPropPtr,jlong paintPropPtr)134 static void android_view_DisplayListCanvas_drawCircleProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
135 jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
136 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
137 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
138 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
139 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
140 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
141 canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
142 }
143
android_view_DisplayListCanvas_drawRippleProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jlong xPropPtr,jlong yPropPtr,jlong radiusPropPtr,jlong paintPropPtr,jlong progressPropPtr,jlong turbulencePhasePtr,jint color,jlong builderPtr)144 static void android_view_DisplayListCanvas_drawRippleProps(
145 CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong xPropPtr, jlong yPropPtr,
146 jlong radiusPropPtr, jlong paintPropPtr, jlong progressPropPtr, jlong turbulencePhasePtr,
147 jint color, jlong builderPtr) {
148 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
149 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
150 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
151 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
152 CanvasPropertyPrimitive* turbulencePhaseProp =
153 reinterpret_cast<CanvasPropertyPrimitive*>(turbulencePhasePtr);
154 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
155 CanvasPropertyPrimitive* progressProp =
156 reinterpret_cast<CanvasPropertyPrimitive*>(progressPropPtr);
157 SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(builderPtr);
158
159 const uirenderer::skiapipeline::RippleDrawableParams params =
160 uirenderer::skiapipeline::RippleDrawableParams{
161 xProp, yProp, radiusProp, progressProp, turbulencePhaseProp,
162 (SkColor)color, paintProp, *builder};
163 canvas->drawRipple(params);
164 }
165
android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,jint functor)166 static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jint functor) {
167 Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
168 canvas->drawWebViewFunctor(functor);
169 }
170
171 // ----------------------------------------------------------------------------
172 // JNI Glue
173 // ----------------------------------------------------------------------------
174
175 const char* const kClassPathName = "android/graphics/RecordingCanvas";
176
177 static JNINativeMethod gMethods[] = {
178 // ------------ @CriticalNative --------------
179 {"nCreateDisplayListCanvas", "(JII)J",
180 (void*)android_view_DisplayListCanvas_createDisplayListCanvas},
181 {"nResetDisplayListCanvas", "(JJII)V",
182 (void*)android_view_DisplayListCanvas_resetDisplayListCanvas},
183 {"nGetMaximumTextureWidth", "()I", (void*)android_view_DisplayListCanvas_getMaxTextureSize},
184 {"nGetMaximumTextureHeight", "()I",
185 (void*)android_view_DisplayListCanvas_getMaxTextureSize},
186 {"nEnableZ", "(JZ)V", (void*)android_view_DisplayListCanvas_enableZ},
187 {"nFinishRecording", "(JJ)V", (void*)android_view_DisplayListCanvas_finishRecording},
188 {"nDrawRenderNode", "(JJ)V", (void*)android_view_DisplayListCanvas_drawRenderNode},
189 {"nDrawTextureLayer", "(JJ)V", (void*)android_view_DisplayListCanvas_drawTextureLayer},
190 {"nDrawCircle", "(JJJJJ)V", (void*)android_view_DisplayListCanvas_drawCircleProps},
191 {"nDrawRoundRect", "(JJJJJJJJ)V", (void*)android_view_DisplayListCanvas_drawRoundRectProps},
192 {"nDrawWebViewFunctor", "(JI)V", (void*)android_view_DisplayListCanvas_drawWebViewFunctor},
193 {"nDrawRipple", "(JJJJJJJIJ)V", (void*)android_view_DisplayListCanvas_drawRippleProps},
194 };
195
register_android_view_DisplayListCanvas(JNIEnv * env)196 int register_android_view_DisplayListCanvas(JNIEnv* env) {
197 jclass runnableClass = FindClassOrDie(env, "java/lang/Runnable");
198 gRunnableMethodId = GetMethodIDOrDie(env, runnableClass, "run", "()V");
199
200 return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
201 }
202
203 };
204