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