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