android_view_DisplayListCanvas.cpp revision b73396b3f89de9620ab6e3d37b25f7451584789c
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#define LOG_TAG "OpenGLRenderer"
18
19#include "jni.h"
20#include "GraphicsJNI.h"
21#include <nativehelper/JNIHelp.h>
22
23#include <android_runtime/AndroidRuntime.h>
24
25#include <cutils/properties.h>
26
27#include <SkBitmap.h>
28#include <SkRegion.h>
29
30
31#include <Canvas.h>
32#include <Rect.h>
33#include <RenderNode.h>
34#include <CanvasProperty.h>
35#include <Paint.h>
36#include <renderthread/RenderProxy.h>
37
38#include "core_jni_helpers.h"
39
40namespace android {
41
42using namespace uirenderer;
43
44// ----------------------------------------------------------------------------
45// Setup
46// ----------------------------------------------------------------------------
47
48static void android_view_DisplayListCanvas_insertReorderBarrier(JNIEnv* env, jobject clazz,
49        jlong canvasPtr, jboolean reorderEnable) {
50    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
51    canvas->insertReorderBarrier(reorderEnable);
52}
53
54// ----------------------------------------------------------------------------
55// Functor
56// ----------------------------------------------------------------------------
57
58static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
59        jlong canvasPtr, jlong functorPtr) {
60    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
61    Functor* functor = reinterpret_cast<Functor*>(functorPtr);
62    canvas->callDrawGLFunction(functor);
63}
64
65// ----------------------------------------------------------------------------
66// Misc
67// ----------------------------------------------------------------------------
68
69static jint android_view_DisplayListCanvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) {
70    if (!Caches::hasInstance()) {
71        android::uirenderer::renderthread::RenderProxy::staticFence();
72    }
73    return Caches::getInstance().maxTextureSize;
74}
75
76static jint android_view_DisplayListCanvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) {
77    if (!Caches::hasInstance()) {
78        android::uirenderer::renderthread::RenderProxy::staticFence();
79    }
80    return Caches::getInstance().maxTextureSize;
81}
82
83// ----------------------------------------------------------------------------
84// Drawing
85// ----------------------------------------------------------------------------
86
87static void android_view_DisplayListCanvas_drawRoundRectProps(JNIEnv* env, jobject clazz,
88        jlong canvasPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
89        jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
90    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
91    CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
92    CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
93    CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
94    CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr);
95    CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr);
96    CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr);
97    CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
98    canvas->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
99}
100
101static void android_view_DisplayListCanvas_drawCircleProps(JNIEnv* env, jobject clazz,
102        jlong canvasPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
103    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
104    CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
105    CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
106    CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
107    CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
108    canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
109}
110
111// ----------------------------------------------------------------------------
112// Display lists
113// ----------------------------------------------------------------------------
114
115static jlong android_view_DisplayListCanvas_finishRecording(JNIEnv* env,
116        jobject clazz, jlong canvasPtr) {
117    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
118    return reinterpret_cast<jlong>(canvas->finishRecording());
119}
120
121static jlong android_view_DisplayListCanvas_createDisplayListCanvas(JNIEnv* env, jobject clazz,
122        jint width, jint height) {
123    return reinterpret_cast<jlong>(Canvas::create_recording_canvas(width, height));
124}
125
126static void android_view_DisplayListCanvas_resetDisplayListCanvas(JNIEnv* env, jobject clazz,
127        jlong canvasPtr, jint width, jint height) {
128    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
129    canvas->resetRecording(width, height);
130}
131
132
133static void android_view_DisplayListCanvas_drawRenderNode(JNIEnv* env,
134        jobject clazz, jlong canvasPtr, jlong renderNodePtr) {
135    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
136    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
137    canvas->drawRenderNode(renderNode);
138}
139
140// ----------------------------------------------------------------------------
141// Layers
142// ----------------------------------------------------------------------------
143
144static void android_view_DisplayListCanvas_drawLayer(JNIEnv* env, jobject clazz,
145        jlong canvasPtr, jlong layerPtr) {
146    Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
147    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
148    canvas->drawLayer(layer);
149}
150
151// ----------------------------------------------------------------------------
152// Common
153// ----------------------------------------------------------------------------
154
155static jboolean android_view_DisplayListCanvas_isAvailable(JNIEnv* env, jobject clazz) {
156    char prop[PROPERTY_VALUE_MAX];
157    if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
158        // not in the emulator
159        return JNI_TRUE;
160    }
161    // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
162    // enabled, 0 otherwise. On old emulator versions it will be undefined.
163    property_get("qemu.gles", prop, "0");
164    return atoi(prop) > 0 ? JNI_TRUE : JNI_FALSE;
165}
166
167// ----------------------------------------------------------------------------
168// Logging
169// ----------------------------------------------------------------------------
170
171static void
172android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
173    int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
174    android::uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd);
175}
176
177// ----------------------------------------------------------------------------
178// JNI Glue
179// ----------------------------------------------------------------------------
180
181const char* const kClassPathName = "android/view/DisplayListCanvas";
182
183static JNINativeMethod gMethods[] = {
184    { "nIsAvailable",       "!()Z",             (void*) android_view_DisplayListCanvas_isAvailable },
185    { "nInsertReorderBarrier","!(JZ)V",         (void*) android_view_DisplayListCanvas_insertReorderBarrier },
186
187    { "nCallDrawGLFunction", "!(JJ)V",          (void*) android_view_DisplayListCanvas_callDrawGLFunction },
188
189    { "nDrawRoundRect",     "!(JJJJJJJJ)V",     (void*) android_view_DisplayListCanvas_drawRoundRectProps },
190    { "nDrawCircle",        "!(JJJJJ)V",        (void*) android_view_DisplayListCanvas_drawCircleProps },
191
192    { "nFinishRecording",   "!(J)J",            (void*) android_view_DisplayListCanvas_finishRecording },
193    { "nDrawRenderNode",    "!(JJ)V",           (void*) android_view_DisplayListCanvas_drawRenderNode },
194
195    { "nCreateDisplayListCanvas", "!(II)J",     (void*) android_view_DisplayListCanvas_createDisplayListCanvas },
196    { "nResetDisplayListCanvas", "!(JII)V",     (void*) android_view_DisplayListCanvas_resetDisplayListCanvas },
197
198    { "nDrawLayer",               "!(JJ)V",     (void*) android_view_DisplayListCanvas_drawLayer },
199
200    { "nGetMaximumTextureWidth",  "!()I",       (void*) android_view_DisplayListCanvas_getMaxTextureWidth },
201    { "nGetMaximumTextureHeight", "!()I",       (void*) android_view_DisplayListCanvas_getMaxTextureHeight },
202};
203
204static JNINativeMethod gActivityThreadMethods[] = {
205    { "dumpGraphicsInfo",        "(Ljava/io/FileDescriptor;)V",
206                                               (void*) android_app_ActivityThread_dumpGraphics }
207};
208
209int register_android_view_DisplayListCanvas(JNIEnv* env) {
210    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
211}
212
213int register_android_app_ActivityThread(JNIEnv* env) {
214    return RegisterMethodsOrDie(env, "android/app/ActivityThread",
215            gActivityThreadMethods, NELEM(gActivityThreadMethods));
216}
217
218};
219