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