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