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 <androidfw/ResourceTypes.h> 26 27#include <cutils/properties.h> 28 29#include <SkBitmap.h> 30#include <SkRegion.h> 31 32#include <DisplayListCanvas.h> 33#include <Rect.h> 34#include <RenderNode.h> 35#include <CanvasProperty.h> 36#include <Paint.h> 37#include <renderthread/RenderProxy.h> 38 39#include "core_jni_helpers.h" 40 41namespace android { 42 43using namespace uirenderer; 44 45static struct { 46 jmethodID set; 47} gRectClassInfo; 48 49// ---------------------------------------------------------------------------- 50// Setup 51// ---------------------------------------------------------------------------- 52 53static void android_view_DisplayListCanvas_setViewport(JNIEnv* env, jobject clazz, 54 jlong rendererPtr, jint width, jint height) { 55 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 56 renderer->setViewport(width, height); 57} 58 59static void android_view_DisplayListCanvas_setHighContrastText(JNIEnv* env, jobject clazz, 60 jlong rendererPtr, jboolean highContrastText) { 61 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 62 renderer->setHighContrastText(highContrastText); 63} 64 65static void android_view_DisplayListCanvas_insertReorderBarrier(JNIEnv* env, jobject clazz, 66 jlong rendererPtr, jboolean reorderEnable) { 67 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 68 renderer->insertReorderBarrier(reorderEnable); 69} 70 71static void android_view_DisplayListCanvas_prepare(JNIEnv* env, jobject clazz, 72 jlong rendererPtr) { 73 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 74 renderer->prepare(); 75} 76 77static void android_view_DisplayListCanvas_prepareDirty(JNIEnv* env, jobject clazz, 78 jlong rendererPtr, jint left, jint top, jint right, jint bottom) { 79 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 80 renderer->prepareDirty(left, top, right, bottom); 81} 82 83static void android_view_DisplayListCanvas_finish(JNIEnv* env, jobject clazz, 84 jlong rendererPtr) { 85 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 86 renderer->finish(); 87} 88 89// ---------------------------------------------------------------------------- 90// Functor 91// ---------------------------------------------------------------------------- 92 93static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz, 94 jlong rendererPtr, jlong functorPtr) { 95 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 96 Functor* functor = reinterpret_cast<Functor*>(functorPtr); 97 renderer->callDrawGLFunction(functor); 98} 99 100// ---------------------------------------------------------------------------- 101// Misc 102// ---------------------------------------------------------------------------- 103 104static jint android_view_DisplayListCanvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) { 105 return Caches::getInstance().maxTextureSize; 106} 107 108static jint android_view_DisplayListCanvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) { 109 return Caches::getInstance().maxTextureSize; 110} 111 112// ---------------------------------------------------------------------------- 113// Drawing 114// ---------------------------------------------------------------------------- 115 116static void android_view_DisplayListCanvas_drawPatch(JNIEnv* env, jobject clazz, 117 jlong rendererPtr, jobject jbitmap, jlong patchPtr, 118 float left, float top, float right, float bottom, jlong paintPtr) { 119 SkBitmap bitmap; 120 GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); 121 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 122 Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr); 123 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 124 renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint); 125} 126 127static void android_view_DisplayListCanvas_drawRoundRectProps(JNIEnv* env, jobject clazz, 128 jlong rendererPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr, 129 jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) { 130 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 131 CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr); 132 CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr); 133 CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr); 134 CanvasPropertyPrimitive* bottomProp = reinterpret_cast<CanvasPropertyPrimitive*>(bottomPropPtr); 135 CanvasPropertyPrimitive* rxProp = reinterpret_cast<CanvasPropertyPrimitive*>(rxPropPtr); 136 CanvasPropertyPrimitive* ryProp = reinterpret_cast<CanvasPropertyPrimitive*>(ryPropPtr); 137 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr); 138 renderer->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp); 139} 140 141static void android_view_DisplayListCanvas_drawCircleProps(JNIEnv* env, jobject clazz, 142 jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) { 143 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 144 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr); 145 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr); 146 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr); 147 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr); 148 renderer->drawCircle(xProp, yProp, radiusProp, paintProp); 149} 150 151static void android_view_DisplayListCanvas_drawRegionAsRects(JNIEnv* env, jobject clazz, 152 jlong rendererPtr, jlong regionPtr, jlong paintPtr) { 153 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 154 SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr); 155 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 156 if (paint->getStyle() != Paint::kFill_Style || 157 (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) { 158 SkRegion::Iterator it(*region); 159 while (!it.done()) { 160 const SkIRect& r = it.rect(); 161 renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, *paint); 162 it.next(); 163 } 164 } else { 165 int count = 0; 166 Vector<float> rects; 167 SkRegion::Iterator it(*region); 168 while (!it.done()) { 169 const SkIRect& r = it.rect(); 170 rects.push(r.fLeft); 171 rects.push(r.fTop); 172 rects.push(r.fRight); 173 rects.push(r.fBottom); 174 count += 4; 175 it.next(); 176 } 177 renderer->drawRects(rects.array(), count, paint); 178 } 179} 180 181// ---------------------------------------------------------------------------- 182// Display lists 183// ---------------------------------------------------------------------------- 184 185static jlong android_view_DisplayListCanvas_finishRecording(JNIEnv* env, 186 jobject clazz, jlong rendererPtr) { 187 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 188 return reinterpret_cast<jlong>(renderer->finishRecording()); 189} 190 191static jlong android_view_DisplayListCanvas_createDisplayListCanvas(JNIEnv* env, jobject clazz) { 192 return reinterpret_cast<jlong>(new DisplayListCanvas); 193} 194 195static void android_view_DisplayListCanvas_drawRenderNode(JNIEnv* env, 196 jobject clazz, jlong rendererPtr, jlong renderNodePtr) { 197 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 198 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); 199 renderer->drawRenderNode(renderNode); 200} 201 202// ---------------------------------------------------------------------------- 203// Layers 204// ---------------------------------------------------------------------------- 205 206static void android_view_DisplayListCanvas_drawLayer(JNIEnv* env, jobject clazz, 207 jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) { 208 DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr); 209 DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr); 210 renderer->drawLayer(layer, x, y); 211} 212 213// ---------------------------------------------------------------------------- 214// Common 215// ---------------------------------------------------------------------------- 216 217static jboolean android_view_DisplayListCanvas_isAvailable(JNIEnv* env, jobject clazz) { 218 char prop[PROPERTY_VALUE_MAX]; 219 if (property_get("ro.kernel.qemu", prop, NULL) == 0) { 220 // not in the emulator 221 return JNI_TRUE; 222 } 223 // In the emulator this property will be set to 1 when hardware GLES is 224 // enabled, 0 otherwise. On old emulator versions it will be undefined. 225 property_get("ro.kernel.qemu.gles", prop, "0"); 226 return atoi(prop) == 1 ? JNI_TRUE : JNI_FALSE; 227} 228 229// ---------------------------------------------------------------------------- 230// Logging 231// ---------------------------------------------------------------------------- 232 233static void 234android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) { 235 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); 236 android::uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd); 237} 238 239// ---------------------------------------------------------------------------- 240// JNI Glue 241// ---------------------------------------------------------------------------- 242 243const char* const kClassPathName = "android/view/DisplayListCanvas"; 244 245static JNINativeMethod gMethods[] = { 246 { "nIsAvailable", "()Z", (void*) android_view_DisplayListCanvas_isAvailable }, 247 { "nSetViewport", "(JII)V", (void*) android_view_DisplayListCanvas_setViewport }, 248 { "nSetHighContrastText","(JZ)V", (void*) android_view_DisplayListCanvas_setHighContrastText }, 249 { "nInsertReorderBarrier","(JZ)V", (void*) android_view_DisplayListCanvas_insertReorderBarrier }, 250 { "nPrepare", "(J)V", (void*) android_view_DisplayListCanvas_prepare }, 251 { "nPrepareDirty", "(JIIII)V", (void*) android_view_DisplayListCanvas_prepareDirty }, 252 { "nFinish", "(J)V", (void*) android_view_DisplayListCanvas_finish }, 253 254 { "nCallDrawGLFunction", "(JJ)V", (void*) android_view_DisplayListCanvas_callDrawGLFunction }, 255 256 { "nDrawPatch", "(JLandroid/graphics/Bitmap;JFFFFJ)V", (void*) android_view_DisplayListCanvas_drawPatch }, 257 258 { "nDrawRects", "(JJJ)V", (void*) android_view_DisplayListCanvas_drawRegionAsRects }, 259 { "nDrawRoundRect", "(JJJJJJJJ)V", (void*) android_view_DisplayListCanvas_drawRoundRectProps }, 260 { "nDrawCircle", "(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps }, 261 262 { "nFinishRecording", "(J)J", (void*) android_view_DisplayListCanvas_finishRecording }, 263 { "nDrawRenderNode", "(JJ)V", (void*) android_view_DisplayListCanvas_drawRenderNode }, 264 265 { "nCreateDisplayListCanvas", "()J", (void*) android_view_DisplayListCanvas_createDisplayListCanvas }, 266 267 { "nDrawLayer", "(JJFF)V", (void*) android_view_DisplayListCanvas_drawLayer }, 268 269 { "nGetMaximumTextureWidth", "()I", (void*) android_view_DisplayListCanvas_getMaxTextureWidth }, 270 { "nGetMaximumTextureHeight", "()I", (void*) android_view_DisplayListCanvas_getMaxTextureHeight }, 271}; 272 273static JNINativeMethod gActivityThreadMethods[] = { 274 { "dumpGraphicsInfo", "(Ljava/io/FileDescriptor;)V", 275 (void*) android_app_ActivityThread_dumpGraphics } 276}; 277 278int register_android_view_DisplayListCanvas(JNIEnv* env) { 279 jclass clazz = FindClassOrDie(env, "android/graphics/Rect"); 280 gRectClassInfo.set = GetMethodIDOrDie(env, clazz, "set", "(IIII)V"); 281 282 return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); 283} 284 285int register_android_app_ActivityThread(JNIEnv* env) { 286 return RegisterMethodsOrDie(env, "android/app/ActivityThread", 287 gActivityThreadMethods, NELEM(gActivityThreadMethods)); 288} 289 290}; 291