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