• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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