android_view_GLES20Canvas.cpp revision e21e2a2d1d85d422230c1115abba824338763a88
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "OpenGLRenderer" 18 19#include "jni.h" 20#include "GraphicsJNI.h" 21#include <nativehelper/JNIHelp.h> 22 23#include <android_runtime/AndroidRuntime.h> 24 25#include <androidfw/ResourceTypes.h> 26 27#include <private/hwui/DrawGlInfo.h> 28 29#include <cutils/properties.h> 30 31#include <SkBitmap.h> 32#include <SkCanvas.h> 33#include <SkImageInfo.h> 34#include <SkMatrix.h> 35#include <SkPorterDuff.h> 36#include <SkRegion.h> 37#include <SkScalerContext.h> 38#include <SkTemplates.h> 39#include <SkXfermode.h> 40 41#include <DisplayListRenderer.h> 42#include <Rect.h> 43#include <RenderNode.h> 44#include <CanvasProperty.h> 45#include <Paint.h> 46 47#include "MinikinUtils.h" 48 49namespace android { 50 51using namespace uirenderer; 52 53/** 54 * Note: DisplayListRenderer JNI layer is generated and compiled only on supported 55 * devices. This means all the logic must be compiled only when the 56 * preprocessor variable USE_OPENGL_RENDERER is defined. 57 */ 58#ifdef USE_OPENGL_RENDERER 59 60// ---------------------------------------------------------------------------- 61// Defines 62// ---------------------------------------------------------------------------- 63 64// Debug 65#define DEBUG_RENDERER 0 66 67// Debug 68#if DEBUG_RENDERER 69 #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__) 70#else 71 #define RENDERER_LOGD(...) 72#endif 73 74// ---------------------------------------------------------------------------- 75 76static struct { 77 jmethodID set; 78} gRectClassInfo; 79 80// ---------------------------------------------------------------------------- 81// Constructors 82// ---------------------------------------------------------------------------- 83 84static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz, 85 jlong rendererPtr) { 86 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 87 RENDERER_LOGD("Destroy DisplayListRenderer"); 88 delete renderer; 89} 90 91// ---------------------------------------------------------------------------- 92// Setup 93// ---------------------------------------------------------------------------- 94 95static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz, 96 jlong rendererPtr, jint width, jint height) { 97 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 98 renderer->setViewport(width, height); 99} 100 101static void android_view_GLES20Canvas_setHighContrastText(JNIEnv* env, jobject clazz, 102 jlong rendererPtr, jboolean highContrastText) { 103 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 104 renderer->setHighContrastText(highContrastText); 105} 106 107static int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz, 108 jlong rendererPtr, jboolean opaque) { 109 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 110 return renderer->prepare(opaque); 111} 112 113static int android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz, 114 jlong rendererPtr, jint left, jint top, jint right, jint bottom, 115 jboolean opaque) { 116 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 117 return renderer->prepareDirty(left, top, right, bottom, opaque); 118} 119 120static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz, 121 jlong rendererPtr) { 122 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 123 renderer->finish(); 124} 125 126static void android_view_GLES20Canvas_setProperty(JNIEnv* env, 127 jobject clazz, jstring name, jstring value) { 128 if (!Caches::hasInstance()) { 129 ALOGW("can't set property, no Caches instance"); 130 return; 131 } 132 133 if (name == NULL || value == NULL) { 134 ALOGW("can't set prop, null passed"); 135 } 136 137 const char* nameCharArray = env->GetStringUTFChars(name, NULL); 138 const char* valueCharArray = env->GetStringUTFChars(value, NULL); 139 Caches::getInstance().setTempProperty(nameCharArray, valueCharArray); 140 env->ReleaseStringUTFChars(name, nameCharArray); 141 env->ReleaseStringUTFChars(name, valueCharArray); 142} 143 144// ---------------------------------------------------------------------------- 145// Functor 146// ---------------------------------------------------------------------------- 147 148static jint android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz, 149 jlong rendererPtr, jlong functorPtr) { 150 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 151 Functor* functor = reinterpret_cast<Functor*>(functorPtr); 152 android::uirenderer::Rect dirty; 153 return renderer->callDrawGLFunction(functor, dirty); 154} 155 156// ---------------------------------------------------------------------------- 157// Misc 158// ---------------------------------------------------------------------------- 159 160static jint android_view_GLES20Canvas_getMaxTextureWidth(JNIEnv* env, jobject clazz) { 161 return Caches::getInstance().maxTextureSize; 162} 163 164static jint android_view_GLES20Canvas_getMaxTextureHeight(JNIEnv* env, jobject clazz) { 165 return Caches::getInstance().maxTextureSize; 166} 167 168// ---------------------------------------------------------------------------- 169// State 170// ---------------------------------------------------------------------------- 171 172static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, jlong rendererPtr, 173 jint flags) { 174 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 175 return renderer->save(flags); 176} 177 178static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz, 179 jlong rendererPtr) { 180 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 181 return renderer->getSaveCount(); 182} 183 184static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz, 185 jlong rendererPtr) { 186 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 187 renderer->restore(); 188} 189 190static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz, 191 jlong rendererPtr, jint saveCount) { 192 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 193 renderer->restoreToCount(saveCount); 194} 195 196// ---------------------------------------------------------------------------- 197// Layers 198// ---------------------------------------------------------------------------- 199 200static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz, 201 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 202 jlong paintPtr, jint saveFlags) { 203 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 204 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 205 return renderer->saveLayer(left, top, right, bottom, paint, saveFlags); 206} 207 208static jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz, 209 jlong rendererPtr, jlong paintPtr, jint saveFlags) { 210 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 211 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 212 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds()); 213 return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, 214 paint, saveFlags); 215} 216 217static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz, 218 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 219 jint alpha, jint saveFlags) { 220 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 221 return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags); 222} 223 224static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz, 225 jlong rendererPtr, jint alpha, jint saveFlags) { 226 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 227 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds()); 228 return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, 229 alpha, saveFlags); 230} 231 232// ---------------------------------------------------------------------------- 233// Clipping 234// ---------------------------------------------------------------------------- 235 236static jboolean android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz, 237 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom) { 238 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 239 const bool result = renderer->quickRejectConservative(left, top, right, bottom); 240 return result ? JNI_TRUE : JNI_FALSE; 241} 242 243static jboolean android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz, 244 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 245 jint op) { 246 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 247 const bool result = renderer->clipRect(left, top, right, bottom, 248 static_cast<SkRegion::Op>(op)); 249 return result ? JNI_TRUE : JNI_FALSE; 250} 251 252static jboolean android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz, 253 jlong rendererPtr, jint left, jint top, jint right, jint bottom, 254 jint op) { 255 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 256 const bool result = renderer->clipRect(float(left), float(top), float(right), 257 float(bottom), 258 static_cast<SkRegion::Op>(op)); 259 return result ? JNI_TRUE : JNI_FALSE; 260} 261 262static jboolean android_view_GLES20Canvas_clipPath(JNIEnv* env, jobject clazz, 263 jlong rendererPtr, jlong pathPtr, jint op) { 264 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 265 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 266 const bool result = renderer->clipPath(path, static_cast<SkRegion::Op>(op)); 267 return result ? JNI_TRUE : JNI_FALSE; 268} 269 270static jboolean android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz, 271 jlong rendererPtr, jlong regionPtr, jint op) { 272 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 273 SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr); 274 const bool result = renderer->clipRegion(region, static_cast<SkRegion::Op>(op)); 275 return result ? JNI_TRUE : JNI_FALSE; 276} 277 278static jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz, 279 jlong rendererPtr, jobject rect) { 280 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 281 const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds()); 282 283 env->CallVoidMethod(rect, gRectClassInfo.set, 284 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); 285 286 return !bounds.isEmpty() ? JNI_TRUE : JNI_FALSE; 287} 288 289// ---------------------------------------------------------------------------- 290// Transforms 291// ---------------------------------------------------------------------------- 292 293static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz, 294 jlong rendererPtr, jfloat dx, jfloat dy) { 295 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 296 renderer->translate(dx, dy); 297} 298 299static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz, 300 jlong rendererPtr, jfloat degrees) { 301 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 302 renderer->rotate(degrees); 303} 304 305static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz, 306 jlong rendererPtr, jfloat sx, jfloat sy) { 307 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 308 renderer->scale(sx, sy); 309} 310 311static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz, 312 jlong rendererPtr, jfloat sx, jfloat sy) { 313 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 314 renderer->skew(sx, sy); 315} 316 317static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz, 318 jlong rendererPtr, jlong matrixPtr) { 319 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 320 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 321 renderer->setMatrix(matrix ? *matrix : SkMatrix::I()); 322} 323 324static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz, 325 jlong rendererPtr, jlong matrixPtr) { 326 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 327 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 328 renderer->getMatrix(matrix); 329} 330 331static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz, 332 jlong rendererPtr, jlong matrixPtr) { 333 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 334 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 335 renderer->concatMatrix(*matrix); 336} 337 338// ---------------------------------------------------------------------------- 339// Drawing 340// ---------------------------------------------------------------------------- 341 342static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz, 343 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 344 jfloat left, jfloat top, jlong paintPtr) { 345 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 346 // This object allows the renderer to allocate a global JNI ref to the buffer object. 347 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 348 349 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 350 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 351 renderer->drawBitmap(bitmap, left, top, paint); 352} 353 354static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, 355 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 356 float srcLeft, float srcTop, float srcRight, float srcBottom, 357 float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) { 358 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 359 // This object allows the renderer to allocate a global JNI ref to the buffer object. 360 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 361 362 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 363 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 364 renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, 365 dstLeft, dstTop, dstRight, dstBottom, paint); 366} 367 368static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz, 369 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 370 jlong matrixPtr, jlong paintPtr) { 371 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 372 // This object allows the renderer to allocate a global JNI ref to the buffer object. 373 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 374 375 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 376 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 377 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 378 renderer->drawBitmap(bitmap, *matrix, paint); 379} 380 381static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz, 382 jlong rendererPtr, jintArray colors, jint offset, jint stride, 383 jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) { 384 // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will 385 // correct the alphaType to kOpaque_SkAlphaType. 386 const SkImageInfo info = SkImageInfo::Make(width, height, 387 hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType, 388 kPremul_SkAlphaType); 389 SkBitmap* bitmap = new SkBitmap; 390 if (!bitmap->allocPixels(info)) { 391 delete bitmap; 392 return; 393 } 394 395 if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap)) { 396 delete bitmap; 397 return; 398 } 399 400 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 401 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 402 renderer->drawBitmapData(bitmap, left, top, paint); 403 404 // Note - bitmap isn't deleted as DisplayListRenderer owns it now 405} 406 407static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, 408 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 409 jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors, 410 jint colorOffset, jlong paintPtr) { 411 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 412 // This object allows the renderer to allocate a global JNI ref to the buffer object. 413 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 414 415 jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL; 416 jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL; 417 418 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 419 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 420 renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint); 421 422 if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0); 423 if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0); 424} 425 426static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, 427 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr, 428 float left, float top, float right, float bottom, 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 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 434 Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr); 435 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 436 renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint); 437} 438 439static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz, 440 jlong rendererPtr, jint color, jint modeHandle) { 441 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 442 SkPorterDuff::Mode mode = static_cast<SkPorterDuff::Mode>(modeHandle); 443 renderer->drawColor(color, SkPorterDuff::ToXfermodeMode(mode)); 444} 445 446static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz, 447 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 448 jlong paintPtr) { 449 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 450 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 451 renderer->drawRect(left, top, right, bottom, paint); 452} 453 454static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz, 455 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 456 jfloat rx, jfloat ry, jlong paintPtr) { 457 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 458 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 459 renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint); 460} 461 462static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz, 463 jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) { 464 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 465 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 466 renderer->drawCircle(x, y, radius, paint); 467} 468 469static void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz, 470 jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) { 471 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 472 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr); 473 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr); 474 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr); 475 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr); 476 renderer->drawCircle(xProp, yProp, radiusProp, paintProp); 477} 478 479static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz, 480 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 481 jlong paintPtr) { 482 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 483 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 484 renderer->drawOval(left, top, right, bottom, paint); 485} 486 487static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz, 488 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 489 jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) { 490 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 491 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 492 renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint); 493} 494 495static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz, 496 jlong rendererPtr, jlong regionPtr, jlong paintPtr) { 497 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 498 SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr); 499 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 500 if (paint->getStyle() != Paint::kFill_Style || 501 (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) { 502 SkRegion::Iterator it(*region); 503 while (!it.done()) { 504 const SkIRect& r = it.rect(); 505 renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint); 506 it.next(); 507 } 508 } else { 509 int count = 0; 510 Vector<float> rects; 511 SkRegion::Iterator it(*region); 512 while (!it.done()) { 513 const SkIRect& r = it.rect(); 514 rects.push(r.fLeft); 515 rects.push(r.fTop); 516 rects.push(r.fRight); 517 rects.push(r.fBottom); 518 count += 4; 519 it.next(); 520 } 521 renderer->drawRects(rects.array(), count, paint); 522 } 523} 524 525static void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz, 526 jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) { 527 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 528 jfloat* storage = env->GetFloatArrayElements(points, NULL); 529 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 530 renderer->drawPoints(storage + offset, count, paint); 531 env->ReleaseFloatArrayElements(points, storage, 0); 532} 533 534static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz, 535 jlong rendererPtr, jlong pathPtr, jlong paintPtr) { 536 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 537 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 538 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 539 renderer->drawPath(path, paint); 540} 541 542static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz, 543 jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) { 544 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 545 jfloat* storage = env->GetFloatArrayElements(points, NULL); 546 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 547 renderer->drawLines(storage + offset, count, paint); 548 env->ReleaseFloatArrayElements(points, storage, 0); 549} 550 551// ---------------------------------------------------------------------------- 552// Draw filters 553// ---------------------------------------------------------------------------- 554 555static void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz, 556 jlong rendererPtr, jint clearBits, jint setBits) { 557 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 558 renderer->setupPaintFilter(clearBits, setBits); 559} 560 561static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz, 562 jlong rendererPtr) { 563 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 564 renderer->resetPaintFilter(); 565} 566 567// ---------------------------------------------------------------------------- 568// Text 569// ---------------------------------------------------------------------------- 570 571class RenderTextFunctor { 572public: 573 RenderTextFunctor(const Layout& layout, DisplayListRenderer* renderer, jfloat x, jfloat y, 574 Paint* paint, uint16_t* glyphs, float* pos, float totalAdvance, 575 uirenderer::Rect& bounds) 576 : layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs), 577 pos(pos), totalAdvance(totalAdvance), bounds(bounds) { } 578 void operator()(size_t start, size_t end) { 579 for (size_t i = start; i < end; i++) { 580 glyphs[i] = layout.getGlyphId(i); 581 pos[2 * i] = layout.getX(i); 582 pos[2 * i + 1] = layout.getY(i); 583 } 584 size_t glyphsCount = end - start; 585 int bytesCount = glyphsCount * sizeof(jchar); 586 renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount, 587 x, y, pos + 2 * start, paint, totalAdvance, bounds); 588 } 589private: 590 const Layout& layout; 591 DisplayListRenderer* renderer; 592 jfloat x; 593 jfloat y; 594 Paint* paint; 595 uint16_t* glyphs; 596 float* pos; 597 float totalAdvance; 598 uirenderer::Rect& bounds; 599}; 600 601static void renderTextLayout(DisplayListRenderer* renderer, Layout* layout, 602 jfloat x, jfloat y, Paint* paint) { 603 size_t nGlyphs = layout->nGlyphs(); 604 float* pos = new float[nGlyphs * 2]; 605 uint16_t* glyphs = new uint16_t[nGlyphs]; 606 MinikinRect b; 607 layout->getBounds(&b); 608 android::uirenderer::Rect bounds(b.mLeft, b.mTop, b.mRight, b.mBottom); 609 bounds.translate(x, y); 610 float totalAdvance = layout->getAdvance(); 611 612 RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds); 613 MinikinUtils::forFontRun(*layout, paint, f); 614 delete[] glyphs; 615 delete[] pos; 616} 617 618static void renderText(DisplayListRenderer* renderer, const jchar* text, int count, 619 jfloat x, jfloat y, int bidiFlags, Paint* paint, TypefaceImpl* typeface) { 620 Layout layout; 621 MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count); 622 x += MinikinUtils::xOffsetForTextAlign(paint, layout); 623 renderTextLayout(renderer, &layout, x, y, paint); 624} 625 626class RenderTextOnPathFunctor { 627public: 628 RenderTextOnPathFunctor(const Layout& layout, DisplayListRenderer* renderer, float hOffset, 629 float vOffset, Paint* paint, SkPath* path) 630 : layout(layout), renderer(renderer), hOffset(hOffset), vOffset(vOffset), 631 paint(paint), path(path) { 632 } 633 void operator()(size_t start, size_t end) { 634 uint16_t glyphs[1]; 635 for (size_t i = start; i < end; i++) { 636 glyphs[0] = layout.getGlyphId(i); 637 float x = hOffset + layout.getX(i); 638 float y = vOffset + layout.getY(i); 639 renderer->drawTextOnPath((const char*) glyphs, sizeof(glyphs), 1, path, x, y, paint); 640 } 641 } 642private: 643 const Layout& layout; 644 DisplayListRenderer* renderer; 645 float hOffset; 646 float vOffset; 647 Paint* paint; 648 SkPath* path; 649}; 650 651static void renderTextOnPath(DisplayListRenderer* renderer, const jchar* text, int count, 652 SkPath* path, jfloat hOffset, jfloat vOffset, int bidiFlags, Paint* paint, 653 TypefaceImpl* typeface) { 654 Layout layout; 655 MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count); 656 hOffset += MinikinUtils::hOffsetForTextAlign(paint, layout, *path); 657 Paint::Align align = paint->getTextAlign(); 658 paint->setTextAlign(Paint::kLeft_Align); 659 660 RenderTextOnPathFunctor f(layout, renderer, hOffset, vOffset, paint, path); 661 MinikinUtils::forFontRun(layout, paint, f); 662 paint->setTextAlign(align); 663} 664 665static void renderTextRun(DisplayListRenderer* renderer, const jchar* text, 666 jint start, jint count, jint contextCount, jfloat x, jfloat y, 667 int bidiFlags, Paint* paint, TypefaceImpl* typeface) { 668 Layout layout; 669 MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, contextCount); 670 x += MinikinUtils::xOffsetForTextAlign(paint, layout); 671 renderTextLayout(renderer, &layout, x, y, paint); 672} 673 674static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz, 675 jlong rendererPtr, jcharArray text, jint index, jint count, 676 jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) { 677 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 678 jchar* textArray = env->GetCharArrayElements(text, NULL); 679 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 680 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 681 682 renderText(renderer, textArray + index, count, x, y, bidiFlags, paint, typeface); 683 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 684} 685 686static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz, 687 jlong rendererPtr, jstring text, jint start, jint end, 688 jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) { 689 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 690 const jchar* textArray = env->GetStringChars(text, NULL); 691 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 692 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 693 694 renderText(renderer, textArray + start, end - start, x, y, bidiFlags, paint, typeface); 695 env->ReleaseStringChars(text, textArray); 696} 697 698static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz, 699 jlong rendererPtr, jcharArray text, jint index, jint count, 700 jlong pathPtr, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintPtr, 701 jlong typefacePtr) { 702 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 703 jchar* textArray = env->GetCharArrayElements(text, NULL); 704 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 705 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 706 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 707 708 renderTextOnPath(renderer, textArray + index, count, path, 709 hOffset, vOffset, bidiFlags, paint, typeface); 710 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 711} 712 713static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz, 714 jlong rendererPtr, jstring text, jint start, jint end, 715 jlong pathPtr, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintPtr, 716 jlong typefacePtr) { 717 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 718 const jchar* textArray = env->GetStringChars(text, NULL); 719 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 720 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 721 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 722 723 renderTextOnPath(renderer, textArray + start, end - start, path, 724 hOffset, vOffset, bidiFlags, paint, typeface); 725 env->ReleaseStringChars(text, textArray); 726} 727 728static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz, 729 jlong rendererPtr, jcharArray text, jint index, jint count, 730 jint contextIndex, jint contextCount, jfloat x, jfloat y, jboolean isRtl, 731 jlong paintPtr, jlong typefacePtr) { 732 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 733 jchar* textArray = env->GetCharArrayElements(text, NULL); 734 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 735 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 736 737 int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; 738 renderTextRun(renderer, textArray + contextIndex, index - contextIndex, 739 count, contextCount, x, y, bidiFlags, paint, typeface); 740 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 741 } 742 743static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz, 744 jlong rendererPtr, jstring text, jint start, jint end, 745 jint contextStart, int contextEnd, jfloat x, jfloat y, jboolean isRtl, 746 jlong paintPtr, jlong typefacePtr) { 747 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 748 const jchar* textArray = env->GetStringChars(text, NULL); 749 jint count = end - start; 750 jint contextCount = contextEnd - contextStart; 751 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 752 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 753 754 int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; 755 renderTextRun(renderer, textArray + contextStart, start - contextStart, 756 count, contextCount, x, y, bidiFlags, paint, typeface); 757 env->ReleaseStringChars(text, textArray); 758} 759 760// ---------------------------------------------------------------------------- 761// Display lists 762// ---------------------------------------------------------------------------- 763 764static jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env, 765 jobject clazz, jlong rendererPtr) { 766 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 767 return reinterpret_cast<jlong>(renderer->finishRecording()); 768} 769 770static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env, jobject clazz) { 771 return reinterpret_cast<jlong>(new DisplayListRenderer); 772} 773 774static jint android_view_GLES20Canvas_drawRenderNode(JNIEnv* env, 775 jobject clazz, jlong rendererPtr, jlong renderNodePtr, 776 jobject dirty, jint flags) { 777 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 778 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); 779 android::uirenderer::Rect bounds; 780 status_t status = renderer->drawRenderNode(renderNode, bounds, flags); 781 if (status != DrawGlInfo::kStatusDone && dirty != NULL) { 782 env->CallVoidMethod(dirty, gRectClassInfo.set, 783 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); 784 } 785 return status; 786} 787 788// ---------------------------------------------------------------------------- 789// Layers 790// ---------------------------------------------------------------------------- 791 792static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz, 793 jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) { 794 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 795 Layer* layer = reinterpret_cast<Layer*>(layerPtr); 796 renderer->drawLayer(layer, x, y); 797} 798 799#endif // USE_OPENGL_RENDERER 800 801// ---------------------------------------------------------------------------- 802// Common 803// ---------------------------------------------------------------------------- 804 805static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz) { 806#ifdef USE_OPENGL_RENDERER 807 char prop[PROPERTY_VALUE_MAX]; 808 if (property_get("ro.kernel.qemu", prop, NULL) == 0) { 809 // not in the emulator 810 return JNI_TRUE; 811 } 812 // In the emulator this property will be set to 1 when hardware GLES is 813 // enabled, 0 otherwise. On old emulator versions it will be undefined. 814 property_get("ro.kernel.qemu.gles", prop, "0"); 815 return atoi(prop) == 1 ? JNI_TRUE : JNI_FALSE; 816#else 817 return JNI_FALSE; 818#endif 819} 820 821// ---------------------------------------------------------------------------- 822// Logging 823// ---------------------------------------------------------------------------- 824 825static void 826android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) { 827#ifdef USE_OPENGL_RENDERER 828 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); 829 android::uirenderer::RenderNode::outputLogBuffer(fd); 830#endif // USE_OPENGL_RENDERER 831} 832 833// ---------------------------------------------------------------------------- 834// JNI Glue 835// ---------------------------------------------------------------------------- 836 837const char* const kClassPathName = "android/view/GLES20Canvas"; 838 839static JNINativeMethod gMethods[] = { 840 { "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable }, 841 842#ifdef USE_OPENGL_RENDERER 843 844 { "nDestroyRenderer", "(J)V", (void*) android_view_GLES20Canvas_destroyRenderer }, 845 { "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport }, 846 { "nSetHighContrastText","(JZ)V", (void*) android_view_GLES20Canvas_setHighContrastText }, 847 { "nPrepare", "(JZ)I", (void*) android_view_GLES20Canvas_prepare }, 848 { "nPrepareDirty", "(JIIIIZ)I", (void*) android_view_GLES20Canvas_prepareDirty }, 849 { "nFinish", "(J)V", (void*) android_view_GLES20Canvas_finish }, 850 { "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V", 851 (void*) android_view_GLES20Canvas_setProperty }, 852 853 { "nCallDrawGLFunction", "(JJ)I", (void*) android_view_GLES20Canvas_callDrawGLFunction }, 854 855 { "nSave", "(JI)I", (void*) android_view_GLES20Canvas_save }, 856 { "nRestore", "(J)V", (void*) android_view_GLES20Canvas_restore }, 857 { "nRestoreToCount", "(JI)V", (void*) android_view_GLES20Canvas_restoreToCount }, 858 { "nGetSaveCount", "(J)I", (void*) android_view_GLES20Canvas_getSaveCount }, 859 860 { "nSaveLayer", "(JFFFFJI)I", (void*) android_view_GLES20Canvas_saveLayer }, 861 { "nSaveLayer", "(JJI)I", (void*) android_view_GLES20Canvas_saveLayerClip }, 862 { "nSaveLayerAlpha", "(JFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha }, 863 { "nSaveLayerAlpha", "(JII)I", (void*) android_view_GLES20Canvas_saveLayerAlphaClip }, 864 865 { "nQuickReject", "(JFFFF)Z", (void*) android_view_GLES20Canvas_quickReject }, 866 { "nClipRect", "(JFFFFI)Z", (void*) android_view_GLES20Canvas_clipRectF }, 867 { "nClipRect", "(JIIIII)Z", (void*) android_view_GLES20Canvas_clipRect }, 868 { "nClipPath", "(JJI)Z", (void*) android_view_GLES20Canvas_clipPath }, 869 { "nClipRegion", "(JJI)Z", (void*) android_view_GLES20Canvas_clipRegion }, 870 871 { "nTranslate", "(JFF)V", (void*) android_view_GLES20Canvas_translate }, 872 { "nRotate", "(JF)V", (void*) android_view_GLES20Canvas_rotate }, 873 { "nScale", "(JFF)V", (void*) android_view_GLES20Canvas_scale }, 874 { "nSkew", "(JFF)V", (void*) android_view_GLES20Canvas_skew }, 875 876 { "nSetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_setMatrix }, 877 { "nGetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_getMatrix }, 878 { "nConcatMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_concatMatrix }, 879 880 { "nDrawBitmap", "(JJ[BFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap }, 881 { "nDrawBitmap", "(JJ[BFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect }, 882 { "nDrawBitmap", "(JJ[BJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, 883 { "nDrawBitmap", "(J[IIIFFIIZJ)V", (void*) android_view_GLES20Canvas_drawBitmapData }, 884 885 { "nDrawBitmapMesh", "(JJ[BII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh }, 886 887 { "nDrawPatch", "(JJ[BJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch }, 888 889 { "nDrawColor", "(JII)V", (void*) android_view_GLES20Canvas_drawColor }, 890 { "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect }, 891 { "nDrawRects", "(JJJ)V", (void*) android_view_GLES20Canvas_drawRegionAsRects }, 892 { "nDrawRoundRect", "(JFFFFFFJ)V", (void*) android_view_GLES20Canvas_drawRoundRect }, 893 { "nDrawCircle", "(JFFFJ)V", (void*) android_view_GLES20Canvas_drawCircle }, 894 { "nDrawCircle", "(JJJJJ)V", (void*) android_view_GLES20Canvas_drawCircleProps }, 895 { "nDrawOval", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawOval }, 896 { "nDrawArc", "(JFFFFFFZJ)V", (void*) android_view_GLES20Canvas_drawArc }, 897 { "nDrawPoints", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawPoints }, 898 899 { "nDrawPath", "(JJJ)V", (void*) android_view_GLES20Canvas_drawPath }, 900 { "nDrawLines", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawLines }, 901 902 { "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter }, 903 { "nResetPaintFilter", "(J)V", (void*) android_view_GLES20Canvas_resetPaintFilter }, 904 905 { "nDrawText", "(J[CIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArray }, 906 { "nDrawText", "(JLjava/lang/String;IIFFIJJ)V", 907 (void*) android_view_GLES20Canvas_drawText }, 908 909 { "nDrawTextOnPath", "(J[CIIJFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath }, 910 { "nDrawTextOnPath", "(JLjava/lang/String;IIJFFIJJ)V", 911 (void*) android_view_GLES20Canvas_drawTextOnPath }, 912 913 { "nDrawTextRun", "(J[CIIIIFFZJJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray }, 914 { "nDrawTextRun", "(JLjava/lang/String;IIIIFFZJJ)V", 915 (void*) android_view_GLES20Canvas_drawTextRun }, 916 917 { "nGetClipBounds", "(JLandroid/graphics/Rect;)Z", (void*) android_view_GLES20Canvas_getClipBounds }, 918 919 { "nFinishRecording", "(J)J", (void*) android_view_GLES20Canvas_finishRecording }, 920 { "nDrawRenderNode", "(JJLandroid/graphics/Rect;I)I", (void*) android_view_GLES20Canvas_drawRenderNode }, 921 922 { "nCreateDisplayListRenderer", "()J", (void*) android_view_GLES20Canvas_createDisplayListRenderer }, 923 924 { "nDrawLayer", "(JJFF)V", (void*) android_view_GLES20Canvas_drawLayer }, 925 926 { "nGetMaximumTextureWidth", "()I", (void*) android_view_GLES20Canvas_getMaxTextureWidth }, 927 { "nGetMaximumTextureHeight", "()I", (void*) android_view_GLES20Canvas_getMaxTextureHeight }, 928 929#endif 930}; 931 932static JNINativeMethod gActivityThreadMethods[] = { 933 { "dumpGraphicsInfo", "(Ljava/io/FileDescriptor;)V", 934 (void*) android_app_ActivityThread_dumpGraphics } 935}; 936 937 938#ifdef USE_OPENGL_RENDERER 939 #define FIND_CLASS(var, className) \ 940 var = env->FindClass(className); \ 941 LOG_FATAL_IF(! var, "Unable to find class " className); 942 943 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 944 var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 945 LOG_FATAL_IF(! var, "Unable to find method " methodName); 946#else 947 #define FIND_CLASS(var, className) 948 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) 949#endif 950 951int register_android_view_GLES20Canvas(JNIEnv* env) { 952 jclass clazz; 953 FIND_CLASS(clazz, "android/graphics/Rect"); 954 GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V"); 955 956 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 957} 958 959const char* const kActivityThreadPathName = "android/app/ActivityThread"; 960 961int register_android_app_ActivityThread(JNIEnv* env) { 962 return AndroidRuntime::registerNativeMethods(env, kActivityThreadPathName, 963 gActivityThreadMethods, NELEM(gActivityThreadMethods)); 964} 965 966}; 967