android_view_GLES20Canvas.cpp revision 796475006f5d670e8383a2050f11719522437a43
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 352 // apply transform directly to canvas, so it affects shaders correctly 353 renderer->save(SkCanvas::kMatrix_SaveFlag); 354 renderer->translate(left, top); 355 renderer->drawBitmap(bitmap, paint); 356 renderer->restore(); 357} 358 359static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz, 360 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 361 float srcLeft, float srcTop, float srcRight, float srcBottom, 362 float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) { 363 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 364 // This object allows the renderer to allocate a global JNI ref to the buffer object. 365 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 366 367 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 368 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 369 renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom, 370 dstLeft, dstTop, dstRight, dstBottom, paint); 371} 372 373static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz, 374 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 375 jlong matrixPtr, jlong paintPtr) { 376 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 377 // This object allows the renderer to allocate a global JNI ref to the buffer object. 378 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 379 380 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 381 SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr); 382 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 383 384 // apply transform directly to canvas, so it affects shaders correctly 385 renderer->save(SkCanvas::kMatrix_SaveFlag); 386 renderer->concatMatrix(*matrix); 387 renderer->drawBitmap(bitmap, paint); 388 renderer->restore(); 389} 390 391static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz, 392 jlong rendererPtr, jintArray colors, jint offset, jint stride, 393 jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) { 394 // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will 395 // correct the alphaType to kOpaque_SkAlphaType. 396 const SkImageInfo info = SkImageInfo::Make(width, height, 397 hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType, 398 kPremul_SkAlphaType); 399 SkBitmap* bitmap = new SkBitmap; 400 if (!bitmap->allocPixels(info)) { 401 delete bitmap; 402 return; 403 } 404 405 if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap)) { 406 delete bitmap; 407 return; 408 } 409 410 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 411 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 412 413 // apply transform directly to canvas, so it affects shaders correctly 414 renderer->save(SkCanvas::kMatrix_SaveFlag); 415 renderer->translate(left, top); 416 renderer->drawBitmapData(bitmap, paint); 417 renderer->restore(); 418 419 // Note - bitmap isn't deleted as DisplayListRenderer owns it now 420} 421 422static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz, 423 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, 424 jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors, 425 jint colorOffset, jlong paintPtr) { 426 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 427 // This object allows the renderer to allocate a global JNI ref to the buffer object. 428 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 429 430 jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL; 431 jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL; 432 433 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 434 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 435 renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint); 436 437 if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0); 438 if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0); 439} 440 441static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, 442 jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr, 443 float left, float top, float right, float bottom, jlong paintPtr) { 444 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr); 445 // This object allows the renderer to allocate a global JNI ref to the buffer object. 446 JavaHeapBitmapRef bitmapRef(env, bitmap, buffer); 447 448 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 449 Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr); 450 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 451 renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint); 452} 453 454static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz, 455 jlong rendererPtr, jint color, jint modeHandle) { 456 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 457 SkPorterDuff::Mode mode = static_cast<SkPorterDuff::Mode>(modeHandle); 458 renderer->drawColor(color, SkPorterDuff::ToXfermodeMode(mode)); 459} 460 461static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz, 462 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 463 jlong paintPtr) { 464 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 465 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 466 renderer->drawRect(left, top, right, bottom, paint); 467} 468 469static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz, 470 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 471 jfloat rx, jfloat ry, jlong paintPtr) { 472 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 473 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 474 renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint); 475} 476 477static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz, 478 jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) { 479 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 480 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 481 renderer->drawCircle(x, y, radius, paint); 482} 483 484static void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz, 485 jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) { 486 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 487 CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr); 488 CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr); 489 CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr); 490 CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr); 491 renderer->drawCircle(xProp, yProp, radiusProp, paintProp); 492} 493 494static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz, 495 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 496 jlong paintPtr) { 497 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 498 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 499 renderer->drawOval(left, top, right, bottom, paint); 500} 501 502static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz, 503 jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom, 504 jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) { 505 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 506 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 507 renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint); 508} 509 510static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz, 511 jlong rendererPtr, jlong regionPtr, jlong paintPtr) { 512 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 513 SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr); 514 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 515 if (paint->getStyle() != Paint::kFill_Style || 516 (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) { 517 SkRegion::Iterator it(*region); 518 while (!it.done()) { 519 const SkIRect& r = it.rect(); 520 renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint); 521 it.next(); 522 } 523 } else { 524 int count = 0; 525 Vector<float> rects; 526 SkRegion::Iterator it(*region); 527 while (!it.done()) { 528 const SkIRect& r = it.rect(); 529 rects.push(r.fLeft); 530 rects.push(r.fTop); 531 rects.push(r.fRight); 532 rects.push(r.fBottom); 533 count += 4; 534 it.next(); 535 } 536 renderer->drawRects(rects.array(), count, paint); 537 } 538} 539 540static void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz, 541 jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) { 542 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 543 jfloat* storage = env->GetFloatArrayElements(points, NULL); 544 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 545 renderer->drawPoints(storage + offset, count, paint); 546 env->ReleaseFloatArrayElements(points, storage, 0); 547} 548 549static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz, 550 jlong rendererPtr, jlong pathPtr, jlong paintPtr) { 551 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 552 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 553 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 554 renderer->drawPath(path, paint); 555} 556 557static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz, 558 jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) { 559 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 560 jfloat* storage = env->GetFloatArrayElements(points, NULL); 561 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 562 renderer->drawLines(storage + offset, count, paint); 563 env->ReleaseFloatArrayElements(points, storage, 0); 564} 565 566// ---------------------------------------------------------------------------- 567// Draw filters 568// ---------------------------------------------------------------------------- 569 570static void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz, 571 jlong rendererPtr, jint clearBits, jint setBits) { 572 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 573 renderer->setupPaintFilter(clearBits, setBits); 574} 575 576static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz, 577 jlong rendererPtr) { 578 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 579 renderer->resetPaintFilter(); 580} 581 582// ---------------------------------------------------------------------------- 583// Text 584// ---------------------------------------------------------------------------- 585 586class RenderTextFunctor { 587public: 588 RenderTextFunctor(const Layout& layout, DisplayListRenderer* renderer, jfloat x, jfloat y, 589 Paint* paint, uint16_t* glyphs, float* pos, float totalAdvance, 590 uirenderer::Rect& bounds) 591 : layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs), 592 pos(pos), totalAdvance(totalAdvance), bounds(bounds) { } 593 void operator()(size_t start, size_t end) { 594 for (size_t i = start; i < end; i++) { 595 glyphs[i] = layout.getGlyphId(i); 596 pos[2 * i] = layout.getX(i); 597 pos[2 * i + 1] = layout.getY(i); 598 } 599 size_t glyphsCount = end - start; 600 int bytesCount = glyphsCount * sizeof(jchar); 601 renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount, 602 x, y, pos + 2 * start, paint, totalAdvance, bounds); 603 } 604private: 605 const Layout& layout; 606 DisplayListRenderer* renderer; 607 jfloat x; 608 jfloat y; 609 Paint* paint; 610 uint16_t* glyphs; 611 float* pos; 612 float totalAdvance; 613 uirenderer::Rect& bounds; 614}; 615 616static void renderTextLayout(DisplayListRenderer* renderer, Layout* layout, 617 jfloat x, jfloat y, Paint* paint) { 618 size_t nGlyphs = layout->nGlyphs(); 619 float* pos = new float[nGlyphs * 2]; 620 uint16_t* glyphs = new uint16_t[nGlyphs]; 621 MinikinRect b; 622 layout->getBounds(&b); 623 android::uirenderer::Rect bounds(b.mLeft, b.mTop, b.mRight, b.mBottom); 624 bounds.translate(x, y); 625 float totalAdvance = layout->getAdvance(); 626 627 RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds); 628 MinikinUtils::forFontRun(*layout, paint, f); 629 delete[] glyphs; 630 delete[] pos; 631} 632 633static void renderText(DisplayListRenderer* renderer, const jchar* text, int count, 634 jfloat x, jfloat y, int bidiFlags, Paint* paint, TypefaceImpl* typeface) { 635 Layout layout; 636 MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count); 637 x += MinikinUtils::xOffsetForTextAlign(paint, layout); 638 renderTextLayout(renderer, &layout, x, y, paint); 639} 640 641class RenderTextOnPathFunctor { 642public: 643 RenderTextOnPathFunctor(const Layout& layout, DisplayListRenderer* renderer, float hOffset, 644 float vOffset, Paint* paint, SkPath* path) 645 : layout(layout), renderer(renderer), hOffset(hOffset), vOffset(vOffset), 646 paint(paint), path(path) { 647 } 648 void operator()(size_t start, size_t end) { 649 uint16_t glyphs[1]; 650 for (size_t i = start; i < end; i++) { 651 glyphs[0] = layout.getGlyphId(i); 652 float x = hOffset + layout.getX(i); 653 float y = vOffset + layout.getY(i); 654 renderer->drawTextOnPath((const char*) glyphs, sizeof(glyphs), 1, path, x, y, paint); 655 } 656 } 657private: 658 const Layout& layout; 659 DisplayListRenderer* renderer; 660 float hOffset; 661 float vOffset; 662 Paint* paint; 663 SkPath* path; 664}; 665 666static void renderTextOnPath(DisplayListRenderer* renderer, const jchar* text, int count, 667 SkPath* path, jfloat hOffset, jfloat vOffset, int bidiFlags, Paint* paint, 668 TypefaceImpl* typeface) { 669 Layout layout; 670 MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count); 671 hOffset += MinikinUtils::hOffsetForTextAlign(paint, layout, *path); 672 Paint::Align align = paint->getTextAlign(); 673 paint->setTextAlign(Paint::kLeft_Align); 674 675 RenderTextOnPathFunctor f(layout, renderer, hOffset, vOffset, paint, path); 676 MinikinUtils::forFontRun(layout, paint, f); 677 paint->setTextAlign(align); 678} 679 680static void renderTextRun(DisplayListRenderer* renderer, const jchar* text, 681 jint start, jint count, jint contextCount, jfloat x, jfloat y, 682 int bidiFlags, Paint* paint, TypefaceImpl* typeface) { 683 Layout layout; 684 MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, contextCount); 685 x += MinikinUtils::xOffsetForTextAlign(paint, layout); 686 renderTextLayout(renderer, &layout, x, y, paint); 687} 688 689static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz, 690 jlong rendererPtr, jcharArray text, jint index, jint count, 691 jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) { 692 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 693 jchar* textArray = env->GetCharArrayElements(text, NULL); 694 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 695 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 696 697 renderText(renderer, textArray + index, count, x, y, bidiFlags, paint, typeface); 698 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 699} 700 701static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz, 702 jlong rendererPtr, jstring text, jint start, jint end, 703 jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) { 704 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 705 const jchar* textArray = env->GetStringChars(text, NULL); 706 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 707 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 708 709 renderText(renderer, textArray + start, end - start, x, y, bidiFlags, paint, typeface); 710 env->ReleaseStringChars(text, textArray); 711} 712 713static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz, 714 jlong rendererPtr, jcharArray text, jint index, jint count, 715 jlong pathPtr, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintPtr, 716 jlong typefacePtr) { 717 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 718 jchar* textArray = env->GetCharArrayElements(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 + index, count, path, 724 hOffset, vOffset, bidiFlags, paint, typeface); 725 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 726} 727 728static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz, 729 jlong rendererPtr, jstring text, jint start, jint end, 730 jlong pathPtr, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintPtr, 731 jlong typefacePtr) { 732 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 733 const jchar* textArray = env->GetStringChars(text, NULL); 734 SkPath* path = reinterpret_cast<SkPath*>(pathPtr); 735 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 736 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 737 738 renderTextOnPath(renderer, textArray + start, end - start, path, 739 hOffset, vOffset, bidiFlags, paint, typeface); 740 env->ReleaseStringChars(text, textArray); 741} 742 743static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz, 744 jlong rendererPtr, jcharArray text, jint index, jint count, 745 jint contextIndex, jint contextCount, jfloat x, jfloat y, jboolean isRtl, 746 jlong paintPtr, jlong typefacePtr) { 747 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 748 jchar* textArray = env->GetCharArrayElements(text, NULL); 749 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 750 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 751 752 int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; 753 renderTextRun(renderer, textArray + contextIndex, index - contextIndex, 754 count, contextCount, x, y, bidiFlags, paint, typeface); 755 env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); 756 } 757 758static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz, 759 jlong rendererPtr, jstring text, jint start, jint end, 760 jint contextStart, int contextEnd, jfloat x, jfloat y, jboolean isRtl, 761 jlong paintPtr, jlong typefacePtr) { 762 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 763 const jchar* textArray = env->GetStringChars(text, NULL); 764 jint count = end - start; 765 jint contextCount = contextEnd - contextStart; 766 Paint* paint = reinterpret_cast<Paint*>(paintPtr); 767 TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr); 768 769 int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR; 770 renderTextRun(renderer, textArray + contextStart, start - contextStart, 771 count, contextCount, x, y, bidiFlags, paint, typeface); 772 env->ReleaseStringChars(text, textArray); 773} 774 775// ---------------------------------------------------------------------------- 776// Display lists 777// ---------------------------------------------------------------------------- 778 779static jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env, 780 jobject clazz, jlong rendererPtr) { 781 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 782 return reinterpret_cast<jlong>(renderer->finishRecording()); 783} 784 785static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env, jobject clazz) { 786 return reinterpret_cast<jlong>(new DisplayListRenderer); 787} 788 789static jint android_view_GLES20Canvas_drawRenderNode(JNIEnv* env, 790 jobject clazz, jlong rendererPtr, jlong renderNodePtr, 791 jobject dirty, jint flags) { 792 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 793 RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); 794 android::uirenderer::Rect bounds; 795 status_t status = renderer->drawRenderNode(renderNode, bounds, flags); 796 if (status != DrawGlInfo::kStatusDone && dirty != NULL) { 797 env->CallVoidMethod(dirty, gRectClassInfo.set, 798 int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); 799 } 800 return status; 801} 802 803// ---------------------------------------------------------------------------- 804// Layers 805// ---------------------------------------------------------------------------- 806 807static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz, 808 jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) { 809 DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); 810 Layer* layer = reinterpret_cast<Layer*>(layerPtr); 811 renderer->drawLayer(layer, x, y); 812} 813 814#endif // USE_OPENGL_RENDERER 815 816// ---------------------------------------------------------------------------- 817// Common 818// ---------------------------------------------------------------------------- 819 820static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz) { 821#ifdef USE_OPENGL_RENDERER 822 char prop[PROPERTY_VALUE_MAX]; 823 if (property_get("ro.kernel.qemu", prop, NULL) == 0) { 824 // not in the emulator 825 return JNI_TRUE; 826 } 827 // In the emulator this property will be set to 1 when hardware GLES is 828 // enabled, 0 otherwise. On old emulator versions it will be undefined. 829 property_get("ro.kernel.qemu.gles", prop, "0"); 830 return atoi(prop) == 1 ? JNI_TRUE : JNI_FALSE; 831#else 832 return JNI_FALSE; 833#endif 834} 835 836// ---------------------------------------------------------------------------- 837// Logging 838// ---------------------------------------------------------------------------- 839 840static void 841android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) { 842#ifdef USE_OPENGL_RENDERER 843 int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); 844 android::uirenderer::RenderNode::outputLogBuffer(fd); 845#endif // USE_OPENGL_RENDERER 846} 847 848// ---------------------------------------------------------------------------- 849// JNI Glue 850// ---------------------------------------------------------------------------- 851 852const char* const kClassPathName = "android/view/GLES20Canvas"; 853 854static JNINativeMethod gMethods[] = { 855 { "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable }, 856 857#ifdef USE_OPENGL_RENDERER 858 859 { "nDestroyRenderer", "(J)V", (void*) android_view_GLES20Canvas_destroyRenderer }, 860 { "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport }, 861 { "nSetHighContrastText","(JZ)V", (void*) android_view_GLES20Canvas_setHighContrastText }, 862 { "nPrepare", "(JZ)I", (void*) android_view_GLES20Canvas_prepare }, 863 { "nPrepareDirty", "(JIIIIZ)I", (void*) android_view_GLES20Canvas_prepareDirty }, 864 { "nFinish", "(J)V", (void*) android_view_GLES20Canvas_finish }, 865 { "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V", 866 (void*) android_view_GLES20Canvas_setProperty }, 867 868 { "nCallDrawGLFunction", "(JJ)I", (void*) android_view_GLES20Canvas_callDrawGLFunction }, 869 870 { "nSave", "(JI)I", (void*) android_view_GLES20Canvas_save }, 871 { "nRestore", "(J)V", (void*) android_view_GLES20Canvas_restore }, 872 { "nRestoreToCount", "(JI)V", (void*) android_view_GLES20Canvas_restoreToCount }, 873 { "nGetSaveCount", "(J)I", (void*) android_view_GLES20Canvas_getSaveCount }, 874 875 { "nSaveLayer", "(JFFFFJI)I", (void*) android_view_GLES20Canvas_saveLayer }, 876 { "nSaveLayer", "(JJI)I", (void*) android_view_GLES20Canvas_saveLayerClip }, 877 { "nSaveLayerAlpha", "(JFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha }, 878 { "nSaveLayerAlpha", "(JII)I", (void*) android_view_GLES20Canvas_saveLayerAlphaClip }, 879 880 { "nQuickReject", "(JFFFF)Z", (void*) android_view_GLES20Canvas_quickReject }, 881 { "nClipRect", "(JFFFFI)Z", (void*) android_view_GLES20Canvas_clipRectF }, 882 { "nClipRect", "(JIIIII)Z", (void*) android_view_GLES20Canvas_clipRect }, 883 { "nClipPath", "(JJI)Z", (void*) android_view_GLES20Canvas_clipPath }, 884 { "nClipRegion", "(JJI)Z", (void*) android_view_GLES20Canvas_clipRegion }, 885 886 { "nTranslate", "(JFF)V", (void*) android_view_GLES20Canvas_translate }, 887 { "nRotate", "(JF)V", (void*) android_view_GLES20Canvas_rotate }, 888 { "nScale", "(JFF)V", (void*) android_view_GLES20Canvas_scale }, 889 { "nSkew", "(JFF)V", (void*) android_view_GLES20Canvas_skew }, 890 891 { "nSetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_setMatrix }, 892 { "nGetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_getMatrix }, 893 { "nConcatMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_concatMatrix }, 894 895 { "nDrawBitmap", "(JJ[BFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap }, 896 { "nDrawBitmap", "(JJ[BFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect }, 897 { "nDrawBitmap", "(JJ[BJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix }, 898 { "nDrawBitmap", "(J[IIIFFIIZJ)V", (void*) android_view_GLES20Canvas_drawBitmapData }, 899 900 { "nDrawBitmapMesh", "(JJ[BII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh }, 901 902 { "nDrawPatch", "(JJ[BJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch }, 903 904 { "nDrawColor", "(JII)V", (void*) android_view_GLES20Canvas_drawColor }, 905 { "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect }, 906 { "nDrawRects", "(JJJ)V", (void*) android_view_GLES20Canvas_drawRegionAsRects }, 907 { "nDrawRoundRect", "(JFFFFFFJ)V", (void*) android_view_GLES20Canvas_drawRoundRect }, 908 { "nDrawCircle", "(JFFFJ)V", (void*) android_view_GLES20Canvas_drawCircle }, 909 { "nDrawCircle", "(JJJJJ)V", (void*) android_view_GLES20Canvas_drawCircleProps }, 910 { "nDrawOval", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawOval }, 911 { "nDrawArc", "(JFFFFFFZJ)V", (void*) android_view_GLES20Canvas_drawArc }, 912 { "nDrawPoints", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawPoints }, 913 914 { "nDrawPath", "(JJJ)V", (void*) android_view_GLES20Canvas_drawPath }, 915 { "nDrawLines", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawLines }, 916 917 { "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter }, 918 { "nResetPaintFilter", "(J)V", (void*) android_view_GLES20Canvas_resetPaintFilter }, 919 920 { "nDrawText", "(J[CIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArray }, 921 { "nDrawText", "(JLjava/lang/String;IIFFIJJ)V", 922 (void*) android_view_GLES20Canvas_drawText }, 923 924 { "nDrawTextOnPath", "(J[CIIJFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath }, 925 { "nDrawTextOnPath", "(JLjava/lang/String;IIJFFIJJ)V", 926 (void*) android_view_GLES20Canvas_drawTextOnPath }, 927 928 { "nDrawTextRun", "(J[CIIIIFFZJJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray }, 929 { "nDrawTextRun", "(JLjava/lang/String;IIIIFFZJJ)V", 930 (void*) android_view_GLES20Canvas_drawTextRun }, 931 932 { "nGetClipBounds", "(JLandroid/graphics/Rect;)Z", (void*) android_view_GLES20Canvas_getClipBounds }, 933 934 { "nFinishRecording", "(J)J", (void*) android_view_GLES20Canvas_finishRecording }, 935 { "nDrawRenderNode", "(JJLandroid/graphics/Rect;I)I", (void*) android_view_GLES20Canvas_drawRenderNode }, 936 937 { "nCreateDisplayListRenderer", "()J", (void*) android_view_GLES20Canvas_createDisplayListRenderer }, 938 939 { "nDrawLayer", "(JJFF)V", (void*) android_view_GLES20Canvas_drawLayer }, 940 941 { "nGetMaximumTextureWidth", "()I", (void*) android_view_GLES20Canvas_getMaxTextureWidth }, 942 { "nGetMaximumTextureHeight", "()I", (void*) android_view_GLES20Canvas_getMaxTextureHeight }, 943 944#endif 945}; 946 947static JNINativeMethod gActivityThreadMethods[] = { 948 { "dumpGraphicsInfo", "(Ljava/io/FileDescriptor;)V", 949 (void*) android_app_ActivityThread_dumpGraphics } 950}; 951 952 953#ifdef USE_OPENGL_RENDERER 954 #define FIND_CLASS(var, className) \ 955 var = env->FindClass(className); \ 956 LOG_FATAL_IF(! var, "Unable to find class " className); 957 958 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 959 var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 960 LOG_FATAL_IF(! var, "Unable to find method " methodName); 961#else 962 #define FIND_CLASS(var, className) 963 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) 964#endif 965 966int register_android_view_GLES20Canvas(JNIEnv* env) { 967 jclass clazz; 968 FIND_CLASS(clazz, "android/graphics/Rect"); 969 GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V"); 970 971 return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); 972} 973 974const char* const kActivityThreadPathName = "android/app/ActivityThread"; 975 976int register_android_app_ActivityThread(JNIEnv* env) { 977 return AndroidRuntime::registerNativeMethods(env, kActivityThreadPathName, 978 gActivityThreadMethods, NELEM(gActivityThreadMethods)); 979} 980 981}; 982