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