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