android_view_GLES20Canvas.cpp revision 2836c4722a156ec78d7f4101b394885a354f5dd6
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_view_GraphicBuffer.h" 24 25#include <android_runtime/AndroidRuntime.h> 26#include <android_runtime/android_graphics_SurfaceTexture.h> 27 28#include <androidfw/ResourceTypes.h> 29 30#include <gui/GLConsumer.h> 31 32#include <private/hwui/DrawGlInfo.h> 33 34#include <cutils/properties.h> 35 36#include <SkBitmap.h> 37#include <SkCanvas.h> 38#include <SkMatrix.h> 39#include <SkPaint.h> 40#include <SkRegion.h> 41#include <SkScalerContext.h> 42#include <SkTemplates.h> 43#include <SkXfermode.h> 44 45#include <DisplayListRenderer.h> 46#include <LayerRenderer.h> 47#include <OpenGLRenderer.h> 48#include <SkiaShader.h> 49#include <Stencil.h> 50#include <Rect.h> 51#include <RenderNode.h> 52#include <CanvasProperty.h> 53 54#ifdef USE_MINIKIN 55#include <minikin/Layout.h> 56#include "MinikinSkia.h" 57#include "MinikinUtils.h" 58#endif 59 60#include <TextLayout.h> 61#include <TextLayoutCache.h> 62 63namespace android { 64 65using namespace uirenderer; 66 67/** 68 * Note: OpenGLRenderer JNI layer is generated and compiled only on supported 69 * devices. This means all the logic must be compiled only when the 70 * preprocessor variable USE_OPENGL_RENDERER is defined. 71 */ 72#ifdef USE_OPENGL_RENDERER 73 74// ---------------------------------------------------------------------------- 75// Defines 76// ---------------------------------------------------------------------------- 77 78// Debug 79#define DEBUG_RENDERER 0 80 81// Debug 82#if DEBUG_RENDERER 83 #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__) 84#else 85 #define RENDERER_LOGD(...) 86#endif 87 88#define MODIFIER_SHADER 2 89 90// ---------------------------------------------------------------------------- 91 92static struct { 93 jmethodID set; 94} gRectClassInfo; 95 96// ---------------------------------------------------------------------------- 97// Caching 98// ---------------------------------------------------------------------------- 99 100static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz, 101 jint mode) { 102 if (Caches::hasInstance()) { 103 Caches::getInstance().flush(static_cast<Caches::FlushMode>(mode)); 104 } 105} 106 107static jboolean android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) { 108 if (Caches::hasInstance()) { 109 return Caches::getInstance().init() ? JNI_TRUE : JNI_FALSE; 110 } 111 return JNI_FALSE; 112} 113 114static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz) { 115 if (Caches::hasInstance()) { 116 Caches::getInstance().terminate(); 117 } 118} 119 120// ---------------------------------------------------------------------------- 121// Caching 122// ---------------------------------------------------------------------------- 123 124static void android_view_GLES20Canvas_initAtlas(JNIEnv* env, jobject clazz, 125 jobject graphicBuffer, jlongArray atlasMapArray, jint count) { 126 127 sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer); 128 jlong* jAtlasMap = env->GetLongArrayElements(atlasMapArray, NULL); 129 Caches::getInstance().assetAtlas.init(buffer, jAtlasMap, count); 130 env->ReleaseLongArrayElements(atlasMapArray, jAtlasMap, 0); 131} 132 133// ---------------------------------------------------------------------------- 134// Constructors 135// ---------------------------------------------------------------------------- 136 137static jlong android_view_GLES20Canvas_createRenderer(JNIEnv* env, jobject clazz) { 138 RENDERER_LOGD("Create OpenGLRenderer"); 139 OpenGLRenderer* renderer = new OpenGLRenderer(); 140 renderer->initProperties(); 141 return reinterpret_cast<jlong>(renderer); 142} 143 144static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz, 145 jlong rendererPtr) { 146 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 147 RENDERER_LOGD("Destroy OpenGLRenderer"); 148 delete renderer; 149} 150 151// ---------------------------------------------------------------------------- 152// Setup 153// ---------------------------------------------------------------------------- 154 155static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz, 156 jlong rendererPtr, jint width, jint height) { 157 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 158 renderer->setViewport(width, height); 159} 160 161static int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz, 162 jlong rendererPtr, jboolean opaque) { 163 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 164 return renderer->prepare(opaque); 165} 166 167static int android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz, 168 jlong rendererPtr, jint left, jint top, jint right, jint bottom, 169 jboolean opaque) { 170 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 171 return renderer->prepareDirty(left, top, right, bottom, opaque); 172} 173 174static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz, 175 jlong rendererPtr) { 176 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 177 renderer->finish(); 178} 179 180static jint android_view_GLES20Canvas_getStencilSize(JNIEnv* env, jobject clazz) { 181 return Stencil::getStencilSize(); 182} 183 184static void android_view_GLES20Canvas_setProperty(JNIEnv* env, 185 jobject clazz, jstring name, jstring value) { 186 if (!Caches::hasInstance()) { 187 ALOGW("can't set property, no Caches instance"); 188 return; 189 } 190 191 if (name == NULL || value == NULL) { 192 ALOGW("can't set prop, null passed"); 193 } 194 195 const char* nameCharArray = env->GetStringUTFChars(name, NULL); 196 const char* valueCharArray = env->GetStringUTFChars(value, NULL); 197 Caches::getInstance().setTempProperty(nameCharArray, valueCharArray); 198 env->ReleaseStringUTFChars(name, nameCharArray); 199 env->ReleaseStringUTFChars(name, valueCharArray); 200} 201 202// ---------------------------------------------------------------------------- 203// Functor 204// ---------------------------------------------------------------------------- 205 206static jint android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz, 207 jlong rendererPtr, jlong functorPtr) { 208 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 209 Functor* functor = reinterpret_cast<Functor*>(functorPtr); 210 android::uirenderer::Rect dirty; 211 return renderer->callDrawGLFunction(functor, dirty); 212} 213 214// ---------------------------------------------------------------------------- 215// Misc 216// ---------------------------------------------------------------------------- 217 218static jint android_view_GLES20Canvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) { 219 return Caches::getInstance().maxTextureSize; 220} 221 222static jint android_view_GLES20Canvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) { 223 return Caches::getInstance().maxTextureSize; 224} 225 226// ---------------------------------------------------------------------------- 227// State 228// ---------------------------------------------------------------------------- 229 230static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, jlong rendererPtr, 231 jint flags) { 232 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 233 return renderer->save(flags); 234} 235 236static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz, 237 jlong rendererPtr) { 238 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 239 return renderer->getSaveCount(); 240} 241 242static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz, 243 jlong rendererPtr) { 244 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 245 renderer->restore(); 246} 247 248static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz, 249 jlong rendererPtr, jint saveCount) { 250 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 251 renderer->restoreToCount(saveCount); 252} 253 254// ---------------------------------------------------------------------------- 255// Layers 256// ---------------------------------------------------------------------------- 257 258static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz, 259 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 260 jlong paintPtr, jint saveFlags) { 261 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 262 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 263 return renderer->saveLayer(left, top, right, bottom, paint, saveFlags); 264} 265 266static jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz, 267 jlong rendererPtr, jlong paintPtr, jint saveFlags) { 268 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 269 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 270 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds()); 271 return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, 272 paint, saveFlags); 273} 274 275static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz, 276 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 277 jint alpha, jint saveFlags) { 278 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 279 return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags); 280} 281 282static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz, 283 jlong rendererPtr, jint alpha, jint saveFlags) { 284 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 285 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds()); 286 return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, 287 alpha, saveFlags); 288} 289 290// ---------------------------------------------------------------------------- 291// Clipping 292// ---------------------------------------------------------------------------- 293 294static jboolean android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz, 295 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom) { 296 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 297 const bool result = renderer->quickRejectConservative(left, top, right, bottom); 298 return result ? JNI_TRUE : JNI_FALSE; 299} 300 301static jboolean android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz, 302 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 303 jint op) { 304 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 305 const bool result = renderer->clipRect(left, top, right, bottom, 306 static_cast<SkRegion::Op>(op)); 307 return result ? JNI_TRUE : JNI_FALSE; 308} 309 310static jboolean android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz, 311 jlong rendererPtr, jint left, jint top, jint right, jint bottom, 312 jint op) { 313 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 314 const bool result = renderer->clipRect(float(left), float(top), float(right), 315 float(bottom), 316 static_cast<SkRegion::Op>(op)); 317 return result ? JNI_TRUE : JNI_FALSE; 318} 319 320static jboolean android_view_GLES20Canvas_clipPath(JNIEnv* env, jobject clazz, 321 jlong rendererPtr, jlong pathPtr, jint op) { 322 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 323 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 324 const bool result = renderer->clipPath(path, static_cast<SkRegion::Op>(op)); 325 return result ? JNI_TRUE : JNI_FALSE; 326} 327 328static jboolean android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz, 329 jlong rendererPtr, jlong regionPtr, jint op) { 330 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 331 SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr); 332 const bool result = renderer->clipRegion(region, static_cast<SkRegion::Op>(op)); 333 return result ? JNI_TRUE : JNI_FALSE; 334} 335 336static jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz, 337 jlong rendererPtr, jobject rect) { 338 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 339 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds()); 340 341 env->CallVoidMethod(rect, gRectClassInfo.set, 342 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); 343 344 return !bounds.isEmpty() ? JNI_TRUE : JNI_FALSE; 345} 346 347// ---------------------------------------------------------------------------- 348// Transforms 349// ---------------------------------------------------------------------------- 350 351static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz, 352 jlong rendererPtr, jfloat dx, jfloat dy) { 353 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 354 renderer->translate(dx, dy); 355} 356 357static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz, 358 jlong rendererPtr, jfloat degrees) { 359 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 360 renderer->rotate(degrees); 361} 362 363static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz, 364 jlong rendererPtr, jfloat sx, jfloat sy) { 365 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 366 renderer->scale(sx, sy); 367} 368 369static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz, 370 jlong rendererPtr, jfloat sx, jfloat sy) { 371 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 372 renderer->skew(sx, sy); 373} 374 375static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz, 376 jlong rendererPtr, jlong matrixPtr) { 377 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 378 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 379 renderer->setMatrix(matrix); 380} 381 382static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz, 383 jlong rendererPtr, jlong matrixPtr) { 384 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 385 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 386 renderer->getMatrix(matrix); 387} 388 389static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz, 390 jlong rendererPtr, jlong matrixPtr) { 391 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 392 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 393 renderer->concatMatrix(matrix); 394} 395 396// ---------------------------------------------------------------------------- 397// Drawing 398// ---------------------------------------------------------------------------- 399 400static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz, 401 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 402 jfloat left, jfloat top, jlong paintPtr) { 403 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 404 // This object allows the renderer to allocate a global JNI ref to the buffer object. 405 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 406 407 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 408 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 409 renderer->drawBitmap(bitmap, left, top, paint); 410} 411 412static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, 413 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 414 float srcLeft, float srcTop, float srcRight, float srcBottom, 415 float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) { 416 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 417 // This object allows the renderer to allocate a global JNI ref to the buffer object. 418 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 419 420 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 421 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 422 renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, 423 dstLeft, dstTop, dstRight, dstBottom, paint); 424} 425 426static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz, 427 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 428 jlong matrixPtr, jlong paintPtr) { 429 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 430 // This object allows the renderer to allocate a global JNI ref to the buffer object. 431 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 432 433 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 434 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 435 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 436 renderer->drawBitmap(bitmap, matrix, paint); 437} 438 439static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz, 440 jlong rendererPtr, jintArray colors, jint offset, jint stride, 441 jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) { 442 SkBitmap* bitmap = new SkBitmap; 443 bitmap->setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config : SkBitmap::kRGB_565_Config, 444 width, height); 445 446 if (!bitmap->allocPixels()) { 447 delete bitmap; 448 return; 449 } 450 451 if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap, true)) { 452 delete bitmap; 453 return; 454 } 455 456 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 457 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 458 renderer->drawBitmapData(bitmap, left, top, paint); 459 460 // If the renderer is a deferred renderer it will own the bitmap 461 if (!renderer->isRecording()) { 462 delete bitmap; 463 } 464} 465 466static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, 467 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 468 jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors, 469 jint colorOffset, jlong paintPtr) { 470 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 471 // This object allows the renderer to allocate a global JNI ref to the buffer object. 472 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 473 474 jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL; 475 jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL; 476 477 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 478 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 479 renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint); 480 481 if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0); 482 if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0); 483} 484 485static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, 486 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr, 487 float left, float top, float right, float bottom, jlong paintPtr) { 488 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 489 // This object allows the renderer to allocate a global JNI ref to the buffer object. 490 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 491 492 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 493 Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr); 494 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 495 renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint); 496} 497 498static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz, 499 jlong rendererPtr, jint color, jint mode) { 500 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 501 renderer->drawColor(color, static_cast<SkXfermode::Mode>(mode)); 502} 503 504static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz, 505 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 506 jlong paintPtr) { 507 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 508 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 509 renderer->drawRect(left, top, right, bottom, paint); 510} 511 512static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz, 513 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 514 jfloat rx, jfloat ry, jlong paintPtr) { 515 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 516 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 517 renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint); 518} 519 520static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz, 521 jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) { 522 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 523 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 524 renderer->drawCircle(x, y, radius, paint); 525} 526 527static void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz, 528 jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) { 529 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 530 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr); 531 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr); 532 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr); 533 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr); 534 renderer->drawCircle(xProp, yProp, radiusProp, paintProp); 535} 536 537static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz, 538 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 539 jlong paintPtr) { 540 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 541 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 542 renderer->drawOval(left, top, right, bottom, paint); 543} 544 545static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz, 546 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 547 jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) { 548 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 549 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 550 renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint); 551} 552 553static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz, 554 jlong rendererPtr, jlong regionPtr, jlong paintPtr) { 555 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 556 SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr); 557 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 558 if (paint->getStyle() != SkPaint::kFill_Style || 559 (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) { 560 SkRegion::Iterator it(*region); 561 while (!it.done()) { 562 const SkIRect& r = it.rect(); 563 renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint); 564 it.next(); 565 } 566 } else { 567 int count = 0; 568 Vector<float> rects; 569 SkRegion::Iterator it(*region); 570 while (!it.done()) { 571 const SkIRect& r = it.rect(); 572 rects.push(r.fLeft); 573 rects.push(r.fTop); 574 rects.push(r.fRight); 575 rects.push(r.fBottom); 576 count += 4; 577 it.next(); 578 } 579 renderer->drawRects(rects.array(), count, paint); 580 } 581} 582 583static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject clazz, 584 jlong rendererPtr, jfloatArray rects, jint count, jlong paintPtr) { 585 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 586 jfloat* storage = env->GetFloatArrayElements(rects, NULL); 587 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 588 renderer->drawRects(storage, count, paint); 589 env->ReleaseFloatArrayElements(rects, storage, 0); 590} 591 592static void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz, 593 jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) { 594 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 595 jfloat* storage = env->GetFloatArrayElements(points, NULL); 596 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 597 renderer->drawPoints(storage + offset, count, paint); 598 env->ReleaseFloatArrayElements(points, storage, 0); 599} 600 601static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz, 602 jlong rendererPtr, jlong pathPtr, jlong paintPtr) { 603 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 604 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 605 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 606 renderer->drawPath(path, paint); 607} 608 609static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz, 610 jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) { 611 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 612 jfloat* storage = env->GetFloatArrayElements(points, NULL); 613 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 614 renderer->drawLines(storage + offset, count, paint); 615 env->ReleaseFloatArrayElements(points, storage, 0); 616} 617 618// ---------------------------------------------------------------------------- 619// Shaders and color filters 620// ---------------------------------------------------------------------------- 621 622static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject clazz, 623 jlong rendererPtr, jint modifiers) { 624 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 625 if (modifiers & MODIFIER_SHADER) renderer->resetShader(); 626} 627 628static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject clazz, 629 jlong rendererPtr, jlong shaderPtr) { 630 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 631 SkiaShader* shader = reinterpret_cast<SkiaShader*>(shaderPtr); 632 renderer->setupShader(shader); 633} 634 635 636// ---------------------------------------------------------------------------- 637// Draw filters 638// ---------------------------------------------------------------------------- 639 640static void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz, 641 jlong rendererPtr, jint clearBits, jint setBits) { 642 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 643 renderer->setupPaintFilter(clearBits, setBits); 644} 645 646static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz, 647 jlong rendererPtr) { 648 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 649 renderer->resetPaintFilter(); 650} 651 652// ---------------------------------------------------------------------------- 653// Text 654// ---------------------------------------------------------------------------- 655 656static float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) { 657 switch (paint->getTextAlign()) { 658 case SkPaint::kCenter_Align: 659 return -totalAdvance / 2.0f; 660 break; 661 case SkPaint::kRight_Align: 662 return -totalAdvance; 663 break; 664 default: 665 break; 666 } 667 return 0; 668} 669 670#ifdef USE_MINIKIN 671static void renderTextLayout(OpenGLRenderer* renderer, Layout* layout, 672 jfloat x, jfloat y, SkPaint* paint) { 673 size_t nGlyphs = layout->nGlyphs(); 674 float* pos = new float[nGlyphs * 2]; 675 uint16_t* glyphs = new uint16_t[nGlyphs]; 676 SkTypeface* lastFace = 0; 677 SkTypeface* skFace = 0; 678 size_t start = 0; 679 MinikinRect b; 680 layout->getBounds(&b); 681 android::uirenderer::Rect bounds(b.mLeft, b.mTop, b.mRight, b.mBottom); 682 bounds.translate(x, y); 683 float totalAdvance = layout->getAdvance(); 684 685 for (size_t i = 0; i < nGlyphs; i++) { 686 MinikinFontSkia* mfs = static_cast<MinikinFontSkia *>(layout->getFont(i)); 687 skFace = mfs->GetSkTypeface(); 688 glyphs[i] = layout->getGlyphId(i); 689 pos[2 * i] = SkFloatToScalar(layout->getX(i)); 690 pos[2 * i + 1] = SkFloatToScalar(layout->getY(i)); 691 if (i > 0 && skFace != lastFace) { 692 paint->setTypeface(lastFace); 693 size_t glyphsCount = i - start; 694 int bytesCount = glyphsCount * sizeof(jchar); 695 renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount, 696 x, y, pos + 2 * start, paint, totalAdvance, bounds); 697 start = i; 698 } 699 lastFace = skFace; 700 } 701 if (skFace != NULL) { 702 paint->setTypeface(skFace); 703 size_t glyphsCount = nGlyphs - start; 704 int bytesCount = glyphsCount * sizeof(jchar); 705 renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount, 706 x, y, pos + 2 * start, paint, totalAdvance, bounds); 707 } 708 delete[] glyphs; 709 delete[] pos; 710} 711#endif 712 713static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, 714 jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) { 715#ifdef USE_MINIKIN 716 Layout layout; 717 MinikinUtils::SetLayoutProperties(&layout, paint, typeface); 718 layout.doLayout(text, count); 719 x += xOffsetForTextAlign(paint, layout.getAdvance()); 720 renderTextLayout(renderer, &layout, x, y, paint); 721#else 722 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, 723 text, 0, count, count, flags); 724 if (value == NULL) { 725 return; 726 } 727 const jchar* glyphs = value->getGlyphs(); 728 size_t glyphsCount = value->getGlyphsCount(); 729 jfloat totalAdvance = value->getTotalAdvance(); 730 x += xOffsetForTextAlign(paint, totalAdvance); 731 const float* positions = value->getPos(); 732 int bytesCount = glyphsCount * sizeof(jchar); 733 const SkRect& r = value->getBounds(); 734 android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom); 735 bounds.translate(x, y); 736 737 renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, 738 x, y, positions, paint, totalAdvance, bounds); 739#endif 740} 741 742static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count, 743 SkPath* path, jfloat hOffset, jfloat vOffset, int flags, SkPaint* paint) { 744 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, 745 text, 0, count, count, flags); 746 if (value == NULL) { 747 return; 748 } 749 const jchar* glyphs = value->getGlyphs(); 750 size_t glyphsCount = value->getGlyphsCount(); 751 int bytesCount = glyphsCount * sizeof(jchar); 752 renderer->drawTextOnPath((const char*) glyphs, bytesCount, glyphsCount, path, 753 hOffset, vOffset, paint); 754} 755 756static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, 757 jint start, jint count, jint contextCount, jfloat x, jfloat y, 758 int flags, SkPaint* paint, TypefaceImpl* typeface) { 759#ifdef USE_MINIKIN 760 Layout layout; 761 MinikinUtils::SetLayoutProperties(&layout, paint, typeface); 762 layout.doLayout(text + start, count); 763 x += xOffsetForTextAlign(paint, layout.getAdvance()); 764 renderTextLayout(renderer, &layout, x, y, paint); 765#else 766 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, 767 text, start, count, contextCount, flags); 768 if (value == NULL) { 769 return; 770 } 771 const jchar* glyphs = value->getGlyphs(); 772 size_t glyphsCount = value->getGlyphsCount(); 773 jfloat totalAdvance = value->getTotalAdvance(); 774 x += xOffsetForTextAlign(paint, totalAdvance); 775 const float* positions = value->getPos(); 776 int bytesCount = glyphsCount * sizeof(jchar); 777 const SkRect& r = value->getBounds(); 778 android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom); 779 bounds.translate(x, y); 780 781 renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, 782 x, y, positions, paint, totalAdvance, bounds); 783#endif 784} 785 786static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz, 787 jlong rendererPtr, jcharArray text, jint index, jint count, 788 jfloat x, jfloat y, jint flags, jlong paintPtr, jlong typefacePtr) { 789 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 790 jchar* textArray = env->GetCharArrayElements(text, NULL); 791 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 792 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 793 794 renderText(renderer, textArray + index, count, x, y, flags, paint, typeface); 795 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 796} 797 798static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz, 799 jlong rendererPtr, jstring text, jint start, jint end, 800 jfloat x, jfloat y, jint flags, jlong paintPtr, jlong typefacePtr) { 801 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 802 const jchar* textArray = env->GetStringChars(text, NULL); 803 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 804 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 805 806 renderText(renderer, textArray + start, end - start, x, y, flags, paint, typeface); 807 env->ReleaseStringChars(text, textArray); 808} 809 810static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz, 811 jlong rendererPtr, jcharArray text, jint index, jint count, 812 jlong pathPtr, jfloat hOffset, jfloat vOffset, jint flags, jlong paintPtr) { 813 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 814 jchar* textArray = env->GetCharArrayElements(text, NULL); 815 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 816 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 817 818 renderTextOnPath(renderer, textArray + index, count, path, 819 hOffset, vOffset, flags, paint); 820 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 821} 822 823static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz, 824 jlong rendererPtr, jstring text, jint start, jint end, 825 jlong pathPtr, jfloat hOffset, jfloat vOffset, jint flags, jlong paintPtr) { 826 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 827 const jchar* textArray = env->GetStringChars(text, NULL); 828 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 829 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 830 831 renderTextOnPath(renderer, textArray + start, end - start, path, 832 hOffset, vOffset, flags, paint); 833 env->ReleaseStringChars(text, textArray); 834} 835 836static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz, 837 jlong rendererPtr, jcharArray text, jint index, jint count, 838 jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags, 839 jlong paintPtr, jlong typefacePtr) { 840 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 841 jchar* textArray = env->GetCharArrayElements(text, NULL); 842 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 843 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 844 845 renderTextRun(renderer, textArray + contextIndex, index - contextIndex, 846 count, contextCount, x, y, dirFlags, paint, typeface); 847 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 848 } 849 850static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz, 851 jlong rendererPtr, jstring text, jint start, jint end, 852 jint contextStart, int contextEnd, jfloat x, jfloat y, jint dirFlags, 853 jlong paintPtr, jlong typefacePtr) { 854 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 855 const jchar* textArray = env->GetStringChars(text, NULL); 856 jint count = end - start; 857 jint contextCount = contextEnd - contextStart; 858 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 859 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 860 861 renderTextRun(renderer, textArray + contextStart, start - contextStart, 862 count, contextCount, x, y, dirFlags, paint, typeface); 863 env->ReleaseStringChars(text, textArray); 864} 865 866static void renderPosText(OpenGLRenderer* renderer, const jchar* text, int count, 867 const jfloat* positions, jint dirFlags, SkPaint* paint) { 868 sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, 869 text, 0, count, count, dirFlags); 870 if (value == NULL) { 871 return; 872 } 873 const jchar* glyphs = value->getGlyphs(); 874 size_t glyphsCount = value->getGlyphsCount(); 875 if (count < int(glyphsCount)) glyphsCount = count; 876 int bytesCount = glyphsCount * sizeof(jchar); 877 878 renderer->drawPosText((const char*) glyphs, bytesCount, glyphsCount, positions, paint); 879} 880 881static void android_view_GLES20Canvas_drawPosTextArray(JNIEnv* env, jobject clazz, 882 jlong rendererPtr, jcharArray text, jint index, jint count, 883 jfloatArray pos, jlong paintPtr) { 884 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 885 jchar* textArray = env->GetCharArrayElements(text, NULL); 886 jfloat* positions = env->GetFloatArrayElements(pos, NULL); 887 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 888 889 renderPosText(renderer, textArray + index, count, positions, kBidi_LTR, paint); 890 891 env->ReleaseFloatArrayElements(pos, positions, JNI_ABORT); 892 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 893} 894 895static void android_view_GLES20Canvas_drawPosText(JNIEnv* env, jobject clazz, 896 jlong rendererPtr, jstring text, jint start, jint end, 897 jfloatArray pos, jlong paintPtr) { 898 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 899 const jchar* textArray = env->GetStringChars(text, NULL); 900 jfloat* positions = env->GetFloatArrayElements(pos, NULL); 901 SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr); 902 903 renderPosText(renderer, textArray + start, end - start, positions, kBidi_LTR, paint); 904 905 env->ReleaseFloatArrayElements(pos, positions, JNI_ABORT); 906 env->ReleaseStringChars(text, textArray); 907} 908 909// ---------------------------------------------------------------------------- 910// Display lists 911// ---------------------------------------------------------------------------- 912 913static jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env, 914 jobject clazz, jlong rendererPtr) { 915 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 916 return reinterpret_cast<jlong>(renderer->finishRecording()); 917} 918 919static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env, jobject clazz) { 920 return reinterpret_cast<jlong>(new DisplayListRenderer); 921} 922 923static jint android_view_GLES20Canvas_drawDisplayList(JNIEnv* env, 924 jobject clazz, jlong rendererPtr, jlong displayListPtr, 925 jobject dirty, jint flags) { 926 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 927 RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); 928 android::uirenderer::Rect bounds; 929 status_t status = renderer->drawDisplayList(displayList, bounds, flags); 930 if (status != DrawGlInfo::kStatusDone && dirty != NULL) { 931 env->CallVoidMethod(dirty, gRectClassInfo.set, 932 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); 933 } 934 return status; 935} 936 937// ---------------------------------------------------------------------------- 938// Layers 939// ---------------------------------------------------------------------------- 940 941static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz, 942 jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) { 943 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 944 Layer* layer = reinterpret_cast<Layer*>(layerPtr); 945 renderer->drawLayer(layer, x, y); 946} 947 948static jboolean android_view_GLES20Canvas_copyLayer(JNIEnv* env, jobject clazz, 949 jlong layerPtr, jlong bitmapPtr) { 950 Layer* layer = reinterpret_cast<Layer*>(layerPtr); 951 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 952 return LayerRenderer::copyLayer(layer, bitmap); 953} 954 955static void android_view_GLES20Canvas_pushLayerUpdate(JNIEnv* env, jobject clazz, 956 jlong rendererPtr, jlong layerPtr) { 957 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 958 Layer* layer = reinterpret_cast<Layer*>(layerPtr); 959 renderer->pushLayerUpdate(layer); 960} 961 962static void android_view_GLES20Canvas_cancelLayerUpdate(JNIEnv* env, jobject clazz, 963 jlong rendererPtr, jlong layerPtr) { 964 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 965 Layer* layer = reinterpret_cast<Layer*>(layerPtr); 966 renderer->cancelLayerUpdate(layer); 967} 968 969static void android_view_GLES20Canvas_clearLayerUpdates(JNIEnv* env, jobject clazz, 970 jlong rendererPtr) { 971 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 972 renderer->clearLayerUpdates(); 973} 974 975static void android_view_GLES20Canvas_flushLayerUpdates(JNIEnv* env, jobject clazz, 976 jlong rendererPtr) { 977 OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr); 978 renderer->flushLayerUpdates(); 979} 980 981#endif // USE_OPENGL_RENDERER 982 983// ---------------------------------------------------------------------------- 984// Common 985// ---------------------------------------------------------------------------- 986 987static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz) { 988#ifdef USE_OPENGL_RENDERER 989 char prop[PROPERTY_VALUE_MAX]; 990 if (property_get("ro.kernel.qemu", prop, NULL) == 0) { 991 // not in the emulator 992 return JNI_TRUE; 993 } 994 // In the emulator this property will be set to 1 when hardware GLES is 995 // enabled, 0 otherwise. On old emulator versions it will be undefined. 996 property_get("ro.kernel.qemu.gles", prop, "0"); 997 return atoi(prop) == 1 ? JNI_TRUE : JNI_FALSE; 998#else 999 return JNI_FALSE; 1000#endif 1001} 1002 1003// ---------------------------------------------------------------------------- 1004// Logging 1005// ---------------------------------------------------------------------------- 1006 1007static void 1008android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) { 1009#ifdef USE_OPENGL_RENDERER 1010 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); 1011 android::uirenderer::RenderNode::outputLogBuffer(fd); 1012#endif // USE_OPENGL_RENDERER 1013} 1014 1015// ---------------------------------------------------------------------------- 1016// JNI Glue 1017// ---------------------------------------------------------------------------- 1018 1019const char* const kClassPathName = "android/view/GLES20Canvas"; 1020 1021static JNINativeMethod gMethods[] = { 1022 { "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable }, 1023 1024#ifdef USE_OPENGL_RENDERER 1025 { "nFlushCaches", "(I)V", (void*) android_view_GLES20Canvas_flushCaches }, 1026 { "nInitCaches", "()Z", (void*) android_view_GLES20Canvas_initCaches }, 1027 { "nTerminateCaches", "()V", (void*) android_view_GLES20Canvas_terminateCaches }, 1028 1029 { "nInitAtlas", "(Landroid/view/GraphicBuffer;[JI)V", 1030 (void*) android_view_GLES20Canvas_initAtlas }, 1031 1032 { "nCreateRenderer", "()J", (void*) android_view_GLES20Canvas_createRenderer }, 1033 { "nDestroyRenderer", "(J)V", (void*) android_view_GLES20Canvas_destroyRenderer }, 1034 { "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport }, 1035 { "nPrepare", "(JZ)I", (void*) android_view_GLES20Canvas_prepare }, 1036 { "nPrepareDirty", "(JIIIIZ)I", (void*) android_view_GLES20Canvas_prepareDirty }, 1037 { "nFinish", "(J)V", (void*) android_view_GLES20Canvas_finish }, 1038 { "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V", 1039 (void*) android_view_GLES20Canvas_setProperty }, 1040 1041 1042 { "nGetStencilSize", "()I", (void*) android_view_GLES20Canvas_getStencilSize }, 1043 1044 { "nCallDrawGLFunction", "(JJ)I", (void*) android_view_GLES20Canvas_callDrawGLFunction }, 1045 1046 { "nSave", "(JI)I", (void*) android_view_GLES20Canvas_save }, 1047 { "nRestore", "(J)V", (void*) android_view_GLES20Canvas_restore }, 1048 { "nRestoreToCount", "(JI)V", (void*) android_view_GLES20Canvas_restoreToCount }, 1049 { "nGetSaveCount", "(J)I", (void*) android_view_GLES20Canvas_getSaveCount }, 1050 1051 { "nSaveLayer", "(JFFFFJI)I", (void*) android_view_GLES20Canvas_saveLayer }, 1052 { "nSaveLayer", "(JJI)I", (void*) android_view_GLES20Canvas_saveLayerClip }, 1053 { "nSaveLayerAlpha", "(JFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha }, 1054 { "nSaveLayerAlpha", "(JII)I", (void*) android_view_GLES20Canvas_saveLayerAlphaClip }, 1055 1056 { "nQuickReject", "(JFFFF)Z", (void*) android_view_GLES20Canvas_quickReject }, 1057 { "nClipRect", "(JFFFFI)Z", (void*) android_view_GLES20Canvas_clipRectF }, 1058 { "nClipRect", "(JIIIII)Z", (void*) android_view_GLES20Canvas_clipRect }, 1059 { "nClipPath", "(JJI)Z", (void*) android_view_GLES20Canvas_clipPath }, 1060 { "nClipRegion", "(JJI)Z", (void*) android_view_GLES20Canvas_clipRegion }, 1061 1062 { "nTranslate", "(JFF)V", (void*) android_view_GLES20Canvas_translate }, 1063 { "nRotate", "(JF)V", (void*) android_view_GLES20Canvas_rotate }, 1064 { "nScale", "(JFF)V", (void*) android_view_GLES20Canvas_scale }, 1065 { "nSkew", "(JFF)V", (void*) android_view_GLES20Canvas_skew }, 1066 1067 { "nSetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_setMatrix }, 1068 { "nGetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_getMatrix }, 1069 { "nConcatMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_concatMatrix }, 1070 1071 { "nDrawBitmap", "(JJ[BFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap }, 1072 { "nDrawBitmap", "(JJ[BFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect }, 1073 { "nDrawBitmap", "(JJ[BJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, 1074 { "nDrawBitmap", "(J[IIIFFIIZJ)V", (void*) android_view_GLES20Canvas_drawBitmapData }, 1075 1076 { "nDrawBitmapMesh", "(JJ[BII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh }, 1077 1078 { "nDrawPatch", "(JJ[BJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch }, 1079 1080 { "nDrawColor", "(JII)V", (void*) android_view_GLES20Canvas_drawColor }, 1081 { "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect }, 1082 { "nDrawRects", "(JJJ)V", (void*) android_view_GLES20Canvas_drawRegionAsRects }, 1083 { "nDrawRects", "(J[FIJ)V", (void*) android_view_GLES20Canvas_drawRects }, 1084 { "nDrawRoundRect", "(JFFFFFFJ)V", (void*) android_view_GLES20Canvas_drawRoundRect }, 1085 { "nDrawCircle", "(JFFFJ)V", (void*) android_view_GLES20Canvas_drawCircle }, 1086 { "nDrawCircle", "(JJJJJ)V", (void*) android_view_GLES20Canvas_drawCircleProps }, 1087 { "nDrawOval", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawOval }, 1088 { "nDrawArc", "(JFFFFFFZJ)V", (void*) android_view_GLES20Canvas_drawArc }, 1089 { "nDrawPoints", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawPoints }, 1090 1091 { "nDrawPath", "(JJJ)V", (void*) android_view_GLES20Canvas_drawPath }, 1092 { "nDrawLines", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawLines }, 1093 1094 { "nResetModifiers", "(JI)V", (void*) android_view_GLES20Canvas_resetModifiers }, 1095 { "nSetupShader", "(JJ)V", (void*) android_view_GLES20Canvas_setupShader }, 1096 1097 { "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter }, 1098 { "nResetPaintFilter", "(J)V", (void*) android_view_GLES20Canvas_resetPaintFilter }, 1099 1100 { "nDrawText", "(J[CIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArray }, 1101 { "nDrawText", "(JLjava/lang/String;IIFFIJJ)V", 1102 (void*) android_view_GLES20Canvas_drawText }, 1103 1104 { "nDrawTextOnPath", "(J[CIIJFFIJ)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath }, 1105 { "nDrawTextOnPath", "(JLjava/lang/String;IIJFFIJ)V", 1106 (void*) android_view_GLES20Canvas_drawTextOnPath }, 1107 1108 { "nDrawTextRun", "(J[CIIIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray }, 1109 { "nDrawTextRun", "(JLjava/lang/String;IIIIFFIJJ)V", 1110 (void*) android_view_GLES20Canvas_drawTextRun }, 1111 1112 { "nDrawPosText", "(J[CII[FJ)V", (void*) android_view_GLES20Canvas_drawPosTextArray }, 1113 { "nDrawPosText", "(JLjava/lang/String;II[FJ)V", 1114 (void*) android_view_GLES20Canvas_drawPosText }, 1115 1116 { "nGetClipBounds", "(JLandroid/graphics/Rect;)Z", 1117 (void*) android_view_GLES20Canvas_getClipBounds }, 1118 1119 { "nFinishRecording", "(J)J", (void*) android_view_GLES20Canvas_finishRecording }, 1120 { "nDrawDisplayList", "(JJLandroid/graphics/Rect;I)I", 1121 (void*) android_view_GLES20Canvas_drawDisplayList }, 1122 1123 { "nCreateDisplayListRenderer", "()J", (void*) android_view_GLES20Canvas_createDisplayListRenderer }, 1124 1125 { "nDrawLayer", "(JJFF)V", (void*) android_view_GLES20Canvas_drawLayer }, 1126 { "nCopyLayer", "(JJ)Z", (void*) android_view_GLES20Canvas_copyLayer }, 1127 { "nClearLayerUpdates", "(J)V", (void*) android_view_GLES20Canvas_clearLayerUpdates }, 1128 { "nFlushLayerUpdates", "(J)V", (void*) android_view_GLES20Canvas_flushLayerUpdates }, 1129 { "nPushLayerUpdate", "(JJ)V", (void*) android_view_GLES20Canvas_pushLayerUpdate }, 1130 { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_GLES20Canvas_cancelLayerUpdate }, 1131 1132 { "nGetMaximumTextureWidth", "()I", (void*) android_view_GLES20Canvas_getMaxTextureWidth }, 1133 { "nGetMaximumTextureHeight", "()I", (void*) android_view_GLES20Canvas_getMaxTextureHeight }, 1134 1135#endif 1136}; 1137 1138static JNINativeMethod gActivityThreadMethods[] = { 1139 { "dumpGraphicsInfo", "(Ljava/io/FileDescriptor;)V", 1140 (void*) android_app_ActivityThread_dumpGraphics } 1141}; 1142 1143 1144#ifdef USE_OPENGL_RENDERER 1145 #define FIND_CLASS(var, className) \ 1146 var = env->FindClass(className); \ 1147 LOG_FATAL_IF(! var, "Unable to find class " className); 1148 1149 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 1150 var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 1151 LOG_FATAL_IF(! var, "Unable to find method " methodName); 1152#else 1153 #define FIND_CLASS(var, className) 1154 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) 1155#endif 1156 1157int register_android_view_GLES20Canvas(JNIEnv* env) { 1158 jclass clazz; 1159 FIND_CLASS(clazz, "android/graphics/Rect"); 1160 GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V"); 1161 1162 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 1163} 1164 1165const char* const kActivityThreadPathName = "android/app/ActivityThread"; 1166 1167int register_android_app_ActivityThread(JNIEnv* env) { 1168 return AndroidRuntime::registerNativeMethods(env, kActivityThreadPathName, 1169 gActivityThreadMethods, NELEM(gActivityThreadMethods)); 1170} 1171 1172}; 1173