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