DisplayListRenderer.cpp revision 63696bfc0592a0b8808aa2b1c40bcf33c656c659
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 "DisplayListOp.h" 25#include "DisplayListRenderer.h" 26#include "Caches.h" 27 28namespace android { 29namespace uirenderer { 30 31/////////////////////////////////////////////////////////////////////////////// 32// Display list 33/////////////////////////////////////////////////////////////////////////////// 34 35void DisplayList::outputLogBuffer(int fd) { 36 DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); 37 if (logBuffer.isEmpty()) { 38 return; 39 } 40 41 FILE *file = fdopen(fd, "a"); 42 43 fprintf(file, "\nRecent DisplayList operations\n"); 44 logBuffer.outputCommands(file); 45 46 String8 cachesLog; 47 Caches::getInstance().dumpMemoryUsage(cachesLog); 48 fprintf(file, "\nCaches:\n%s", cachesLog.string()); 49 fprintf(file, "\n"); 50 51 fflush(file); 52} 53 54DisplayList::DisplayList(const DisplayListRenderer& recorder) : 55 mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL), 56 mStaticMatrix(NULL), mAnimationMatrix(NULL) { 57 58 initFromDisplayListRenderer(recorder); 59} 60 61DisplayList::~DisplayList() { 62 clearResources(); 63} 64 65void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { 66 if (displayList) { 67 DISPLAY_LIST_LOGD("Deferring display list destruction"); 68 Caches::getInstance().deleteDisplayListDeferred(displayList); 69 } 70} 71 72void DisplayList::clearResources() { 73 mDisplayListData = NULL; 74 delete mTransformMatrix; 75 delete mTransformCamera; 76 delete mTransformMatrix3D; 77 delete mStaticMatrix; 78 delete mAnimationMatrix; 79 80 mTransformMatrix = NULL; 81 mTransformCamera = NULL; 82 mTransformMatrix3D = NULL; 83 mStaticMatrix = NULL; 84 mAnimationMatrix = NULL; 85 86 Caches& caches = Caches::getInstance(); 87 caches.unregisterFunctors(mFunctorCount); 88 caches.resourceCache.lock(); 89 90 for (size_t i = 0; i < mBitmapResources.size(); i++) { 91 caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); 92 } 93 94 for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { 95 SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i); 96 caches.resourceCache.decrementRefcountLocked(bitmap); 97 caches.resourceCache.destructorLocked(bitmap); 98 } 99 100 for (size_t i = 0; i < mFilterResources.size(); i++) { 101 caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i)); 102 } 103 104 for (size_t i = 0; i < mShaders.size(); i++) { 105 caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); 106 caches.resourceCache.destructorLocked(mShaders.itemAt(i)); 107 } 108 109 for (size_t i = 0; i < mSourcePaths.size(); i++) { 110 caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); 111 } 112 113 for (size_t i = 0; i < mLayers.size(); i++) { 114 caches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i)); 115 } 116 117 caches.resourceCache.unlock(); 118 119 for (size_t i = 0; i < mPaints.size(); i++) { 120 delete mPaints.itemAt(i); 121 } 122 123 for (size_t i = 0; i < mRegions.size(); i++) { 124 delete mRegions.itemAt(i); 125 } 126 127 for (size_t i = 0; i < mPaths.size(); i++) { 128 SkPath* path = mPaths.itemAt(i); 129 caches.pathCache.remove(path); 130 delete path; 131 } 132 133 for (size_t i = 0; i < mMatrices.size(); i++) { 134 delete mMatrices.itemAt(i); 135 } 136 137 mBitmapResources.clear(); 138 mOwnedBitmapResources.clear(); 139 mFilterResources.clear(); 140 mShaders.clear(); 141 mSourcePaths.clear(); 142 mPaints.clear(); 143 mRegions.clear(); 144 mPaths.clear(); 145 mMatrices.clear(); 146 mLayers.clear(); 147} 148 149void DisplayList::reset() { 150 clearResources(); 151 init(); 152} 153 154void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) { 155 if (reusing) { 156 // re-using display list - clear out previous allocations 157 clearResources(); 158 } 159 160 init(); 161 162 mDisplayListData = recorder.getDisplayListData(); 163 mSize = mDisplayListData->allocator.usedSize(); 164 165 if (mSize == 0) { 166 return; 167 } 168 169 mFunctorCount = recorder.getFunctorCount(); 170 171 Caches& caches = Caches::getInstance(); 172 caches.registerFunctors(mFunctorCount); 173 caches.resourceCache.lock(); 174 175 const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources(); 176 for (size_t i = 0; i < bitmapResources.size(); i++) { 177 SkBitmap* resource = bitmapResources.itemAt(i); 178 mBitmapResources.add(resource); 179 caches.resourceCache.incrementRefcountLocked(resource); 180 } 181 182 const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources(); 183 for (size_t i = 0; i < ownedBitmapResources.size(); i++) { 184 SkBitmap* resource = ownedBitmapResources.itemAt(i); 185 mOwnedBitmapResources.add(resource); 186 caches.resourceCache.incrementRefcountLocked(resource); 187 } 188 189 const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources(); 190 for (size_t i = 0; i < filterResources.size(); i++) { 191 SkiaColorFilter* resource = filterResources.itemAt(i); 192 mFilterResources.add(resource); 193 caches.resourceCache.incrementRefcountLocked(resource); 194 } 195 196 const Vector<SkiaShader*>& shaders = recorder.getShaders(); 197 for (size_t i = 0; i < shaders.size(); i++) { 198 SkiaShader* resource = shaders.itemAt(i); 199 mShaders.add(resource); 200 caches.resourceCache.incrementRefcountLocked(resource); 201 } 202 203 const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths(); 204 for (size_t i = 0; i < sourcePaths.size(); i++) { 205 mSourcePaths.add(sourcePaths.itemAt(i)); 206 caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i)); 207 } 208 209 const Vector<Layer*>& layers = recorder.getLayers(); 210 for (size_t i = 0; i < layers.size(); i++) { 211 mLayers.add(layers.itemAt(i)); 212 caches.resourceCache.incrementRefcountLocked(layers.itemAt(i)); 213 } 214 215 caches.resourceCache.unlock(); 216 217 mPaints.appendVector(recorder.getPaints()); 218 mRegions.appendVector(recorder.getRegions()); 219 mPaths.appendVector(recorder.getPaths()); 220 mMatrices.appendVector(recorder.getMatrices()); 221} 222 223void DisplayList::init() { 224 mSize = 0; 225 mIsRenderable = true; 226 mFunctorCount = 0; 227 mLeft = 0; 228 mTop = 0; 229 mRight = 0; 230 mBottom = 0; 231 mClipChildren = true; 232 mAlpha = 1; 233 mMultipliedAlpha = 255; 234 mHasOverlappingRendering = true; 235 mTranslationX = 0; 236 mTranslationY = 0; 237 mRotation = 0; 238 mRotationX = 0; 239 mRotationY= 0; 240 mScaleX = 1; 241 mScaleY = 1; 242 mPivotX = 0; 243 mPivotY = 0; 244 mCameraDistance = 0; 245 mMatrixDirty = false; 246 mMatrixFlags = 0; 247 mPrevWidth = -1; 248 mPrevHeight = -1; 249 mWidth = 0; 250 mHeight = 0; 251 mPivotExplicitlySet = false; 252 mCaching = false; 253} 254 255size_t DisplayList::getSize() { 256 return mSize; 257} 258 259/** 260 * This function is a simplified version of replay(), where we simply retrieve and log the 261 * display list. This function should remain in sync with the replay() function. 262 */ 263void DisplayList::output(uint32_t level) { 264 ALOGD("%*sStart display list (%p, %s, render=%d)", level * 2, "", this, 265 mName.string(), isRenderable()); 266 267 ALOGD("%*s%s %d", level * 2, "", "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 268 outputViewProperties(level); 269 int flags = DisplayListOp::kOpLogFlag_Recurse; 270 for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { 271 mDisplayListData->displayListOps[i]->output(level, flags); 272 } 273 ALOGD("%*sDone (%p, %s)", level * 2, "", this, mName.string()); 274} 275 276void DisplayList::updateMatrix() { 277 if (mMatrixDirty) { 278 if (!mTransformMatrix) { 279 mTransformMatrix = new SkMatrix(); 280 } 281 if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) { 282 mTransformMatrix->reset(); 283 } else { 284 if (!mPivotExplicitlySet) { 285 if (mWidth != mPrevWidth || mHeight != mPrevHeight) { 286 mPrevWidth = mWidth; 287 mPrevHeight = mHeight; 288 mPivotX = mPrevWidth / 2; 289 mPivotY = mPrevHeight / 2; 290 } 291 } 292 if ((mMatrixFlags & ROTATION_3D) == 0) { 293 mTransformMatrix->setTranslate(mTranslationX, mTranslationY); 294 mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY); 295 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY); 296 } else { 297 if (!mTransformCamera) { 298 mTransformCamera = new Sk3DView(); 299 mTransformMatrix3D = new SkMatrix(); 300 } 301 mTransformMatrix->reset(); 302 mTransformCamera->save(); 303 mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY); 304 mTransformCamera->rotateX(mRotationX); 305 mTransformCamera->rotateY(mRotationY); 306 mTransformCamera->rotateZ(-mRotation); 307 mTransformCamera->getMatrix(mTransformMatrix3D); 308 mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY); 309 mTransformMatrix3D->postTranslate(mPivotX + mTranslationX, 310 mPivotY + mTranslationY); 311 mTransformMatrix->postConcat(*mTransformMatrix3D); 312 mTransformCamera->restore(); 313 } 314 } 315 mMatrixDirty = false; 316 } 317} 318 319void DisplayList::outputViewProperties(uint32_t level) { 320 updateMatrix(); 321 if (mLeft != 0 || mTop != 0) { 322 ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop); 323 } 324 if (mStaticMatrix) { 325 ALOGD("%*sConcatMatrix (static) %p: " MATRIX_STRING, 326 level * 2, "", mStaticMatrix, MATRIX_ARGS(mStaticMatrix)); 327 } 328 if (mAnimationMatrix) { 329 ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING, 330 level * 2, "", mAnimationMatrix, MATRIX_ARGS(mStaticMatrix)); 331 } 332 if (mMatrixFlags != 0) { 333 if (mMatrixFlags == TRANSLATION) { 334 ALOGD("%*sTranslate %f, %f", level * 2, "", mTranslationX, mTranslationY); 335 } else { 336 ALOGD("%*sConcatMatrix %p: " MATRIX_STRING, 337 level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix)); 338 } 339 } 340 if (mAlpha < 1 && !mCaching) { 341 if (!mHasOverlappingRendering) { 342 ALOGD("%*sSetAlpha %.2f", level * 2, "", mAlpha); 343 } else { 344 int flags = SkCanvas::kHasAlphaLayer_SaveFlag; 345 if (mClipChildren) { 346 flags |= SkCanvas::kClipToLayer_SaveFlag; 347 } 348 ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "", 349 (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop, 350 mMultipliedAlpha, flags); 351 } 352 } 353 if (mClipChildren && !mCaching) { 354 ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f, 355 (float) mRight - mLeft, (float) mBottom - mTop); 356 } 357} 358 359void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) { 360#if DEBUG_DISPLAYLIST 361 outputViewProperties(level); 362#endif 363 updateMatrix(); 364 if (mLeft != 0 || mTop != 0) { 365 renderer.translate(mLeft, mTop); 366 } 367 if (mStaticMatrix) { 368 renderer.concatMatrix(mStaticMatrix); 369 } else if (mAnimationMatrix) { 370 renderer.concatMatrix(mAnimationMatrix); 371 } 372 if (mMatrixFlags != 0) { 373 if (mMatrixFlags == TRANSLATION) { 374 renderer.translate(mTranslationX, mTranslationY); 375 } else { 376 renderer.concatMatrix(mTransformMatrix); 377 } 378 } 379 if (mAlpha < 1 && !mCaching) { 380 if (!mHasOverlappingRendering) { 381 renderer.setAlpha(mAlpha); 382 } else { 383 // TODO: should be able to store the size of a DL at record time and not 384 // have to pass it into this call. In fact, this information might be in the 385 // location/size info that we store with the new native transform data. 386 int flags = SkCanvas::kHasAlphaLayer_SaveFlag; 387 if (mClipChildren) { 388 flags |= SkCanvas::kClipToLayer_SaveFlag; 389 } 390 renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop, 391 mMultipliedAlpha, flags); 392 } 393 } 394 if (mClipChildren && !mCaching) { 395 renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop, 396 SkRegion::kIntersect_Op); 397 } 398} 399 400status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) { 401 status_t drawGlStatus = DrawGlInfo::kStatusDone; 402 403#if DEBUG_DISPLAY_LIST 404 Rect* clipRect = renderer.getClipRect(); 405 DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f", 406 (level+1)*2, "", this, mName.string(), clipRect->left, clipRect->top, 407 clipRect->right, clipRect->bottom); 408#endif 409 410 renderer.startMark(mName.string()); 411 412 int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 413 DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "", 414 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo); 415 setViewProperties(renderer, level); 416 417 if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) { 418 DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo); 419 renderer.restoreToCount(restoreTo); 420 renderer.endMark(); 421 return drawGlStatus; 422 } 423 424 DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); 425 int saveCount = renderer.getSaveCount() - 1; 426 for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { 427 DisplayListOp *op = mDisplayListData->displayListOps[i]; 428#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS 429 Caches::getInstance().eventMark(strlen(op->name()), op->name()); 430#endif 431 432 drawGlStatus |= op->replay(renderer, dirty, flags, 433 saveCount, level, mCaching, mMultipliedAlpha); 434 logBuffer.writeCommand(level, op->name()); 435 } 436 437 DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo); 438 renderer.restoreToCount(restoreTo); 439 renderer.endMark(); 440 441 DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", (level + 1) * 2, "", this, mName.string(), 442 drawGlStatus); 443 return drawGlStatus; 444} 445 446/////////////////////////////////////////////////////////////////////////////// 447// Base structure 448/////////////////////////////////////////////////////////////////////////////// 449 450DisplayListRenderer::DisplayListRenderer(): 451 mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData), 452 mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), 453 mHasDrawOps(false), mFunctorCount(0) { 454} 455 456DisplayListRenderer::~DisplayListRenderer() { 457 reset(); 458} 459 460void DisplayListRenderer::reset() { 461 mDisplayListData = new DisplayListData(); 462 mCaches.resourceCache.lock(); 463 464 for (size_t i = 0; i < mBitmapResources.size(); i++) { 465 mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i)); 466 } 467 468 for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) { 469 mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i)); 470 } 471 472 for (size_t i = 0; i < mFilterResources.size(); i++) { 473 mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i)); 474 } 475 476 for (size_t i = 0; i < mShaders.size(); i++) { 477 mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i)); 478 } 479 480 for (size_t i = 0; i < mSourcePaths.size(); i++) { 481 mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i)); 482 } 483 484 for (size_t i = 0; i < mLayers.size(); i++) { 485 mCaches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i)); 486 } 487 488 mCaches.resourceCache.unlock(); 489 490 mBitmapResources.clear(); 491 mOwnedBitmapResources.clear(); 492 mFilterResources.clear(); 493 mSourcePaths.clear(); 494 495 mShaders.clear(); 496 mShaderMap.clear(); 497 498 mPaints.clear(); 499 mPaintMap.clear(); 500 501 mRegions.clear(); 502 mRegionMap.clear(); 503 504 mPaths.clear(); 505 mPathMap.clear(); 506 507 mMatrices.clear(); 508 509 mLayers.clear(); 510 511 mHasDrawOps = false; 512 mFunctorCount = 0; 513} 514 515/////////////////////////////////////////////////////////////////////////////// 516// Operations 517/////////////////////////////////////////////////////////////////////////////// 518 519DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) { 520 if (!displayList) { 521 displayList = new DisplayList(*this); 522 } else { 523 displayList->initFromDisplayListRenderer(*this, true); 524 } 525 displayList->setRenderable(mHasDrawOps); 526 return displayList; 527} 528 529bool DisplayListRenderer::isDeferred() { 530 return true; 531} 532 533void DisplayListRenderer::setViewport(int width, int height) { 534 mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); 535 536 mWidth = width; 537 mHeight = height; 538} 539 540status_t DisplayListRenderer::prepareDirty(float left, float top, 541 float right, float bottom, bool opaque) { 542 mSnapshot = new Snapshot(mFirstSnapshot, 543 SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); 544 mSaveCount = 1; 545 546 mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight); 547 mDirtyClip = opaque; 548 549 mRestoreSaveCount = -1; 550 551 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time 552} 553 554void DisplayListRenderer::finish() { 555 insertRestoreToCount(); 556 insertTranslate(); 557} 558 559void DisplayListRenderer::interrupt() { 560} 561 562void DisplayListRenderer::resume() { 563} 564 565status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { 566 // Ignore dirty during recording, it matters only when we replay 567 addDrawOp(new (alloc()) DrawFunctorOp(functor)); 568 mFunctorCount++; 569 return DrawGlInfo::kStatusDone; // No invalidate needed at record-time 570} 571 572int DisplayListRenderer::save(int flags) { 573 addStateOp(new (alloc()) SaveOp(flags)); 574 return OpenGLRenderer::save(flags); 575} 576 577void DisplayListRenderer::restore() { 578 if (mRestoreSaveCount < 0) { 579 restoreToCount(getSaveCount() - 1); 580 return; 581 } 582 583 mRestoreSaveCount--; 584 insertTranslate(); 585 OpenGLRenderer::restore(); 586} 587 588void DisplayListRenderer::restoreToCount(int saveCount) { 589 mRestoreSaveCount = saveCount; 590 insertTranslate(); 591 OpenGLRenderer::restoreToCount(saveCount); 592} 593 594int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, 595 SkPaint* p, int flags) { 596 addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, p, flags)); 597 return OpenGLRenderer::save(flags); 598} 599 600int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom, 601 int alpha, int flags) { 602 addStateOp(new (alloc()) SaveLayerAlphaOp(left, top, right, bottom, alpha, flags)); 603 return OpenGLRenderer::save(flags); 604} 605 606void DisplayListRenderer::translate(float dx, float dy) { 607 mHasTranslate = true; 608 mTranslateX += dx; 609 mTranslateY += dy; 610 insertRestoreToCount(); 611 OpenGLRenderer::translate(dx, dy); 612} 613 614void DisplayListRenderer::rotate(float degrees) { 615 addStateOp(new (alloc()) RotateOp(degrees)); 616 OpenGLRenderer::rotate(degrees); 617} 618 619void DisplayListRenderer::scale(float sx, float sy) { 620 addStateOp(new (alloc()) ScaleOp(sx, sy)); 621 OpenGLRenderer::scale(sx, sy); 622} 623 624void DisplayListRenderer::skew(float sx, float sy) { 625 addStateOp(new (alloc()) SkewOp(sx, sy)); 626 OpenGLRenderer::skew(sx, sy); 627} 628 629void DisplayListRenderer::setMatrix(SkMatrix* matrix) { 630 matrix = refMatrix(matrix); 631 addStateOp(new (alloc()) SetMatrixOp(matrix)); 632 OpenGLRenderer::setMatrix(matrix); 633} 634 635void DisplayListRenderer::concatMatrix(SkMatrix* matrix) { 636 matrix = refMatrix(matrix); 637 addStateOp(new (alloc()) ConcatMatrixOp(matrix)); 638 OpenGLRenderer::concatMatrix(matrix); 639} 640 641bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom, 642 SkRegion::Op op) { 643 addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op)); 644 return OpenGLRenderer::clipRect(left, top, right, bottom, op); 645} 646 647bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) { 648 path = refPath(path); 649 addStateOp(new (alloc()) ClipPathOp(path, op)); 650 return OpenGLRenderer::clipPath(path, op); 651} 652 653bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) { 654 region = refRegion(region); 655 addStateOp(new (alloc()) ClipRegionOp(region, op)); 656 return OpenGLRenderer::clipRegion(region, op); 657} 658 659status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList, 660 Rect& dirty, int32_t flags, uint32_t level) { 661 // dirty is an out parameter and should not be recorded, 662 // it matters only when replaying the display list 663 664 // TODO: To be safe, the display list should be ref-counted in the 665 // resources cache, but we rely on the caller (UI toolkit) to 666 // do the right thing for now 667 668 addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags)); 669 return DrawGlInfo::kStatusDone; 670} 671 672status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { 673 mLayers.add(layer); 674 mCaches.resourceCache.incrementRefcount(layer); 675 paint = refPaint(paint); 676 677 addDrawOp(new (alloc()) DrawLayerOp(layer, x, y, paint)); 678 return DrawGlInfo::kStatusDone; 679} 680 681status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { 682 bitmap = refBitmap(bitmap); 683 paint = refPaint(paint); 684 685 addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint)); 686 return DrawGlInfo::kStatusDone; 687} 688 689status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { 690 bitmap = refBitmap(bitmap); 691 matrix = refMatrix(matrix); 692 paint = refPaint(paint); 693 694 addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint)); 695 return DrawGlInfo::kStatusDone; 696} 697 698status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 699 float srcRight, float srcBottom, float dstLeft, float dstTop, 700 float dstRight, float dstBottom, SkPaint* paint) { 701 bitmap = refBitmap(bitmap); 702 paint = refPaint(paint); 703 704 addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap, 705 srcLeft, srcTop, srcRight, srcBottom, 706 dstLeft, dstTop, dstRight, dstBottom, paint)); 707 return DrawGlInfo::kStatusDone; 708} 709 710status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, 711 SkPaint* paint) { 712 bitmap = refBitmapData(bitmap); 713 paint = refPaint(paint); 714 715 addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint)); 716 return DrawGlInfo::kStatusDone; 717} 718 719status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 720 float* vertices, int* colors, SkPaint* paint) { 721 int count = (meshWidth + 1) * (meshHeight + 1) * 2; 722 bitmap = refBitmap(bitmap); 723 vertices = refBuffer<float>(vertices, count); 724 paint = refPaint(paint); 725 colors = refBuffer<int>(colors, count); 726 727 addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight, 728 vertices, colors, paint)); 729 return DrawGlInfo::kStatusDone; 730} 731 732status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, 733 const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, 734 int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) { 735 int alpha; 736 SkXfermode::Mode mode; 737 OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode); 738 739 bitmap = refBitmap(bitmap); 740 xDivs = refBuffer<int>(xDivs, width); 741 yDivs = refBuffer<int>(yDivs, height); 742 colors = refBuffer<uint32_t>(colors, numColors); 743 744 addDrawOp(new (alloc()) DrawPatchOp(bitmap, xDivs, yDivs, colors, width, height, numColors, 745 left, top, right, bottom, alpha, mode)); 746 return DrawGlInfo::kStatusDone; 747} 748 749status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 750 addDrawOp(new (alloc()) DrawColorOp(color, mode)); 751 return DrawGlInfo::kStatusDone; 752} 753 754status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom, 755 SkPaint* paint) { 756 paint = refPaint(paint); 757 addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint)); 758 return DrawGlInfo::kStatusDone; 759} 760 761status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, 762 float rx, float ry, SkPaint* paint) { 763 paint = refPaint(paint); 764 addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint)); 765 return DrawGlInfo::kStatusDone; 766} 767 768status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { 769 paint = refPaint(paint); 770 addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint)); 771 return DrawGlInfo::kStatusDone; 772} 773 774status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom, 775 SkPaint* paint) { 776 paint = refPaint(paint); 777 addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint)); 778 return DrawGlInfo::kStatusDone; 779} 780 781status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom, 782 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { 783 paint = refPaint(paint); 784 addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom, 785 startAngle, sweepAngle, useCenter, paint)); 786 return DrawGlInfo::kStatusDone; 787} 788 789status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { 790 path = refPath(path); 791 paint = refPaint(paint); 792 793 addDrawOp(new (alloc()) DrawPathOp(path, paint)); 794 return DrawGlInfo::kStatusDone; 795} 796 797status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { 798 points = refBuffer<float>(points, count); 799 paint = refPaint(paint); 800 801 addDrawOp(new (alloc()) DrawLinesOp(points, count, paint)); 802 return DrawGlInfo::kStatusDone; 803} 804 805status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { 806 points = refBuffer<float>(points, count); 807 paint = refPaint(paint); 808 809 addDrawOp(new (alloc()) DrawPointsOp(points, count, paint)); 810 return DrawGlInfo::kStatusDone; 811} 812 813status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, 814 SkPath* path, float hOffset, float vOffset, SkPaint* paint) { 815 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 816 817 text = refText(text, bytesCount); 818 path = refPath(path); 819 paint = refPaint(paint); 820 821 DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path, 822 hOffset, vOffset, paint); 823 if (addDrawOp(op)) { 824 // precache if draw operation is visible 825 FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); 826 fontRenderer.precache(paint, text, count, *mSnapshot->transform); 827 } 828 return DrawGlInfo::kStatusDone; 829} 830 831status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, 832 const float* positions, SkPaint* paint) { 833 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 834 835 text = refText(text, bytesCount); 836 positions = refBuffer<float>(positions, count * 2); 837 paint = refPaint(paint); 838 839 DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint); 840 if (addDrawOp(op)) { 841 // precache if draw operation is visible 842 FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); 843 fontRenderer.precache(paint, text, count, *mSnapshot->transform); 844 } 845 return DrawGlInfo::kStatusDone; 846} 847 848status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count, 849 float x, float y, const float* positions, SkPaint* paint, float length) { 850 if (!text || count <= 0) return DrawGlInfo::kStatusDone; 851 852 if (length < 0.0f) length = paint->measureText(text, bytesCount); 853 854 text = refText(text, bytesCount); 855 positions = refBuffer<float>(positions, count * 2); 856 paint = refPaint(paint); 857 858 DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length); 859 if (addDrawOp(op)) { 860 // precache if draw operation is visible 861 FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); 862 fontRenderer.precache(paint, text, count, *mSnapshot->transform); 863 } 864 return DrawGlInfo::kStatusDone; 865} 866 867status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) { 868 if (count <= 0) return DrawGlInfo::kStatusDone; 869 870 rects = refBuffer<float>(rects, count); 871 paint = refPaint(paint); 872 addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint)); 873 return DrawGlInfo::kStatusDone; 874} 875 876void DisplayListRenderer::resetShader() { 877 addStateOp(new (alloc()) ResetShaderOp()); 878} 879 880void DisplayListRenderer::setupShader(SkiaShader* shader) { 881 shader = refShader(shader); 882 addStateOp(new (alloc()) SetupShaderOp(shader)); 883} 884 885void DisplayListRenderer::resetColorFilter() { 886 addStateOp(new (alloc()) ResetColorFilterOp()); 887} 888 889void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) { 890 filter = refColorFilter(filter); 891 addStateOp(new (alloc()) SetupColorFilterOp(filter)); 892} 893 894void DisplayListRenderer::resetShadow() { 895 addStateOp(new (alloc()) ResetShadowOp()); 896} 897 898void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) { 899 addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color)); 900} 901 902void DisplayListRenderer::resetPaintFilter() { 903 addStateOp(new (alloc()) ResetPaintFilterOp()); 904} 905 906void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) { 907 addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits)); 908} 909 910void DisplayListRenderer::insertRestoreToCount() { 911 if (mRestoreSaveCount >= 0) { 912 DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount); 913 mDisplayListData->displayListOps.add(op); 914 mRestoreSaveCount = -1; 915 } 916} 917 918void DisplayListRenderer::insertTranslate() { 919 if (mHasTranslate) { 920 if (mTranslateX != 0.0f || mTranslateY != 0.0f) { 921 DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY); 922 mDisplayListData->displayListOps.add(op); 923 mTranslateX = mTranslateY = 0.0f; 924 } 925 mHasTranslate = false; 926 } 927} 928 929void DisplayListRenderer::addStateOp(StateOp* op) { 930 addOpInternal(op); 931} 932 933bool DisplayListRenderer::addDrawOp(DrawOp* op) { 934 bool rejected = false; 935 Rect localBounds; 936 if (op->getLocalBounds(localBounds)) { 937 rejected = quickRejectNoScissor(localBounds.left, localBounds.top, 938 localBounds.right, localBounds.bottom); 939 op->setQuickRejected(rejected); 940 } 941 mHasDrawOps = true; 942 addOpInternal(op); 943 return !rejected; 944} 945 946}; // namespace uirenderer 947}; // namespace android 948