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