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 <SkCamera.h> 20 21 #include <private/hwui/DrawGlInfo.h> 22 23 #include "DisplayListLogBuffer.h" 24 #include "DisplayListRenderer.h" 25 #include "Caches.h" 26 27 namespace android { 28 namespace uirenderer { 29 30 /////////////////////////////////////////////////////////////////////////////// 31 // Display list 32 /////////////////////////////////////////////////////////////////////////////// 33 34 const char* DisplayList::OP_NAMES[] = { 35 "Save", 36 "Restore", 37 "RestoreToCount", 38 "SaveLayer", 39 "SaveLayerAlpha", 40 "Translate", 41 "Rotate", 42 "Scale", 43 "Skew", 44 "SetMatrix", 45 "ConcatMatrix", 46 "ClipRect", 47 "DrawDisplayList", 48 "DrawLayer", 49 "DrawBitmap", 50 "DrawBitmapMatrix", 51 "DrawBitmapRect", 52 "DrawBitmapData", 53 "DrawBitmapMesh", 54 "DrawPatch", 55 "DrawColor", 56 "DrawRect", 57 "DrawRoundRect", 58 "DrawCircle", 59 "DrawOval", 60 "DrawArc", 61 "DrawPath", 62 "DrawLines", 63 "DrawPoints", 64 "DrawText", 65 "DrawTextOnPath", 66 "DrawPosText", 67 "ResetShader", 68 "SetupShader", 69 "ResetColorFilter", 70 "SetupColorFilter", 71 "ResetShadow", 72 "SetupShadow", 73 "ResetPaintFilter", 74 "SetupPaintFilter", 75 "DrawGLFunction" 76 }; 77 78 void DisplayList::outputLogBuffer(int fd) { 79 DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); 80 if (logBuffer.isEmpty()) { 81 return; 82 } 83 84 FILE *file = fdopen(fd, "a"); 85 86 fprintf(file, "\nRecent DisplayList operations\n"); 87 logBuffer.outputCommands(file, OP_NAMES); 88 89 String8 cachesLog; 90 Caches::getInstance().dumpMemoryUsage(cachesLog); 91 fprintf(file, "\nCaches:\n%s", cachesLog.string()); 92 fprintf(file, "\n"); 93 94 fflush(file); 95 } 96 97 DisplayList::DisplayList(const DisplayListRenderer& recorder) : 98 mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL), 99 mStaticMatrix(NULL), mAnimationMatrix(NULL) { 100 101 initFromDisplayListRenderer(recorder); 102 } 103 104 DisplayList::~DisplayList() { 105 clearResources(); 106 } 107 108 void DisplayList::initProperties() { 109 mLeft = 0; 110 mTop = 0; 111 mRight = 0; 112 mBottom = 0; 113 mClipChildren = true; 114 mAlpha = 1; 115 mMultipliedAlpha = 255; 116 mHasOverlappingRendering = true; 117 mTranslationX = 0; 118 mTranslationY = 0; 119 mRotation = 0; 120 mRotationX = 0; 121 mRotationY= 0; 122 mScaleX = 1; 123 mScaleY = 1; 124 mPivotX = 0; 125 mPivotY = 0; 126 mCameraDistance = 0; 127 mMatrixDirty = false; 128 mMatrixFlags = 0; 129 mPrevWidth = -1; 130 mPrevHeight = -1; 131 mWidth = 0; 132 mHeight = 0; 133 mPivotExplicitlySet = false; 134 mCaching = false; 135 } 136 137 void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { 138 if (displayList) { 139 DISPLAY_LIST_LOGD("Deferring display list destruction"); 140 Caches::getInstance().deleteDisplayListDeferred(displayList); 141 } 142 } 143 144 void DisplayList::clearResources() { 145 sk_free((void*) mReader.base()); 146 147 delete mTransformMatrix; 148 delete mTransformCamera; 149 delete mTransformMatrix3D; 150 delete mStaticMatrix; 151 delete mAnimationMatrix; 152 mTransformMatrix = NULL; 153 mTransformCamera = NULL; 154 mTransformMatrix3D = NULL; 155 mStaticMatrix = NULL; 156 mAnimationMatrix = NULL; 157 158 Caches& caches = Caches::getInstance(); 159 160 for (size_t i = 0; i < mBitmapResources.size(); i++) { 161 caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); 162 } 163 mBitmapResources.clear(); 164 165 for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { 166 SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); 167 caches.resourceCache.decrementRefcount(bitmap); 168 caches.resourceCache.destructor(bitmap); 169 } 170 mOwnedBitmapResources.clear(); 171 172 for (size_t i = 0; i < mFilterResources.size(); i++) { 173 caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i)); 174 } 175 mFilterResources.clear(); 176 177 for (size_t i = 0; i < mShaders.size(); i++) { 178 caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); 179 caches.resourceCache.destructor(mShaders.itemAt(i)); 180 } 181 mShaders.clear(); 182 183 for (size_t i = 0; i < mPaints.size(); i++) { 184 delete mPaints.itemAt(i); 185 } 186 mPaints.clear(); 187 188 for (size_t i = 0; i < mPaths.size(); i++) { 189 SkPath* path = mPaths.itemAt(i); 190 caches.pathCache.remove(path); 191 delete path; 192 } 193 mPaths.clear(); 194 195 for (size_t i = 0; i < mSourcePaths.size(); i++) { 196 caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i)); 197 } 198 mSourcePaths.clear(); 199 200 for (size_t i = 0; i < mMatrices.size(); i++) { 201 delete mMatrices.itemAt(i); 202 } 203 mMatrices.clear(); 204 } 205 206 void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) { 207 const SkWriter32& writer = recorder.writeStream(); 208 init(); 209 210 if (writer.size() == 0) { 211 return; 212 } 213 214 if (reusing) { 215 // re-using display list - clear out previous allocations 216 clearResources(); 217 } 218 initProperties(); 219 220 mSize = writer.size(); 221 void* buffer = sk_malloc_throw(mSize); 222 writer.flatten(buffer); 223 mReader.setMemory(buffer, mSize); 224 225 Caches& caches = Caches::getInstance(); 226 227 const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources(); 228 for (size_t i = 0; i < bitmapResources.size(); i++) { 229 SkBitmap* resource = bitmapResources.itemAt(i); 230 mBitmapResources.add(resource); 231 caches.resourceCache.incrementRefcount(resource); 232 } 233 234 const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources(); 235 for (size_t i = 0; i < ownedBitmapResources.size(); i++) { 236 SkBitmap* resource = ownedBitmapResources.itemAt(i); 237 mOwnedBitmapResources.add(resource); 238 caches.resourceCache.incrementRefcount(resource); 239 } 240 241 const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources(); 242 for (size_t i = 0; i < filterResources.size(); i++) { 243 SkiaColorFilter* resource = filterResources.itemAt(i); 244 mFilterResources.add(resource); 245 caches.resourceCache.incrementRefcount(resource); 246 } 247 248 const Vector<SkiaShader*>& shaders = recorder.getShaders(); 249 for (size_t i = 0; i < shaders.size(); i++) { 250 SkiaShader* resource = shaders.itemAt(i); 251 mShaders.add(resource); 252 caches.resourceCache.incrementRefcount(resource); 253 } 254 255 const Vector<SkPaint*>& paints = recorder.getPaints(); 256 for (size_t i = 0; i < paints.size(); i++) { 257 mPaints.add(paints.itemAt(i)); 258 } 259 260 const Vector<SkPath*>& paths = recorder.getPaths(); 261 for (size_t i = 0; i < paths.size(); i++) { 262 mPaths.add(paths.itemAt(i)); 263 } 264 265 const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths(); 266 for (size_t i = 0; i < sourcePaths.size(); i++) { 267 mSourcePaths.add(sourcePaths.itemAt(i)); 268 caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i)); 269 } 270 271 const Vector<SkMatrix*>& matrices = recorder.getMatrices(); 272 for (size_t i = 0; i < matrices.size(); i++) { 273 mMatrices.add(matrices.itemAt(i)); 274 } 275 } 276 277 void DisplayList::init() { 278 mSize = 0; 279 mIsRenderable = true; 280 } 281 282 size_t DisplayList::getSize() { 283 return mSize; 284 } 285 286 /** 287 * This function is a simplified version of replay(), where we simply retrieve and log the 288 * display list. This function should remain in sync with the replay() function. 289 */ 290 void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { 291 TextContainer text; 292 293 uint32_t count = (level + 1) * 2; 294 char indent[count + 1]; 295 for (uint32_t i = 0; i < count; i++) { 296 indent[i] = ' '; 297 } 298 indent[count] = '\0'; 299 ALOGD("%sStart display list (%p, %s, render=%d)", (char*) indent + 2, this, 300 mName.string(), isRenderable()); 301 302 ALOGD("%s%s %d", indent, "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 303 int saveCount = renderer.getSaveCount() - 1; 304 305 outputViewProperties(renderer, (char*) indent); 306 mReader.rewind(); 307 308 while (!mReader.eof()) { 309 int op = mReader.readInt(); 310 if (op & OP_MAY_BE_SKIPPED_MASK) { 311 int skip = mReader.readInt(); 312 ALOGD("%sSkip %d", (char*) indent, skip); 313 op &= ~OP_MAY_BE_SKIPPED_MASK; 314 } 315 316 switch (op) { 317 case DrawGLFunction: { 318 Functor *functor = (Functor *) getInt(); 319 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor); 320 } 321 break; 322 case Save: { 323 int rendererNum = getInt(); 324 ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum); 325 } 326 break; 327 case Restore: { 328 ALOGD("%s%s", (char*) indent, OP_NAMES[op]); 329 } 330 break; 331 case RestoreToCount: { 332 int restoreCount = saveCount + getInt(); 333 ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount); 334 } 335 break; 336 case SaveLayer: { 337 float f1 = getFloat(); 338 float f2 = getFloat(); 339 float f3 = getFloat(); 340 float f4 = getFloat(); 341 SkPaint* paint = getPaint(renderer); 342 int flags = getInt(); 343 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent, 344 OP_NAMES[op], f1, f2, f3, f4, paint, flags); 345 } 346 break; 347 case SaveLayerAlpha: { 348 float f1 = getFloat(); 349 float f2 = getFloat(); 350 float f3 = getFloat(); 351 float f4 = getFloat(); 352 int alpha = getInt(); 353 int flags = getInt(); 354 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent, 355 OP_NAMES[op], f1, f2, f3, f4, alpha, flags); 356 } 357 break; 358 case Translate: { 359 float f1 = getFloat(); 360 float f2 = getFloat(); 361 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2); 362 } 363 break; 364 case Rotate: { 365 float rotation = getFloat(); 366 ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation); 367 } 368 break; 369 case Scale: { 370 float sx = getFloat(); 371 float sy = getFloat(); 372 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); 373 } 374 break; 375 case Skew: { 376 float sx = getFloat(); 377 float sy = getFloat(); 378 ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); 379 } 380 break; 381 case SetMatrix: { 382 SkMatrix* matrix = getMatrix(); 383 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix); 384 } 385 break; 386 case ConcatMatrix: { 387 SkMatrix* matrix = getMatrix(); 388 ALOGD("%s%s new concat %p: [%f, %f, %f] [%f, %f, %f] [%f, %f, %f]", 389 (char*) indent, OP_NAMES[op], matrix, matrix->get(0), matrix->get(1), 390 matrix->get(2), matrix->get(3), matrix->get(4), matrix->get(5), 391 matrix->get(6), matrix->get(7), matrix->get(8)); 392 } 393 break; 394 case ClipRect: { 395 float f1 = getFloat(); 396 float f2 = getFloat(); 397 float f3 = getFloat(); 398 float f4 = getFloat(); 399 int regionOp = getInt(); 400 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op], 401 f1, f2, f3, f4, regionOp); 402 } 403 break; 404 case DrawDisplayList: { 405 DisplayList* displayList = getDisplayList(); 406 int32_t flags = getInt(); 407 ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op], 408 displayList, mWidth, mHeight, flags, level + 1); 409 renderer.outputDisplayList(displayList, level + 1); 410 } 411 break; 412 case DrawLayer: { 413 Layer* layer = (Layer*) getInt(); 414 float x = getFloat(); 415 float y = getFloat(); 416 SkPaint* paint = getPaint(renderer); 417 ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], 418 layer, x, y, paint); 419 } 420 break; 421 case DrawBitmap: { 422 SkBitmap* bitmap = getBitmap(); 423 float x = getFloat(); 424 float y = getFloat(); 425 SkPaint* paint = getPaint(renderer); 426 ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], 427 bitmap, x, y, paint); 428 } 429 break; 430 case DrawBitmapMatrix: { 431 SkBitmap* bitmap = getBitmap(); 432 SkMatrix* matrix = getMatrix(); 433 SkPaint* paint = getPaint(renderer); 434 ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op], 435 bitmap, matrix, paint); 436 } 437 break; 438 case DrawBitmapRect: { 439 SkBitmap* bitmap = getBitmap(); 440 float f1 = getFloat(); 441 float f2 = getFloat(); 442 float f3 = getFloat(); 443 float f4 = getFloat(); 444 float f5 = getFloat(); 445 float f6 = getFloat(); 446 float f7 = getFloat(); 447 float f8 = getFloat(); 448 SkPaint* paint = getPaint(renderer); 449 ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", 450 (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint); 451 } 452 break; 453 case DrawBitmapData: { 454 SkBitmap* bitmap = getBitmapData(); 455 float x = getFloat(); 456 float y = getFloat(); 457 SkPaint* paint = getPaint(renderer); 458 ALOGD("%s%s %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], x, y, paint); 459 } 460 break; 461 case DrawBitmapMesh: { 462 int verticesCount = 0; 463 uint32_t colorsCount = 0; 464 SkBitmap* bitmap = getBitmap(); 465 uint32_t meshWidth = getInt(); 466 uint32_t meshHeight = getInt(); 467 float* vertices = getFloats(verticesCount); 468 bool hasColors = getInt(); 469 int* colors = hasColors ? getInts(colorsCount) : NULL; 470 SkPaint* paint = getPaint(renderer); 471 ALOGD("%s%s", (char*) indent, OP_NAMES[op]); 472 } 473 break; 474 case DrawPatch: { 475 int32_t* xDivs = NULL; 476 int32_t* yDivs = NULL; 477 uint32_t* colors = NULL; 478 uint32_t xDivsCount = 0; 479 uint32_t yDivsCount = 0; 480 int8_t numColors = 0; 481 SkBitmap* bitmap = getBitmap(); 482 xDivs = getInts(xDivsCount); 483 yDivs = getInts(yDivsCount); 484 colors = getUInts(numColors); 485 float left = getFloat(); 486 float top = getFloat(); 487 float right = getFloat(); 488 float bottom = getFloat(); 489 SkPaint* paint = getPaint(renderer); 490 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op], 491 left, top, right, bottom); 492 } 493 break; 494 case DrawColor: { 495 int color = getInt(); 496 int xferMode = getInt(); 497 ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode); 498 } 499 break; 500 case DrawRect: { 501 float f1 = getFloat(); 502 float f2 = getFloat(); 503 float f3 = getFloat(); 504 float f4 = getFloat(); 505 SkPaint* paint = getPaint(renderer); 506 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], 507 f1, f2, f3, f4, paint); 508 } 509 break; 510 case DrawRoundRect: { 511 float f1 = getFloat(); 512 float f2 = getFloat(); 513 float f3 = getFloat(); 514 float f4 = getFloat(); 515 float f5 = getFloat(); 516 float f6 = getFloat(); 517 SkPaint* paint = getPaint(renderer); 518 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", 519 (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint); 520 } 521 break; 522 case DrawCircle: { 523 float f1 = getFloat(); 524 float f2 = getFloat(); 525 float f3 = getFloat(); 526 SkPaint* paint = getPaint(renderer); 527 ALOGD("%s%s %.2f, %.2f, %.2f, %p", 528 (char*) indent, OP_NAMES[op], f1, f2, f3, paint); 529 } 530 break; 531 case DrawOval: { 532 float f1 = getFloat(); 533 float f2 = getFloat(); 534 float f3 = getFloat(); 535 float f4 = getFloat(); 536 SkPaint* paint = getPaint(renderer); 537 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", 538 (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint); 539 } 540 break; 541 case DrawArc: { 542 float f1 = getFloat(); 543 float f2 = getFloat(); 544 float f3 = getFloat(); 545 float f4 = getFloat(); 546 float f5 = getFloat(); 547 float f6 = getFloat(); 548 int i1 = getInt(); 549 SkPaint* paint = getPaint(renderer); 550 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p", 551 (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint); 552 } 553 break; 554 case DrawPath: { 555 SkPath* path = getPath(); 556 SkPaint* paint = getPaint(renderer); 557 ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint); 558 } 559 break; 560 case DrawLines: { 561 int count = 0; 562 float* points = getFloats(count); 563 SkPaint* paint = getPaint(renderer); 564 ALOGD("%s%s", (char*) indent, OP_NAMES[op]); 565 } 566 break; 567 case DrawPoints: { 568 int count = 0; 569 float* points = getFloats(count); 570 SkPaint* paint = getPaint(renderer); 571 ALOGD("%s%s", (char*) indent, OP_NAMES[op]); 572 } 573 break; 574 case DrawText: { 575 getText(&text); 576 int32_t count = getInt(); 577 float x = getFloat(); 578 float y = getFloat(); 579 SkPaint* paint = getPaint(renderer); 580 float length = getFloat(); 581 ALOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op], 582 text.text(), text.length(), count, x, y, paint, length); 583 } 584 break; 585 case DrawTextOnPath: { 586 getText(&text); 587 int32_t count = getInt(); 588 SkPath* path = getPath(); 589 float hOffset = getFloat(); 590 float vOffset = getFloat(); 591 SkPaint* paint = getPaint(renderer); 592 ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], 593 text.text(), text.length(), count, paint); 594 } 595 break; 596 case DrawPosText: { 597 getText(&text); 598 int count = getInt(); 599 int positionsCount = 0; 600 float* positions = getFloats(positionsCount); 601 SkPaint* paint = getPaint(renderer); 602 ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], 603 text.text(), text.length(), count, paint); 604 } 605 case ResetShader: { 606 ALOGD("%s%s", (char*) indent, OP_NAMES[op]); 607 } 608 break; 609 case SetupShader: { 610 SkiaShader* shader = getShader(); 611 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader); 612 } 613 break; 614 case ResetColorFilter: { 615 ALOGD("%s%s", (char*) indent, OP_NAMES[op]); 616 } 617 break; 618 case SetupColorFilter: { 619 SkiaColorFilter *colorFilter = getColorFilter(); 620 ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter); 621 } 622 break; 623 case ResetShadow: { 624 ALOGD("%s%s", (char*) indent, OP_NAMES[op]); 625 } 626 break; 627 case SetupShadow: { 628 float radius = getFloat(); 629 float dx = getFloat(); 630 float dy = getFloat(); 631 int color = getInt(); 632 ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op], 633 radius, dx, dy, color); 634 } 635 break; 636 case ResetPaintFilter: { 637 ALOGD("%s%s", (char*) indent, OP_NAMES[op]); 638 } 639 break; 640 case SetupPaintFilter: { 641 int clearBits = getInt(); 642 int setBits = getInt(); 643 ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits); 644 } 645 break; 646 default: 647 ALOGD("Display List error: op not handled: %s%s", 648 (char*) indent, OP_NAMES[op]); 649 break; 650 } 651 } 652 ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string()); 653 } 654 655 void DisplayList::updateMatrix() { 656 if (mMatrixDirty) { 657 if (!mTransformMatrix) { 658 mTransformMatrix = new SkMatrix(); 659 } 660 if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) { 661 mTransformMatrix->reset(); 662 } else { 663 if (!mPivotExplicitlySet) { 664 if (mWidth != mPrevWidth || mHeight != mPrevHeight) { 665 mPrevWidth = mWidth; 666 mPrevHeight = mHeight; 667 mPivotX = mPrevWidth / 2; 668 mPivotY = mPrevHeight / 2; 669 } 670 } 671 if ((mMatrixFlags & ROTATION_3D) == 0) { 672 mTransformMatrix->setTranslate(mTranslationX, mTranslationY); 673 mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY); 674 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY); 675 } else { 676 if (!mTransformCamera) { 677 mTransformCamera = new Sk3DView(); 678 mTransformMatrix3D = new SkMatrix(); 679 } 680 mTransformMatrix->reset(); 681 mTransformCamera->save(); 682 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY); 683 mTransformCamera->rotateX(mRotationX); 684 mTransformCamera->rotateY(mRotationY); 685 mTransformCamera->rotateZ(-mRotation); 686 mTransformCamera->getMatrix(mTransformMatrix3D); 687 mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY); 688 mTransformMatrix3D->postTranslate(mPivotX + mTranslationX, 689 mPivotY + mTranslationY); 690 mTransformMatrix->postConcat(*mTransformMatrix3D); 691 mTransformCamera->restore(); 692 } 693 } 694 mMatrixDirty = false; 695 } 696 } 697 698 void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) { 699 updateMatrix(); 700 if (mLeft != 0 || mTop != 0) { 701 ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop); 702 } 703 if (mStaticMatrix) { 704 ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", 705 indent, "ConcatMatrix (static)", mStaticMatrix, 706 mStaticMatrix->get(0), mStaticMatrix->get(1), 707 mStaticMatrix->get(2), mStaticMatrix->get(3), 708 mStaticMatrix->get(4), mStaticMatrix->get(5), 709 mStaticMatrix->get(6), mStaticMatrix->get(7), 710 mStaticMatrix->get(8)); 711 } 712 if (mAnimationMatrix) { 713 ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", 714 indent, "ConcatMatrix (animation)", mAnimationMatrix, 715 mAnimationMatrix->get(0), mAnimationMatrix->get(1), 716 mAnimationMatrix->get(2), mAnimationMatrix->get(3), 717 mAnimationMatrix->get(4), mAnimationMatrix->get(5), 718 mAnimationMatrix->get(6), mAnimationMatrix->get(7), 719 mAnimationMatrix->get(8)); 720 } 721 if (mMatrixFlags != 0) { 722 if (mMatrixFlags == TRANSLATION) { 723 ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY); 724 } else { 725 ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", 726 indent, "ConcatMatrix", mTransformMatrix, 727 mTransformMatrix->get(0), mTransformMatrix->get(1), 728 mTransformMatrix->get(2), mTransformMatrix->get(3), 729 mTransformMatrix->get(4), mTransformMatrix->get(5), 730 mTransformMatrix->get(6), mTransformMatrix->get(7), 731 mTransformMatrix->get(8)); 732 } 733 } 734 if (mAlpha < 1 && !mCaching) { 735 // TODO: should be able to store the size of a DL at record time and not 736 // have to pass it into this call. In fact, this information might be in the 737 // location/size info that we store with the new native transform data. 738 int flags = SkCanvas::kHasAlphaLayer_SaveFlag; 739 if (mClipChildren) { 740 flags |= SkCanvas::kClipToLayer_SaveFlag; 741 } 742 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha", 743 (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop, 744 mMultipliedAlpha, flags); 745 } 746 if (mClipChildren) { 747 ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f, 748 (float) mRight - mLeft, (float) mBottom - mTop); 749 } 750 } 751 752 void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) { 753 #if DEBUG_DISPLAY_LIST 754 uint32_t count = (level + 1) * 2; 755 char indent[count + 1]; 756 for (uint32_t i = 0; i < count; i++) { 757 indent[i] = ' '; 758 } 759 indent[count] = '\0'; 760 #endif 761 updateMatrix(); 762 if (mLeft != 0 || mTop != 0) { 763 DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop); 764 renderer.translate(mLeft, mTop); 765 } 766 if (mStaticMatrix) { 767 DISPLAY_LIST_LOGD( 768 "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", 769 indent, "ConcatMatrix (static)", mStaticMatrix, 770 mStaticMatrix->get(0), mStaticMatrix->get(1), 771 mStaticMatrix->get(2), mStaticMatrix->get(3), 772 mStaticMatrix->get(4), mStaticMatrix->get(5), 773 mStaticMatrix->get(6), mStaticMatrix->get(7), 774 mStaticMatrix->get(8)); 775 renderer.concatMatrix(mStaticMatrix); 776 } else if (mAnimationMatrix) { 777 DISPLAY_LIST_LOGD( 778 "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", 779 indent, "ConcatMatrix (animation)", mAnimationMatrix, 780 mAnimationMatrix->get(0), mAnimationMatrix->get(1), 781 mAnimationMatrix->get(2), mAnimationMatrix->get(3), 782 mAnimationMatrix->get(4), mAnimationMatrix->get(5), 783 mAnimationMatrix->get(6), mAnimationMatrix->get(7), 784 mAnimationMatrix->get(8)); 785 renderer.concatMatrix(mAnimationMatrix); 786 } 787 if (mMatrixFlags != 0) { 788 if (mMatrixFlags == TRANSLATION) { 789 DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY); 790 renderer.translate(mTranslationX, mTranslationY); 791 } else { 792 DISPLAY_LIST_LOGD( 793 "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", 794 indent, "ConcatMatrix", mTransformMatrix, 795 mTransformMatrix->get(0), mTransformMatrix->get(1), 796 mTransformMatrix->get(2), mTransformMatrix->get(3), 797 mTransformMatrix->get(4), mTransformMatrix->get(5), 798 mTransformMatrix->get(6), mTransformMatrix->get(7), 799 mTransformMatrix->get(8)); 800 renderer.concatMatrix(mTransformMatrix); 801 } 802 } 803 if (mAlpha < 1 && !mCaching) { 804 if (!mHasOverlappingRendering) { 805 DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha); 806 renderer.setAlpha(mAlpha); 807 } else { 808 // TODO: should be able to store the size of a DL at record time and not 809 // have to pass it into this call. In fact, this information might be in the 810 // location/size info that we store with the new native transform data. 811 int flags = SkCanvas::kHasAlphaLayer_SaveFlag; 812 if (mClipChildren) { 813 flags |= SkCanvas::kClipToLayer_SaveFlag; 814 } 815 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha", 816 (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop, 817 mMultipliedAlpha, flags); 818 renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop, 819 mMultipliedAlpha, flags); 820 } 821 } 822 if (mClipChildren) { 823 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f, 824 (float) mRight - mLeft, (float) mBottom - mTop); 825 renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop, 826 SkRegion::kIntersect_Op); 827 } 828 } 829 830 /** 831 * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked 832 * in the output() function, since that function processes the same list of opcodes for the 833 * purposes of logging display list info for a given view. 834 */ 835 status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) { 836 status_t drawGlStatus = DrawGlInfo::kStatusDone; 837 TextContainer text; 838 mReader.rewind(); 839 840 #if DEBUG_DISPLAY_LIST 841 uint32_t count = (level + 1) * 2; 842 char indent[count + 1]; 843 for (uint32_t i = 0; i < count; i++) { 844 indent[i] = ' '; 845 } 846 indent[count] = '\0'; 847 Rect* clipRect = renderer.getClipRect(); 848 DISPLAY_LIST_LOGD("%sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f", 849 (char*) indent + 2, this, mName.string(), clipRect->left, clipRect->top, 850 clipRect->right, clipRect->bottom); 851 #endif 852 853 renderer.startMark(mName.string()); 854 int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 855 DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save", 856 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo); 857 setViewProperties(renderer, level); 858 if (renderer.quickReject(0, 0, mWidth, mHeight)) { 859 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo); 860 renderer.restoreToCount(restoreTo); 861 renderer.endMark(); 862 return drawGlStatus; 863 } 864 865 DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); 866 int saveCount = renderer.getSaveCount() - 1; 867 while (!mReader.eof()) { 868 int op = mReader.readInt(); 869 if (op & OP_MAY_BE_SKIPPED_MASK) { 870 int32_t skip = mReader.readInt(); 871 if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) { 872 mReader.skip(skip); 873 DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent, 874 OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip); 875 continue; 876 } else { 877 op &= ~OP_MAY_BE_SKIPPED_MASK; 878 } 879 } 880 logBuffer.writeCommand(level, op); 881 882 switch (op) { 883 case DrawGLFunction: { 884 Functor *functor = (Functor *) getInt(); 885 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor); 886 renderer.startMark("GL functor"); 887 drawGlStatus |= renderer.callDrawGLFunction(functor, dirty); 888 renderer.endMark(); 889 } 890 break; 891 case Save: { 892 int32_t rendererNum = getInt(); 893 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum); 894 renderer.save(rendererNum); 895 } 896 break; 897 case Restore: { 898 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 899 renderer.restore(); 900 } 901 break; 902 case RestoreToCount: { 903 int32_t restoreCount = saveCount + getInt(); 904 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount); 905 renderer.restoreToCount(restoreCount); 906 } 907 break; 908 case SaveLayer: { 909 float f1 = getFloat(); 910 float f2 = getFloat(); 911 float f3 = getFloat(); 912 float f4 = getFloat(); 913 SkPaint* paint = getPaint(renderer); 914 int32_t flags = getInt(); 915 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent, 916 OP_NAMES[op], f1, f2, f3, f4, paint, flags); 917 renderer.saveLayer(f1, f2, f3, f4, paint, flags); 918 } 919 break; 920 case SaveLayerAlpha: { 921 float f1 = getFloat(); 922 float f2 = getFloat(); 923 float f3 = getFloat(); 924 float f4 = getFloat(); 925 int32_t alpha = getInt(); 926 int32_t flags = getInt(); 927 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent, 928 OP_NAMES[op], f1, f2, f3, f4, alpha, flags); 929 renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags); 930 } 931 break; 932 case Translate: { 933 float f1 = getFloat(); 934 float f2 = getFloat(); 935 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2); 936 renderer.translate(f1, f2); 937 } 938 break; 939 case Rotate: { 940 float rotation = getFloat(); 941 DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation); 942 renderer.rotate(rotation); 943 } 944 break; 945 case Scale: { 946 float sx = getFloat(); 947 float sy = getFloat(); 948 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); 949 renderer.scale(sx, sy); 950 } 951 break; 952 case Skew: { 953 float sx = getFloat(); 954 float sy = getFloat(); 955 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy); 956 renderer.skew(sx, sy); 957 } 958 break; 959 case SetMatrix: { 960 SkMatrix* matrix = getMatrix(); 961 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix); 962 renderer.setMatrix(matrix); 963 } 964 break; 965 case ConcatMatrix: { 966 SkMatrix* matrix = getMatrix(); 967 DISPLAY_LIST_LOGD( 968 "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]", 969 (char*) indent, OP_NAMES[op], matrix, 970 matrix->get(0), matrix->get(1), matrix->get(2), 971 matrix->get(3), matrix->get(4), matrix->get(5), 972 matrix->get(6), matrix->get(7), matrix->get(8)); 973 renderer.concatMatrix(matrix); 974 } 975 break; 976 case ClipRect: { 977 float f1 = getFloat(); 978 float f2 = getFloat(); 979 float f3 = getFloat(); 980 float f4 = getFloat(); 981 int32_t regionOp = getInt(); 982 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op], 983 f1, f2, f3, f4, regionOp); 984 renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp); 985 } 986 break; 987 case DrawDisplayList: { 988 DisplayList* displayList = getDisplayList(); 989 int32_t flags = getInt(); 990 DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op], 991 displayList, mWidth, mHeight, flags, level + 1); 992 drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1); 993 } 994 break; 995 case DrawLayer: { 996 Layer* layer = (Layer*) getInt(); 997 float x = getFloat(); 998 float y = getFloat(); 999 SkPaint* paint = getPaint(renderer); 1000 if (mCaching) { 1001 paint->setAlpha(mMultipliedAlpha); 1002 } 1003 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], 1004 layer, x, y, paint); 1005 drawGlStatus |= renderer.drawLayer(layer, x, y, paint); 1006 } 1007 break; 1008 case DrawBitmap: { 1009 SkBitmap* bitmap = getBitmap(); 1010 float x = getFloat(); 1011 float y = getFloat(); 1012 SkPaint* paint = getPaint(renderer); 1013 if (mCaching) { 1014 paint->setAlpha(mMultipliedAlpha); 1015 } 1016 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], 1017 bitmap, x, y, paint); 1018 drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint); 1019 } 1020 break; 1021 case DrawBitmapMatrix: { 1022 SkBitmap* bitmap = getBitmap(); 1023 SkMatrix* matrix = getMatrix(); 1024 SkPaint* paint = getPaint(renderer); 1025 DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op], 1026 bitmap, matrix, paint); 1027 drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint); 1028 } 1029 break; 1030 case DrawBitmapRect: { 1031 SkBitmap* bitmap = getBitmap(); 1032 float f1 = getFloat(); 1033 float f2 = getFloat(); 1034 float f3 = getFloat(); 1035 float f4 = getFloat(); 1036 float f5 = getFloat(); 1037 float f6 = getFloat(); 1038 float f7 = getFloat(); 1039 float f8 = getFloat(); 1040 SkPaint* paint = getPaint(renderer); 1041 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", 1042 (char*) indent, OP_NAMES[op], bitmap, 1043 f1, f2, f3, f4, f5, f6, f7, f8,paint); 1044 drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint); 1045 } 1046 break; 1047 case DrawBitmapData: { 1048 SkBitmap* bitmap = getBitmapData(); 1049 float x = getFloat(); 1050 float y = getFloat(); 1051 SkPaint* paint = getPaint(renderer); 1052 DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], 1053 bitmap, x, y, paint); 1054 drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint); 1055 } 1056 break; 1057 case DrawBitmapMesh: { 1058 int32_t verticesCount = 0; 1059 uint32_t colorsCount = 0; 1060 1061 SkBitmap* bitmap = getBitmap(); 1062 uint32_t meshWidth = getInt(); 1063 uint32_t meshHeight = getInt(); 1064 float* vertices = getFloats(verticesCount); 1065 bool hasColors = getInt(); 1066 int32_t* colors = hasColors ? getInts(colorsCount) : NULL; 1067 SkPaint* paint = getPaint(renderer); 1068 1069 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 1070 drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, 1071 colors, paint); 1072 } 1073 break; 1074 case DrawPatch: { 1075 int32_t* xDivs = NULL; 1076 int32_t* yDivs = NULL; 1077 uint32_t* colors = NULL; 1078 uint32_t xDivsCount = 0; 1079 uint32_t yDivsCount = 0; 1080 int8_t numColors = 0; 1081 1082 SkBitmap* bitmap = getBitmap(); 1083 1084 xDivs = getInts(xDivsCount); 1085 yDivs = getInts(yDivsCount); 1086 colors = getUInts(numColors); 1087 1088 float left = getFloat(); 1089 float top = getFloat(); 1090 float right = getFloat(); 1091 float bottom = getFloat(); 1092 SkPaint* paint = getPaint(renderer); 1093 1094 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 1095 drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors, 1096 xDivsCount, yDivsCount, numColors, left, top, right, bottom, paint); 1097 } 1098 break; 1099 case DrawColor: { 1100 int32_t color = getInt(); 1101 int32_t xferMode = getInt(); 1102 DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode); 1103 drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode); 1104 } 1105 break; 1106 case DrawRect: { 1107 float f1 = getFloat(); 1108 float f2 = getFloat(); 1109 float f3 = getFloat(); 1110 float f4 = getFloat(); 1111 SkPaint* paint = getPaint(renderer); 1112 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], 1113 f1, f2, f3, f4, paint); 1114 drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint); 1115 } 1116 break; 1117 case DrawRoundRect: { 1118 float f1 = getFloat(); 1119 float f2 = getFloat(); 1120 float f3 = getFloat(); 1121 float f4 = getFloat(); 1122 float f5 = getFloat(); 1123 float f6 = getFloat(); 1124 SkPaint* paint = getPaint(renderer); 1125 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p", 1126 (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint); 1127 drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint); 1128 } 1129 break; 1130 case DrawCircle: { 1131 float f1 = getFloat(); 1132 float f2 = getFloat(); 1133 float f3 = getFloat(); 1134 SkPaint* paint = getPaint(renderer); 1135 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p", 1136 (char*) indent, OP_NAMES[op], f1, f2, f3, paint); 1137 drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint); 1138 } 1139 break; 1140 case DrawOval: { 1141 float f1 = getFloat(); 1142 float f2 = getFloat(); 1143 float f3 = getFloat(); 1144 float f4 = getFloat(); 1145 SkPaint* paint = getPaint(renderer); 1146 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", 1147 (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint); 1148 drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint); 1149 } 1150 break; 1151 case DrawArc: { 1152 float f1 = getFloat(); 1153 float f2 = getFloat(); 1154 float f3 = getFloat(); 1155 float f4 = getFloat(); 1156 float f5 = getFloat(); 1157 float f6 = getFloat(); 1158 int32_t i1 = getInt(); 1159 SkPaint* paint = getPaint(renderer); 1160 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p", 1161 (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint); 1162 drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint); 1163 } 1164 break; 1165 case DrawPath: { 1166 SkPath* path = getPath(); 1167 SkPaint* paint = getPaint(renderer); 1168 DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint); 1169 drawGlStatus |= renderer.drawPath(path, paint); 1170 } 1171 break; 1172 case DrawLines: { 1173 int32_t count = 0; 1174 float* points = getFloats(count); 1175 SkPaint* paint = getPaint(renderer); 1176 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 1177 drawGlStatus |= renderer.drawLines(points, count, paint); 1178 } 1179 break; 1180 case DrawPoints: { 1181 int32_t count = 0; 1182 float* points = getFloats(count); 1183 SkPaint* paint = getPaint(renderer); 1184 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 1185 drawGlStatus |= renderer.drawPoints(points, count, paint); 1186 } 1187 break; 1188 case DrawText: { 1189 getText(&text); 1190 int32_t count = getInt(); 1191 float x = getFloat(); 1192 float y = getFloat(); 1193 SkPaint* paint = getPaint(renderer); 1194 float length = getFloat(); 1195 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, 1196 OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length); 1197 drawGlStatus |= renderer.drawText(text.text(), text.length(), count, x, y, 1198 paint, length); 1199 } 1200 break; 1201 case DrawTextOnPath: { 1202 getText(&text); 1203 int32_t count = getInt(); 1204 SkPath* path = getPath(); 1205 float hOffset = getFloat(); 1206 float vOffset = getFloat(); 1207 SkPaint* paint = getPaint(renderer); 1208 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], 1209 text.text(), text.length(), count, paint); 1210 drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path, 1211 hOffset, vOffset, paint); 1212 } 1213 break; 1214 case DrawPosText: { 1215 getText(&text); 1216 int32_t count = getInt(); 1217 int32_t positionsCount = 0; 1218 float* positions = getFloats(positionsCount); 1219 SkPaint* paint = getPaint(renderer); 1220 DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, 1221 OP_NAMES[op], text.text(), text.length(), count, paint); 1222 drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count, 1223 positions, paint); 1224 } 1225 break; 1226 case ResetShader: { 1227 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 1228 renderer.resetShader(); 1229 } 1230 break; 1231 case SetupShader: { 1232 SkiaShader* shader = getShader(); 1233 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader); 1234 renderer.setupShader(shader); 1235 } 1236 break; 1237 case ResetColorFilter: { 1238 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 1239 renderer.resetColorFilter(); 1240 } 1241 break; 1242 case SetupColorFilter: { 1243 SkiaColorFilter *colorFilter = getColorFilter(); 1244 DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter); 1245 renderer.setupColorFilter(colorFilter); 1246 } 1247 break; 1248 case ResetShadow: { 1249 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 1250 renderer.resetShadow(); 1251 } 1252 break; 1253 case SetupShadow: { 1254 float radius = getFloat(); 1255 float dx = getFloat(); 1256 float dy = getFloat(); 1257 int32_t color = getInt(); 1258 DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op], 1259 radius, dx, dy, color); 1260 renderer.setupShadow(radius, dx, dy, color); 1261 } 1262 break; 1263 case ResetPaintFilter: { 1264 DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); 1265 renderer.resetPaintFilter(); 1266 } 1267 break; 1268 case SetupPaintFilter: { 1269 int32_t clearBits = getInt(); 1270 int32_t setBits = getInt(); 1271 DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], 1272 clearBits, setBits); 1273 renderer.setupPaintFilter(clearBits, setBits); 1274 } 1275 break; 1276 default: 1277 DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s", 1278 (char*) indent, OP_NAMES[op]); 1279 break; 1280 } 1281 } 1282 1283 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo); 1284 renderer.restoreToCount(restoreTo); 1285 renderer.endMark(); 1286 1287 DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(), 1288 drawGlStatus); 1289 return drawGlStatus; 1290 } 1291 1292 /////////////////////////////////////////////////////////////////////////////// 1293 // Base structure 1294 /////////////////////////////////////////////////////////////////////////////// 1295 1296 DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE), 1297 mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) { 1298 } 1299 1300 DisplayListRenderer::~DisplayListRenderer() { 1301 reset(); 1302 } 1303 1304 void DisplayListRenderer::reset() { 1305 mWriter.reset(); 1306 1307 Caches& caches = Caches::getInstance(); 1308 for (size_t i = 0; i < mBitmapResources.size(); i++) { 1309 caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i)); 1310 } 1311 mBitmapResources.clear(); 1312 1313 for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { 1314 SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); 1315 caches.resourceCache.decrementRefcount(bitmap); 1316 } 1317 mOwnedBitmapResources.clear(); 1318 1319 for (size_t i = 0; i < mFilterResources.size(); i++) { 1320 caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i)); 1321 } 1322 mFilterResources.clear(); 1323 1324 for (size_t i = 0; i < mShaders.size(); i++) { 1325 caches.resourceCache.decrementRefcount(mShaders.itemAt(i)); 1326 } 1327 mShaders.clear(); 1328 mShaderMap.clear(); 1329 1330 for (size_t i = 0; i < mSourcePaths.size(); i++) { 1331 caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i)); 1332 } 1333 mSourcePaths.clear(); 1334 1335 mPaints.clear(); 1336 mPaintMap.clear(); 1337 1338 mPaths.clear(); 1339 mPathMap.clear(); 1340 1341 mMatrices.clear(); 1342 1343 mHasDrawOps = false; 1344 } 1345 1346 /////////////////////////////////////////////////////////////////////////////// 1347 // Operations 1348 /////////////////////////////////////////////////////////////////////////////// 1349 1350 DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) { 1351 if (!displayList) { 1352 displayList = new DisplayList(*this); 1353 } else { 1354 displayList->initFromDisplayListRenderer(*this, true); 1355 } 1356 displayList->setRenderable(mHasDrawOps); 1357 return displayList; 1358 } 1359 1360 bool DisplayListRenderer::isDeferred() { 1361 return true; 1362 } 1363 1364 void DisplayListRenderer::setViewport(int width, int height) { 1365 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 1366 1367 mWidth = width; 1368 mHeight = height; 1369 } 1370 1371 int DisplayListRenderer::prepareDirty(float left, float top, 1372 float right, float bottom, bool opaque) { 1373 mSnapshot = new Snapshot(mFirstSnapshot, 1374 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 1375 mSaveCount = 1; 1376 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); 1377 mRestoreSaveCount = -1; 1378 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time 1379 } 1380 1381 void DisplayListRenderer::finish() { 1382 insertRestoreToCount(); 1383 insertTranlate(); 1384 } 1385 1386 void DisplayListRenderer::interrupt() { 1387 } 1388 1389 void DisplayListRenderer::resume() { 1390 } 1391 1392 status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { 1393 // Ignore dirty during recording, it matters only when we replay 1394 addOp(DisplayList::DrawGLFunction); 1395 addInt((int) functor); 1396 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time 1397 } 1398 1399 int DisplayListRenderer::save(int flags) { 1400 addOp(DisplayList::Save); 1401 addInt(flags); 1402 return OpenGLRenderer::save(flags); 1403 } 1404 1405 void DisplayListRenderer::restore() { 1406 if (mRestoreSaveCount < 0) { 1407 restoreToCount(getSaveCount() - 1); 1408 return; 1409 } 1410 1411 mRestoreSaveCount--; 1412 insertTranlate(); 1413 OpenGLRenderer::restore(); 1414 } 1415 1416 void DisplayListRenderer::restoreToCount(int saveCount) { 1417 mRestoreSaveCount = saveCount; 1418 insertTranlate(); 1419 OpenGLRenderer::restoreToCount(saveCount); 1420 } 1421 1422 int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 1423 SkPaint* p, int flags) { 1424 addOp(DisplayList::SaveLayer); 1425 addBounds(left, top, right, bottom); 1426 addPaint(p); 1427 addInt(flags); 1428 return OpenGLRenderer::save(flags); 1429 } 1430 1431 int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom, 1432 int alpha, int flags) { 1433 addOp(DisplayList::SaveLayerAlpha); 1434 addBounds(left, top, right, bottom); 1435 addInt(alpha); 1436 addInt(flags); 1437 return OpenGLRenderer::save(flags); 1438 } 1439 1440 void DisplayListRenderer::translate(float dx, float dy) { 1441 mHasTranslate = true; 1442 mTranslateX += dx; 1443 mTranslateY += dy; 1444 insertRestoreToCount(); 1445 OpenGLRenderer::translate(dx, dy); 1446 } 1447 1448 void DisplayListRenderer::rotate(float degrees) { 1449 addOp(DisplayList::Rotate); 1450 addFloat(degrees); 1451 OpenGLRenderer::rotate(degrees); 1452 } 1453 1454 void DisplayListRenderer::scale(float sx, float sy) { 1455 addOp(DisplayList::Scale); 1456 addPoint(sx, sy); 1457 OpenGLRenderer::scale(sx, sy); 1458 } 1459 1460 void DisplayListRenderer::skew(float sx, float sy) { 1461 addOp(DisplayList::Skew); 1462 addPoint(sx, sy); 1463 OpenGLRenderer::skew(sx, sy); 1464 } 1465 1466 void DisplayListRenderer::setMatrix(SkMatrix* matrix) { 1467 addOp(DisplayList::SetMatrix); 1468 addMatrix(matrix); 1469 OpenGLRenderer::setMatrix(matrix); 1470 } 1471 1472 void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { 1473 addOp(DisplayList::ConcatMatrix); 1474 addMatrix(matrix); 1475 OpenGLRenderer::concatMatrix(matrix); 1476 } 1477 1478 bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 1479 SkRegion::Op op) { 1480 addOp(DisplayList::ClipRect); 1481 addBounds(left, top, right, bottom); 1482 addInt(op); 1483 return OpenGLRenderer::clipRect(left, top, right, bottom, op); 1484 } 1485 1486 status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList, 1487 Rect& dirty, int32_t flags, uint32_t level) { 1488 // dirty is an out parameter and should not be recorded, 1489 // it matters only when replaying the display list 1490 1491 addOp(DisplayList::DrawDisplayList); 1492 addDisplayList(displayList); 1493 addInt(flags); 1494 return DrawGlInfo::kStatusDone; 1495 } 1496 1497 status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { 1498 addOp(DisplayList::DrawLayer); 1499 addInt((int) layer); 1500 addPoint(x, y); 1501 addPaint(paint); 1502 return DrawGlInfo::kStatusDone; 1503 } 1504 1505 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { 1506 const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height()); 1507 uint32_t* location = addOp(DisplayList::DrawBitmap, reject); 1508 addBitmap(bitmap); 1509 addPoint(left, top); 1510 addPaint(paint); 1511 addSkip(location); 1512 return DrawGlInfo::kStatusDone; 1513 } 1514 1515 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { 1516 Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height()); 1517 const mat4 transform(*matrix); 1518 transform.mapRect(r); 1519 1520 const bool reject = quickReject(r.left, r.top, r.right, r.bottom); 1521 uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject); 1522 addBitmap(bitmap); 1523 addMatrix(matrix); 1524 addPaint(paint); 1525 addSkip(location); 1526 return DrawGlInfo::kStatusDone; 1527 } 1528 1529 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 1530 float srcRight, float srcBottom, float dstLeft, float dstTop, 1531 float dstRight, float dstBottom, SkPaint* paint) { 1532 const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom); 1533 uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject); 1534 addBitmap(bitmap); 1535 addBounds(srcLeft, srcTop, srcRight, srcBottom); 1536 addBounds(dstLeft, dstTop, dstRight, dstBottom); 1537 addPaint(paint); 1538 addSkip(location); 1539 return DrawGlInfo::kStatusDone; 1540 } 1541 1542 status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, 1543 SkPaint* paint) { 1544 const bool reject = quickReject(left, top, left + bitmap->width(), bitmap->height()); 1545 uint32_t* location = addOp(DisplayList::DrawBitmapData, reject); 1546 addBitmapData(bitmap); 1547 addPoint(left, top); 1548 addPaint(paint); 1549 addSkip(location); 1550 return DrawGlInfo::kStatusDone; 1551 } 1552 1553 status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 1554 float* vertices, int* colors, SkPaint* paint) { 1555 addOp(DisplayList::DrawBitmapMesh); 1556 addBitmap(bitmap); 1557 addInt(meshWidth); 1558 addInt(meshHeight); 1559 addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2); 1560 if (colors) { 1561 addInt(1); 1562 addInts(colors, (meshWidth + 1) * (meshHeight + 1)); 1563 } else { 1564 addInt(0); 1565 } 1566 addPaint(paint); 1567 return DrawGlInfo::kStatusDone; 1568 } 1569 1570 status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, 1571 const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, 1572 int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) { 1573 const bool reject = quickReject(left, top, right, bottom); 1574 uint32_t* location = addOp(DisplayList::DrawPatch, reject); 1575 addBitmap(bitmap); 1576 addInts(xDivs, width); 1577 addInts(yDivs, height); 1578 addUInts(colors, numColors); 1579 addBounds(left, top, right, bottom); 1580 addPaint(paint); 1581 addSkip(location); 1582 return DrawGlInfo::kStatusDone; 1583 } 1584 1585 status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 1586 addOp(DisplayList::DrawColor); 1587 addInt(color); 1588 addInt(mode); 1589 return DrawGlInfo::kStatusDone; 1590 } 1591 1592 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 1593 SkPaint* paint) { 1594 const bool reject = paint->getStyle() == SkPaint::kFill_Style && 1595 quickReject(left, top, right, bottom); 1596 uint32_t* location = addOp(DisplayList::DrawRect, reject); 1597 addBounds(left, top, right, bottom); 1598 addPaint(paint); 1599 addSkip(location); 1600 return DrawGlInfo::kStatusDone; 1601 } 1602 1603 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, 1604 float rx, float ry, SkPaint* paint) { 1605 const bool reject = paint->getStyle() == SkPaint::kFill_Style && 1606 quickReject(left, top, right, bottom); 1607 uint32_t* location = addOp(DisplayList::DrawRoundRect, reject); 1608 addBounds(left, top, right, bottom); 1609 addPoint(rx, ry); 1610 addPaint(paint); 1611 addSkip(location); 1612 return DrawGlInfo::kStatusDone; 1613 } 1614 1615 status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { 1616 addOp(DisplayList::DrawCircle); 1617 addPoint(x, y); 1618 addFloat(radius); 1619 addPaint(paint); 1620 return DrawGlInfo::kStatusDone; 1621 } 1622 1623 status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom, 1624 SkPaint* paint) { 1625 addOp(DisplayList::DrawOval); 1626 addBounds(left, top, right, bottom); 1627 addPaint(paint); 1628 return DrawGlInfo::kStatusDone; 1629 } 1630 1631 status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom, 1632 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { 1633 addOp(DisplayList::DrawArc); 1634 addBounds(left, top, right, bottom); 1635 addPoint(startAngle, sweepAngle); 1636 addInt(useCenter ? 1 : 0); 1637 addPaint(paint); 1638 return DrawGlInfo::kStatusDone; 1639 } 1640 1641 status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { 1642 float left, top, offset; 1643 uint32_t width, height; 1644 computePathBounds(path, paint, left, top, offset, width, height); 1645 1646 const bool reject = quickReject(left - offset, top - offset, width, height); 1647 uint32_t* location = addOp(DisplayList::DrawPath, reject); 1648 addPath(path); 1649 addPaint(paint); 1650 addSkip(location); 1651 return DrawGlInfo::kStatusDone; 1652 } 1653 1654 status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { 1655 addOp(DisplayList::DrawLines); 1656 addFloats(points, count); 1657 addPaint(paint); 1658 return DrawGlInfo::kStatusDone; 1659 } 1660 1661 status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { 1662 addOp(DisplayList::DrawPoints); 1663 addFloats(points, count); 1664 addPaint(paint); 1665 return DrawGlInfo::kStatusDone; 1666 } 1667 1668 status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, 1669 float x, float y, SkPaint* paint, float length) { 1670 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 1671 1672 // TODO: We should probably make a copy of the paint instead of modifying 1673 // it; modifying the paint will change its generationID the first 1674 // time, which might impact caches. More investigation needed to 1675 // see if it matters. 1676 // If we make a copy, then drawTextDecorations() should *not* make 1677 // its own copy as it does right now. 1678 // Beware: this needs Glyph encoding (already done on the Paint constructor) 1679 paint->setAntiAlias(true); 1680 if (length < 0.0f) length = paint->measureText(text, bytesCount); 1681 1682 bool reject = false; 1683 if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) { 1684 SkPaint::FontMetrics metrics; 1685 paint->getFontMetrics(&metrics, 0.0f); 1686 reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom); 1687 } 1688 1689 uint32_t* location = addOp(DisplayList::DrawText, reject); 1690 addText(text, bytesCount); 1691 addInt(count); 1692 addPoint(x, y); 1693 addPaint(paint); 1694 addFloat(length); 1695 addSkip(location); 1696 return DrawGlInfo::kStatusDone; 1697 } 1698 1699 status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, 1700 SkPath* path, float hOffset, float vOffset, SkPaint* paint) { 1701 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 1702 addOp(DisplayList::DrawTextOnPath); 1703 addText(text, bytesCount); 1704 addInt(count); 1705 addPath(path); 1706 addFloat(hOffset); 1707 addFloat(vOffset); 1708 paint->setAntiAlias(true); 1709 addPaint(paint); 1710 return DrawGlInfo::kStatusDone; 1711 } 1712 1713 status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, 1714 const float* positions, SkPaint* paint) { 1715 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 1716 addOp(DisplayList::DrawPosText); 1717 addText(text, bytesCount); 1718 addInt(count); 1719 addFloats(positions, count * 2); 1720 paint->setAntiAlias(true); 1721 addPaint(paint); 1722 return DrawGlInfo::kStatusDone; 1723 } 1724 1725 void DisplayListRenderer::resetShader() { 1726 addOp(DisplayList::ResetShader); 1727 } 1728 1729 void DisplayListRenderer::setupShader(SkiaShader* shader) { 1730 addOp(DisplayList::SetupShader); 1731 addShader(shader); 1732 } 1733 1734 void DisplayListRenderer::resetColorFilter() { 1735 addOp(DisplayList::ResetColorFilter); 1736 } 1737 1738 void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { 1739 addOp(DisplayList::SetupColorFilter); 1740 addColorFilter(filter); 1741 } 1742 1743 void DisplayListRenderer::resetShadow() { 1744 addOp(DisplayList::ResetShadow); 1745 } 1746 1747 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { 1748 addOp(DisplayList::SetupShadow); 1749 addFloat(radius); 1750 addPoint(dx, dy); 1751 addInt(color); 1752 } 1753 1754 void DisplayListRenderer::resetPaintFilter() { 1755 addOp(DisplayList::ResetPaintFilter); 1756 } 1757 1758 void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) { 1759 addOp(DisplayList::SetupPaintFilter); 1760 addInt(clearBits); 1761 addInt(setBits); 1762 } 1763 1764 }; // namespace uirenderer 1765 }; // namespace android 1766