DisplayListRenderer.h revision 49c5fc0b9e850497233e189ff9dcc71a78ebe6e7
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#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 18#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 19 20#include <SkChunkAlloc.h> 21#include <SkFlattenable.h> 22#include <SkMatrix.h> 23#include <SkCamera.h> 24#include <SkPaint.h> 25#include <SkPath.h> 26#include <SkRefCnt.h> 27#include <SkTDArray.h> 28#include <SkTSearch.h> 29 30#include <cutils/compiler.h> 31 32#include "DisplayListLogBuffer.h" 33#include "OpenGLRenderer.h" 34 35namespace android { 36namespace uirenderer { 37 38/////////////////////////////////////////////////////////////////////////////// 39// Defines 40/////////////////////////////////////////////////////////////////////////////// 41 42#define MIN_WRITER_SIZE 4096 43#define OP_MAY_BE_SKIPPED_MASK 0xff000000 44 45// Debug 46#if DEBUG_DISPLAY_LIST 47 #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__) 48#else 49 #define DISPLAY_LIST_LOGD(...) 50#endif 51 52#define TRANSLATION 0x0001 53#define ROTATION 0x0002 54#define ROTATION_3D 0x0004 55#define SCALE 0x0008 56#define PIVOT 0x0010 57 58/////////////////////////////////////////////////////////////////////////////// 59// Display list 60/////////////////////////////////////////////////////////////////////////////// 61 62class DisplayListRenderer; 63 64/** 65 * Replays recorded drawing commands. 66 */ 67class DisplayList { 68public: 69 DisplayList(const DisplayListRenderer& recorder); 70 ANDROID_API ~DisplayList(); 71 72 // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file 73 // when modifying this file 74 enum Op { 75 // Non-drawing operations 76 Save = 0, 77 Restore, 78 RestoreToCount, 79 SaveLayer, 80 SaveLayerAlpha, 81 Translate, 82 Rotate, 83 Scale, 84 Skew, 85 SetMatrix, 86 ConcatMatrix, 87 ClipRect, 88 // Drawing operations 89 DrawDisplayList, 90 DrawLayer, 91 DrawBitmap, 92 DrawBitmapMatrix, 93 DrawBitmapRect, 94 DrawBitmapData, 95 DrawBitmapMesh, 96 DrawPatch, 97 DrawColor, 98 DrawRect, 99 DrawRoundRect, 100 DrawCircle, 101 DrawOval, 102 DrawArc, 103 DrawPath, 104 DrawLines, 105 DrawPoints, 106 DrawText, 107 DrawTextOnPath, 108 DrawPosText, 109 ResetShader, 110 SetupShader, 111 ResetColorFilter, 112 SetupColorFilter, 113 ResetShadow, 114 SetupShadow, 115 ResetPaintFilter, 116 SetupPaintFilter, 117 DrawGLFunction, 118 }; 119 120 // See flags defined in DisplayList.java 121 enum ReplayFlag { 122 kReplayFlag_ClipChildren = 0x1 123 }; 124 125 static const char* OP_NAMES[]; 126 127 void setViewProperties(OpenGLRenderer& renderer, uint32_t level); 128 void outputViewProperties(OpenGLRenderer& renderer, char* indent); 129 130 ANDROID_API size_t getSize(); 131 ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList); 132 ANDROID_API static void outputLogBuffer(int fd); 133 134 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); 135 136 status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0); 137 138 void output(OpenGLRenderer& renderer, uint32_t level = 0); 139 140 void setRenderable(bool renderable) { 141 mIsRenderable = renderable; 142 } 143 144 bool isRenderable() const { 145 return mIsRenderable; 146 } 147 148 void setName(const char* name) { 149 if (name) { 150 mName.setTo(name); 151 } 152 } 153 154 void setClipChildren(bool clipChildren) { 155 mClipChildren = clipChildren; 156 } 157 158 void setStaticMatrix(SkMatrix* matrix) { 159 delete mStaticMatrix; 160 mStaticMatrix = new SkMatrix(*matrix); 161 } 162 163 void setAnimationMatrix(SkMatrix* matrix) { 164 delete mAnimationMatrix; 165 if (matrix) { 166 mAnimationMatrix = new SkMatrix(*matrix); 167 } else { 168 mAnimationMatrix = NULL; 169 } 170 } 171 172 void setAlpha(float alpha) { 173 if (alpha != mAlpha) { 174 mAlpha = alpha; 175 mMultipliedAlpha = (int)(255 * alpha); 176 } 177 } 178 179 void setHasOverlappingRendering(bool hasOverlappingRendering) { 180 mHasOverlappingRendering = hasOverlappingRendering; 181 } 182 183 void setTranslationX(float translationX) { 184 if (translationX != mTranslationX) { 185 mTranslationX = translationX; 186 mMatrixDirty = true; 187 if (ALMOST_EQUAL(mTranslationX, 0) && ALMOST_EQUAL(mTranslationY, 0)) { 188 mMatrixFlags &= ~TRANSLATION; 189 } else { 190 mMatrixFlags |= TRANSLATION; 191 } 192 } 193 } 194 195 void setTranslationY(float translationY) { 196 if (translationY != mTranslationY) { 197 mTranslationY = translationY; 198 mMatrixDirty = true; 199 if (ALMOST_EQUAL(mTranslationX, 0) && ALMOST_EQUAL(mTranslationY, 0)) { 200 mMatrixFlags &= ~TRANSLATION; 201 } else { 202 mMatrixFlags |= TRANSLATION; 203 } 204 } 205 } 206 207 void setRotation(float rotation) { 208 if (rotation != mRotation) { 209 mRotation = rotation; 210 mMatrixDirty = true; 211 if (ALMOST_EQUAL(mRotation, 0)) { 212 mMatrixFlags &= ~ROTATION; 213 } else { 214 mMatrixFlags |= ROTATION; 215 } 216 } 217 } 218 219 void setRotationX(float rotationX) { 220 if (rotationX != mRotationX) { 221 mRotationX = rotationX; 222 mMatrixDirty = true; 223 if (ALMOST_EQUAL(mRotationX, 0) && ALMOST_EQUAL(mRotationY, 0)) { 224 mMatrixFlags &= ~ROTATION_3D; 225 } else { 226 mMatrixFlags |= ROTATION_3D; 227 } 228 } 229 } 230 231 void setRotationY(float rotationY) { 232 if (rotationY != mRotationY) { 233 mRotationY = rotationY; 234 mMatrixDirty = true; 235 if (ALMOST_EQUAL(mRotationX, 0) && ALMOST_EQUAL(mRotationY, 0)) { 236 mMatrixFlags &= ~ROTATION_3D; 237 } else { 238 mMatrixFlags |= ROTATION_3D; 239 } 240 } 241 } 242 243 void setScaleX(float scaleX) { 244 if (scaleX != mScaleX) { 245 mScaleX = scaleX; 246 mMatrixDirty = true; 247 if (ALMOST_EQUAL(mScaleX, 1) && ALMOST_EQUAL(mScaleY, 1)) { 248 mMatrixFlags &= ~SCALE; 249 } else { 250 mMatrixFlags |= SCALE; 251 } 252 } 253 } 254 255 void setScaleY(float scaleY) { 256 if (scaleY != mScaleY) { 257 mScaleY = scaleY; 258 mMatrixDirty = true; 259 if (mScaleX == 1.0f && mScaleY == 1.0f) { 260 mMatrixFlags &= ~SCALE; 261 } else { 262 mMatrixFlags |= SCALE; 263 } 264 } 265 } 266 267 void setPivotX(float pivotX) { 268 mPivotX = pivotX; 269 mMatrixDirty = true; 270 if (ALMOST_EQUAL(mPivotX, 0) && ALMOST_EQUAL(mPivotY, 0)) { 271 mMatrixFlags &= ~PIVOT; 272 } else { 273 mMatrixFlags |= PIVOT; 274 } 275 mPivotExplicitlySet = true; 276 } 277 278 void setPivotY(float pivotY) { 279 mPivotY = pivotY; 280 mMatrixDirty = true; 281 if (ALMOST_EQUAL(mPivotX, 0) && ALMOST_EQUAL(mPivotY, 0)) { 282 mMatrixFlags &= ~PIVOT; 283 } else { 284 mMatrixFlags |= PIVOT; 285 } 286 mPivotExplicitlySet = true; 287 } 288 289 void setCameraDistance(float distance) { 290 if (distance != mCameraDistance) { 291 mCameraDistance = distance; 292 mMatrixDirty = true; 293 if (!mTransformCamera) { 294 mTransformCamera = new Sk3DView(); 295 mTransformMatrix3D = new SkMatrix(); 296 } 297 mTransformCamera->setCameraLocation(0, 0, distance); 298 } 299 } 300 301 void setLeft(int left) { 302 if (left != mLeft) { 303 mLeft = left; 304 mWidth = mRight - mLeft; 305 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 306 mMatrixDirty = true; 307 } 308 } 309 } 310 311 void setTop(int top) { 312 if (top != mTop) { 313 mTop = top; 314 mHeight = mBottom - mTop; 315 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 316 mMatrixDirty = true; 317 } 318 } 319 } 320 321 void setRight(int right) { 322 if (right != mRight) { 323 mRight = right; 324 mWidth = mRight - mLeft; 325 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 326 mMatrixDirty = true; 327 } 328 } 329 } 330 331 void setBottom(int bottom) { 332 if (bottom != mBottom) { 333 mBottom = bottom; 334 mHeight = mBottom - mTop; 335 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 336 mMatrixDirty = true; 337 } 338 } 339 } 340 341 void setLeftTop(int left, int top) { 342 if (left != mLeft || top != mTop) { 343 mLeft = left; 344 mTop = top; 345 mWidth = mRight - mLeft; 346 mHeight = mBottom - mTop; 347 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 348 mMatrixDirty = true; 349 } 350 } 351 } 352 353 void setLeftTopRightBottom(int left, int top, int right, int bottom) { 354 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) { 355 mLeft = left; 356 mTop = top; 357 mRight = right; 358 mBottom = bottom; 359 mWidth = mRight - mLeft; 360 mHeight = mBottom - mTop; 361 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 362 mMatrixDirty = true; 363 } 364 } 365 } 366 367 void offsetLeftRight(int offset) { 368 if (offset != 0) { 369 mLeft += offset; 370 mRight += offset; 371 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 372 mMatrixDirty = true; 373 } 374 } 375 } 376 377 void offsetTopBottom(int offset) { 378 if (offset != 0) { 379 mTop += offset; 380 mBottom += offset; 381 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 382 mMatrixDirty = true; 383 } 384 } 385 } 386 387 void setCaching(bool caching) { 388 mCaching = caching; 389 } 390 391 int getWidth() { 392 return mWidth; 393 } 394 395 int getHeight() { 396 return mHeight; 397 } 398 399private: 400 void init(); 401 void initProperties(); 402 403 void clearResources(); 404 405 void updateMatrix(); 406 407 class TextContainer { 408 public: 409 size_t length() const { 410 return mByteLength; 411 } 412 413 const char* text() const { 414 return (const char*) mText; 415 } 416 417 size_t mByteLength; 418 const char* mText; 419 }; 420 421 SkBitmap* getBitmap() { 422 return (SkBitmap*) getInt(); 423 } 424 425 SkBitmap* getBitmapData() { 426 return (SkBitmap*) getInt(); 427 } 428 429 SkiaShader* getShader() { 430 return (SkiaShader*) getInt(); 431 } 432 433 SkiaColorFilter* getColorFilter() { 434 return (SkiaColorFilter*) getInt(); 435 } 436 437 inline int32_t getIndex() { 438 return mReader.readInt(); 439 } 440 441 inline int32_t getInt() { 442 return mReader.readInt(); 443 } 444 445 inline uint32_t getUInt() { 446 return mReader.readU32(); 447 } 448 449 SkMatrix* getMatrix() { 450 return (SkMatrix*) getInt(); 451 } 452 453 SkPath* getPath() { 454 return (SkPath*) getInt(); 455 } 456 457 SkPaint* getPaint(OpenGLRenderer& renderer) { 458 return renderer.filterPaint((SkPaint*) getInt()); 459 } 460 461 DisplayList* getDisplayList() { 462 return (DisplayList*) getInt(); 463 } 464 465 inline float getFloat() { 466 return mReader.readScalar(); 467 } 468 469 int32_t* getInts(uint32_t& count) { 470 count = getInt(); 471 return (int32_t*) mReader.skip(count * sizeof(int32_t)); 472 } 473 474 uint32_t* getUInts(int8_t& count) { 475 count = getInt(); 476 return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); 477 } 478 479 float* getFloats(int32_t& count) { 480 count = getInt(); 481 return (float*) mReader.skip(count * sizeof(float)); 482 } 483 484 void getText(TextContainer* text) { 485 size_t length = text->mByteLength = getInt(); 486 text->mText = (const char*) mReader.skip(length); 487 } 488 489 Vector<SkBitmap*> mBitmapResources; 490 Vector<SkBitmap*> mOwnedBitmapResources; 491 Vector<SkiaColorFilter*> mFilterResources; 492 493 Vector<SkPaint*> mPaints; 494 Vector<SkPath*> mPaths; 495 SortedVector<SkPath*> mSourcePaths; 496 Vector<SkMatrix*> mMatrices; 497 Vector<SkiaShader*> mShaders; 498 499 mutable SkFlattenableReadBuffer mReader; 500 501 size_t mSize; 502 503 bool mIsRenderable; 504 505 String8 mName; 506 507 // View properties 508 bool mClipChildren; 509 float mAlpha; 510 int mMultipliedAlpha; 511 bool mHasOverlappingRendering; 512 float mTranslationX, mTranslationY; 513 float mRotation, mRotationX, mRotationY; 514 float mScaleX, mScaleY; 515 float mPivotX, mPivotY; 516 float mCameraDistance; 517 int mLeft, mTop, mRight, mBottom; 518 int mWidth, mHeight; 519 int mPrevWidth, mPrevHeight; 520 bool mPivotExplicitlySet; 521 bool mMatrixDirty; 522 bool mMatrixIsIdentity; 523 uint32_t mMatrixFlags; 524 SkMatrix* mTransformMatrix; 525 Sk3DView* mTransformCamera; 526 SkMatrix* mTransformMatrix3D; 527 SkMatrix* mStaticMatrix; 528 SkMatrix* mAnimationMatrix; 529 bool mCaching; 530}; 531 532/////////////////////////////////////////////////////////////////////////////// 533// Renderer 534/////////////////////////////////////////////////////////////////////////////// 535 536/** 537 * Records drawing commands in a display list for latter playback. 538 */ 539class DisplayListRenderer: public OpenGLRenderer { 540public: 541 ANDROID_API DisplayListRenderer(); 542 virtual ~DisplayListRenderer(); 543 544 ANDROID_API DisplayList* getDisplayList(DisplayList* displayList); 545 546 virtual bool isDeferred(); 547 548 virtual void setViewport(int width, int height); 549 virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque); 550 virtual void finish(); 551 552 virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty); 553 554 virtual void interrupt(); 555 virtual void resume(); 556 557 virtual int save(int flags); 558 virtual void restore(); 559 virtual void restoreToCount(int saveCount); 560 561 virtual int saveLayer(float left, float top, float right, float bottom, 562 SkPaint* p, int flags); 563 virtual int saveLayerAlpha(float left, float top, float right, float bottom, 564 int alpha, int flags); 565 566 virtual void translate(float dx, float dy); 567 virtual void rotate(float degrees); 568 virtual void scale(float sx, float sy); 569 virtual void skew(float sx, float sy); 570 571 virtual void setMatrix(SkMatrix* matrix); 572 virtual void concatMatrix(SkMatrix* matrix); 573 574 virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 575 576 virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags, 577 uint32_t level = 0); 578 virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint); 579 virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); 580 virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); 581 virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 582 float srcRight, float srcBottom, float dstLeft, float dstTop, 583 float dstRight, float dstBottom, SkPaint* paint); 584 virtual void drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint); 585 virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 586 float* vertices, int* colors, SkPaint* paint); 587 virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 588 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 589 float left, float top, float right, float bottom, SkPaint* paint); 590 virtual void drawColor(int color, SkXfermode::Mode mode); 591 virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint); 592 virtual void drawRoundRect(float left, float top, float right, float bottom, 593 float rx, float ry, SkPaint* paint); 594 virtual void drawCircle(float x, float y, float radius, SkPaint* paint); 595 virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint); 596 virtual void drawArc(float left, float top, float right, float bottom, 597 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); 598 virtual void drawPath(SkPath* path, SkPaint* paint); 599 virtual void drawLines(float* points, int count, SkPaint* paint); 600 virtual void drawPoints(float* points, int count, SkPaint* paint); 601 virtual void drawText(const char* text, int bytesCount, int count, float x, float y, 602 SkPaint* paint, float length = -1.0f); 603 virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, 604 float hOffset, float vOffset, SkPaint* paint); 605 virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, 606 SkPaint* paint); 607 608 virtual void resetShader(); 609 virtual void setupShader(SkiaShader* shader); 610 611 virtual void resetColorFilter(); 612 virtual void setupColorFilter(SkiaColorFilter* filter); 613 614 virtual void resetShadow(); 615 virtual void setupShadow(float radius, float dx, float dy, int color); 616 617 virtual void resetPaintFilter(); 618 virtual void setupPaintFilter(int clearBits, int setBits); 619 620 ANDROID_API void reset(); 621 622 const SkWriter32& writeStream() const { 623 return mWriter; 624 } 625 626 const Vector<SkBitmap*>& getBitmapResources() const { 627 return mBitmapResources; 628 } 629 630 const Vector<SkBitmap*>& getOwnedBitmapResources() const { 631 return mOwnedBitmapResources; 632 } 633 634 const Vector<SkiaColorFilter*>& getFilterResources() const { 635 return mFilterResources; 636 } 637 638 const Vector<SkiaShader*>& getShaders() const { 639 return mShaders; 640 } 641 642 const Vector<SkPaint*>& getPaints() const { 643 return mPaints; 644 } 645 646 const Vector<SkPath*>& getPaths() const { 647 return mPaths; 648 } 649 650 const SortedVector<SkPath*>& getSourcePaths() const { 651 return mSourcePaths; 652 } 653 654 const Vector<SkMatrix*>& getMatrices() const { 655 return mMatrices; 656 } 657 658private: 659 void insertRestoreToCount() { 660 if (mRestoreSaveCount >= 0) { 661 mWriter.writeInt(DisplayList::RestoreToCount); 662 addInt(mRestoreSaveCount); 663 mRestoreSaveCount = -1; 664 } 665 } 666 667 void insertTranlate() { 668 if (mHasTranslate) { 669 if (mTranslateX != 0.0f || mTranslateY != 0.0f) { 670 mWriter.writeInt(DisplayList::Translate); 671 addPoint(mTranslateX, mTranslateY); 672 mTranslateX = mTranslateY = 0.0f; 673 } 674 mHasTranslate = false; 675 } 676 } 677 678 inline void addOp(const DisplayList::Op drawOp) { 679 insertRestoreToCount(); 680 insertTranlate(); 681 mWriter.writeInt(drawOp); 682 mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList; 683 } 684 685 uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) { 686 insertRestoreToCount(); 687 insertTranlate(); 688 mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList; 689 if (reject) { 690 mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp); 691 mWriter.writeInt(0xdeaddead); 692 mBufferSize = mWriter.size(); 693 return mWriter.peek32(mBufferSize - sizeof(int32_t)); 694 } 695 mWriter.writeInt(drawOp); 696 return NULL; 697 } 698 699 inline void addSkip(uint32_t* location) { 700 if (location) { 701 *location = (int32_t) (mWriter.size() - mBufferSize); 702 } 703 } 704 705 inline void addInt(int32_t value) { 706 mWriter.writeInt(value); 707 } 708 709 inline void addSize(uint32_t w, uint32_t h) { 710 mWriter.writeInt(w); 711 mWriter.writeInt(h); 712 } 713 714 void addInts(const int32_t* values, uint32_t count) { 715 mWriter.writeInt(count); 716 mWriter.write(values, count * sizeof(int32_t)); 717 } 718 719 void addUInts(const uint32_t* values, int8_t count) { 720 mWriter.writeInt(count); 721 mWriter.write(values, count * sizeof(uint32_t)); 722 } 723 724 inline void addFloat(float value) { 725 mWriter.writeScalar(value); 726 } 727 728 void addFloats(const float* values, int32_t count) { 729 mWriter.writeInt(count); 730 mWriter.write(values, count * sizeof(float)); 731 } 732 733 inline void addPoint(float x, float y) { 734 mWriter.writeScalar(x); 735 mWriter.writeScalar(y); 736 } 737 738 inline void addBounds(float left, float top, float right, float bottom) { 739 mWriter.writeScalar(left); 740 mWriter.writeScalar(top); 741 mWriter.writeScalar(right); 742 mWriter.writeScalar(bottom); 743 } 744 745 inline void addText(const void* text, size_t byteLength) { 746 mWriter.writeInt(byteLength); 747 mWriter.writePad(text, byteLength); 748 } 749 750 inline void addPath(SkPath* path) { 751 if (!path) { 752 addInt((int) NULL); 753 return; 754 } 755 756 SkPath* pathCopy = mPathMap.valueFor(path); 757 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 758 pathCopy = new SkPath(*path); 759 pathCopy->setSourcePath(path); 760 // replaceValueFor() performs an add if the entry doesn't exist 761 mPathMap.replaceValueFor(path, pathCopy); 762 mPaths.add(pathCopy); 763 } 764 if (mSourcePaths.indexOf(path) < 0) { 765 Caches::getInstance().resourceCache.incrementRefcount(path); 766 mSourcePaths.add(path); 767 } 768 769 addInt((int) pathCopy); 770 } 771 772 inline void addPaint(SkPaint* paint) { 773 if (!paint) { 774 addInt((int) NULL); 775 return; 776 } 777 778 SkPaint* paintCopy = mPaintMap.valueFor(paint); 779 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 780 paintCopy = new SkPaint(*paint); 781 // replaceValueFor() performs an add if the entry doesn't exist 782 mPaintMap.replaceValueFor(paint, paintCopy); 783 mPaints.add(paintCopy); 784 } 785 786 addInt((int) paintCopy); 787 } 788 789 inline void addDisplayList(DisplayList* displayList) { 790 // TODO: To be safe, the display list should be ref-counted in the 791 // resources cache, but we rely on the caller (UI toolkit) to 792 // do the right thing for now 793 addInt((int) displayList); 794 } 795 796 inline void addMatrix(SkMatrix* matrix) { 797 // Copying the matrix is cheap and prevents against the user changing the original 798 // matrix before the operation that uses it 799 SkMatrix* copy = new SkMatrix(*matrix); 800 addInt((int) copy); 801 mMatrices.add(copy); 802 } 803 804 inline void addBitmap(SkBitmap* bitmap) { 805 // Note that this assumes the bitmap is immutable. There are cases this won't handle 806 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 807 // contents, and drawing again. The only fix would be to always copy it the first time, 808 // which doesn't seem worth the extra cycles for this unlikely case. 809 addInt((int) bitmap); 810 mBitmapResources.add(bitmap); 811 Caches::getInstance().resourceCache.incrementRefcount(bitmap); 812 } 813 814 void addBitmapData(SkBitmap* bitmap) { 815 addInt((int) bitmap); 816 mOwnedBitmapResources.add(bitmap); 817 Caches::getInstance().resourceCache.incrementRefcount(bitmap); 818 } 819 820 inline void addShader(SkiaShader* shader) { 821 if (!shader) { 822 addInt((int) NULL); 823 return; 824 } 825 826 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 827 // TODO: We also need to handle generation ID changes in compose shaders 828 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 829 shaderCopy = shader->copy(); 830 // replaceValueFor() performs an add if the entry doesn't exist 831 mShaderMap.replaceValueFor(shader, shaderCopy); 832 mShaders.add(shaderCopy); 833 Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); 834 } 835 836 addInt((int) shaderCopy); 837 } 838 839 inline void addColorFilter(SkiaColorFilter* colorFilter) { 840 addInt((int) colorFilter); 841 mFilterResources.add(colorFilter); 842 Caches::getInstance().resourceCache.incrementRefcount(colorFilter); 843 } 844 845 Vector<SkBitmap*> mBitmapResources; 846 Vector<SkBitmap*> mOwnedBitmapResources; 847 Vector<SkiaColorFilter*> mFilterResources; 848 849 Vector<SkPaint*> mPaints; 850 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 851 852 Vector<SkPath*> mPaths; 853 DefaultKeyedVector<SkPath*, SkPath*> mPathMap; 854 855 SortedVector<SkPath*> mSourcePaths; 856 857 Vector<SkiaShader*> mShaders; 858 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 859 860 Vector<SkMatrix*> mMatrices; 861 862 SkWriter32 mWriter; 863 uint32_t mBufferSize; 864 865 int mRestoreSaveCount; 866 867 float mTranslateX; 868 float mTranslateY; 869 bool mHasTranslate; 870 871 bool mHasDrawOps; 872 873 friend class DisplayList; 874 875}; // class DisplayListRenderer 876 877}; // namespace uirenderer 878}; // namespace android 879 880#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 881