DisplayListCanvas.h revision 2af4635e4a9e448a65ff541252f8f94bc6ac48e0
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#include "utils/LinearAllocator.h" 35 36namespace android { 37namespace uirenderer { 38 39/////////////////////////////////////////////////////////////////////////////// 40// Defines 41/////////////////////////////////////////////////////////////////////////////// 42 43#define MIN_WRITER_SIZE 4096 44#define OP_MAY_BE_SKIPPED_MASK 0xff000000 45 46// Debug 47#if DEBUG_DISPLAY_LIST 48 #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__) 49#else 50 #define DISPLAY_LIST_LOGD(...) 51#endif 52 53#define TRANSLATION 0x0001 54#define ROTATION 0x0002 55#define ROTATION_3D 0x0004 56#define SCALE 0x0008 57#define PIVOT 0x0010 58 59/////////////////////////////////////////////////////////////////////////////// 60// Display list 61/////////////////////////////////////////////////////////////////////////////// 62 63class DisplayListRenderer; 64class DisplayListOp; 65class DrawOp; 66class StateOp; 67 68/** 69 * Refcounted structure that holds data used in display list stream 70 */ 71class DisplayListData: public LightRefBase<DisplayListData> { 72public: 73 LinearAllocator allocator; 74 Vector<DisplayListOp*> displayListOps; 75}; 76 77/** 78 * Replays recorded drawing commands. 79 */ 80class DisplayList { 81public: 82 DisplayList(const DisplayListRenderer& recorder); 83 ANDROID_API ~DisplayList(); 84 85 // See flags defined in DisplayList.java 86 enum ReplayFlag { 87 kReplayFlag_ClipChildren = 0x1 88 }; 89 90 void setViewProperties(OpenGLRenderer& renderer, uint32_t level); 91 void outputViewProperties(uint32_t level); 92 93 ANDROID_API size_t getSize(); 94 ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList); 95 ANDROID_API static void outputLogBuffer(int fd); 96 97 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); 98 99 status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0); 100 101 void output(uint32_t level = 0); 102 103 ANDROID_API void reset(); 104 105 void setRenderable(bool renderable) { 106 mIsRenderable = renderable; 107 } 108 109 bool isRenderable() const { 110 return mIsRenderable; 111 } 112 113 void setName(const char* name) { 114 if (name) { 115 mName.setTo(name); 116 } 117 } 118 119 void setClipChildren(bool clipChildren) { 120 mClipChildren = clipChildren; 121 } 122 123 void setStaticMatrix(SkMatrix* matrix) { 124 delete mStaticMatrix; 125 mStaticMatrix = new SkMatrix(*matrix); 126 } 127 128 void setAnimationMatrix(SkMatrix* matrix) { 129 delete mAnimationMatrix; 130 if (matrix) { 131 mAnimationMatrix = new SkMatrix(*matrix); 132 } else { 133 mAnimationMatrix = NULL; 134 } 135 } 136 137 void setAlpha(float alpha) { 138 alpha = fminf(1.0f, fmaxf(0.0f, alpha)); 139 if (alpha != mAlpha) { 140 mAlpha = alpha; 141 mMultipliedAlpha = (int) (255 * alpha); 142 } 143 } 144 145 void setHasOverlappingRendering(bool hasOverlappingRendering) { 146 mHasOverlappingRendering = hasOverlappingRendering; 147 } 148 149 void setTranslationX(float translationX) { 150 if (translationX != mTranslationX) { 151 mTranslationX = translationX; 152 mMatrixDirty = true; 153 if (mTranslationX == 0.0f && mTranslationY == 0.0f) { 154 mMatrixFlags &= ~TRANSLATION; 155 } else { 156 mMatrixFlags |= TRANSLATION; 157 } 158 } 159 } 160 161 void setTranslationY(float translationY) { 162 if (translationY != mTranslationY) { 163 mTranslationY = translationY; 164 mMatrixDirty = true; 165 if (mTranslationX == 0.0f && mTranslationY == 0.0f) { 166 mMatrixFlags &= ~TRANSLATION; 167 } else { 168 mMatrixFlags |= TRANSLATION; 169 } 170 } 171 } 172 173 void setRotation(float rotation) { 174 if (rotation != mRotation) { 175 mRotation = rotation; 176 mMatrixDirty = true; 177 if (mRotation == 0.0f) { 178 mMatrixFlags &= ~ROTATION; 179 } else { 180 mMatrixFlags |= ROTATION; 181 } 182 } 183 } 184 185 void setRotationX(float rotationX) { 186 if (rotationX != mRotationX) { 187 mRotationX = rotationX; 188 mMatrixDirty = true; 189 if (mRotationX == 0.0f && mRotationY == 0.0f) { 190 mMatrixFlags &= ~ROTATION_3D; 191 } else { 192 mMatrixFlags |= ROTATION_3D; 193 } 194 } 195 } 196 197 void setRotationY(float rotationY) { 198 if (rotationY != mRotationY) { 199 mRotationY = rotationY; 200 mMatrixDirty = true; 201 if (mRotationX == 0.0f && mRotationY == 0.0f) { 202 mMatrixFlags &= ~ROTATION_3D; 203 } else { 204 mMatrixFlags |= ROTATION_3D; 205 } 206 } 207 } 208 209 void setScaleX(float scaleX) { 210 if (scaleX != mScaleX) { 211 mScaleX = scaleX; 212 mMatrixDirty = true; 213 if (mScaleX == 1.0f && mScaleY == 1.0f) { 214 mMatrixFlags &= ~SCALE; 215 } else { 216 mMatrixFlags |= SCALE; 217 } 218 } 219 } 220 221 void setScaleY(float scaleY) { 222 if (scaleY != mScaleY) { 223 mScaleY = scaleY; 224 mMatrixDirty = true; 225 if (mScaleX == 1.0f && mScaleY == 1.0f) { 226 mMatrixFlags &= ~SCALE; 227 } else { 228 mMatrixFlags |= SCALE; 229 } 230 } 231 } 232 233 void setPivotX(float pivotX) { 234 mPivotX = pivotX; 235 mMatrixDirty = true; 236 if (mPivotX == 0.0f && mPivotY == 0.0f) { 237 mMatrixFlags &= ~PIVOT; 238 } else { 239 mMatrixFlags |= PIVOT; 240 } 241 mPivotExplicitlySet = true; 242 } 243 244 void setPivotY(float pivotY) { 245 mPivotY = pivotY; 246 mMatrixDirty = true; 247 if (mPivotX == 0.0f && mPivotY == 0.0f) { 248 mMatrixFlags &= ~PIVOT; 249 } else { 250 mMatrixFlags |= PIVOT; 251 } 252 mPivotExplicitlySet = true; 253 } 254 255 void setCameraDistance(float distance) { 256 if (distance != mCameraDistance) { 257 mCameraDistance = distance; 258 mMatrixDirty = true; 259 if (!mTransformCamera) { 260 mTransformCamera = new Sk3DView(); 261 mTransformMatrix3D = new SkMatrix(); 262 } 263 mTransformCamera->setCameraLocation(0, 0, distance); 264 } 265 } 266 267 void setLeft(int left) { 268 if (left != mLeft) { 269 mLeft = left; 270 mWidth = mRight - mLeft; 271 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 272 mMatrixDirty = true; 273 } 274 } 275 } 276 277 void setTop(int top) { 278 if (top != mTop) { 279 mTop = top; 280 mHeight = mBottom - mTop; 281 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 282 mMatrixDirty = true; 283 } 284 } 285 } 286 287 void setRight(int right) { 288 if (right != mRight) { 289 mRight = right; 290 mWidth = mRight - mLeft; 291 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 292 mMatrixDirty = true; 293 } 294 } 295 } 296 297 void setBottom(int bottom) { 298 if (bottom != mBottom) { 299 mBottom = bottom; 300 mHeight = mBottom - mTop; 301 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 302 mMatrixDirty = true; 303 } 304 } 305 } 306 307 void setLeftTop(int left, int top) { 308 if (left != mLeft || top != mTop) { 309 mLeft = left; 310 mTop = top; 311 mWidth = mRight - mLeft; 312 mHeight = mBottom - mTop; 313 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 314 mMatrixDirty = true; 315 } 316 } 317 } 318 319 void setLeftTopRightBottom(int left, int top, int right, int bottom) { 320 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) { 321 mLeft = left; 322 mTop = top; 323 mRight = right; 324 mBottom = bottom; 325 mWidth = mRight - mLeft; 326 mHeight = mBottom - mTop; 327 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 328 mMatrixDirty = true; 329 } 330 } 331 } 332 333 void offsetLeftRight(int offset) { 334 if (offset != 0) { 335 mLeft += offset; 336 mRight += offset; 337 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 338 mMatrixDirty = true; 339 } 340 } 341 } 342 343 void offsetTopBottom(int offset) { 344 if (offset != 0) { 345 mTop += offset; 346 mBottom += offset; 347 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 348 mMatrixDirty = true; 349 } 350 } 351 } 352 353 void setCaching(bool caching) { 354 mCaching = caching; 355 } 356 357 int getWidth() { 358 return mWidth; 359 } 360 361 int getHeight() { 362 return mHeight; 363 } 364 365private: 366 void init(); 367 368 void clearResources(); 369 370 void updateMatrix(); 371 372 class TextContainer { 373 public: 374 size_t length() const { 375 return mByteLength; 376 } 377 378 const char* text() const { 379 return (const char*) mText; 380 } 381 382 size_t mByteLength; 383 const char* mText; 384 }; 385 386 Vector<SkBitmap*> mBitmapResources; 387 Vector<SkBitmap*> mOwnedBitmapResources; 388 Vector<SkiaColorFilter*> mFilterResources; 389 390 Vector<SkPaint*> mPaints; 391 Vector<SkPath*> mPaths; 392 SortedVector<SkPath*> mSourcePaths; 393 Vector<SkRegion*> mRegions; 394 Vector<SkMatrix*> mMatrices; 395 Vector<SkiaShader*> mShaders; 396 Vector<Layer*> mLayers; 397 398 sp<DisplayListData> mDisplayListData; 399 400 size_t mSize; 401 402 bool mIsRenderable; 403 uint32_t mFunctorCount; 404 405 String8 mName; 406 407 // View properties 408 bool mClipChildren; 409 float mAlpha; 410 int mMultipliedAlpha; 411 bool mHasOverlappingRendering; 412 float mTranslationX, mTranslationY; 413 float mRotation, mRotationX, mRotationY; 414 float mScaleX, mScaleY; 415 float mPivotX, mPivotY; 416 float mCameraDistance; 417 int mLeft, mTop, mRight, mBottom; 418 int mWidth, mHeight; 419 int mPrevWidth, mPrevHeight; 420 bool mPivotExplicitlySet; 421 bool mMatrixDirty; 422 bool mMatrixIsIdentity; 423 uint32_t mMatrixFlags; 424 SkMatrix* mTransformMatrix; 425 Sk3DView* mTransformCamera; 426 SkMatrix* mTransformMatrix3D; 427 SkMatrix* mStaticMatrix; 428 SkMatrix* mAnimationMatrix; 429 bool mCaching; 430}; 431 432/////////////////////////////////////////////////////////////////////////////// 433// Renderer 434/////////////////////////////////////////////////////////////////////////////// 435 436/** 437 * Records drawing commands in a display list for latter playback. 438 */ 439class DisplayListRenderer: public OpenGLRenderer { 440public: 441 ANDROID_API DisplayListRenderer(); 442 virtual ~DisplayListRenderer(); 443 444 ANDROID_API DisplayList* getDisplayList(DisplayList* displayList); 445 446 virtual bool isDeferred(); 447 448 virtual void setViewport(int width, int height); 449 virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque); 450 virtual void finish(); 451 452 virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty); 453 454 virtual void interrupt(); 455 virtual void resume(); 456 457 virtual int save(int flags); 458 virtual void restore(); 459 virtual void restoreToCount(int saveCount); 460 461 virtual int saveLayer(float left, float top, float right, float bottom, 462 SkPaint* p, int flags); 463 virtual int saveLayerAlpha(float left, float top, float right, float bottom, 464 int alpha, int flags); 465 466 virtual void translate(float dx, float dy); 467 virtual void rotate(float degrees); 468 virtual void scale(float sx, float sy); 469 virtual void skew(float sx, float sy); 470 471 virtual void setMatrix(SkMatrix* matrix); 472 virtual void concatMatrix(SkMatrix* matrix); 473 474 virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op); 475 virtual bool clipPath(SkPath* path, SkRegion::Op op); 476 virtual bool clipRegion(SkRegion* region, SkRegion::Op op); 477 478 virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags, 479 uint32_t level = 0); 480 virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint); 481 virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); 482 virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); 483 virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, 484 float srcRight, float srcBottom, float dstLeft, float dstTop, 485 float dstRight, float dstBottom, SkPaint* paint); 486 virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint); 487 virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, 488 float* vertices, int* colors, SkPaint* paint); 489 virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, 490 const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, 491 float left, float top, float right, float bottom, SkPaint* paint); 492 virtual status_t drawColor(int color, SkXfermode::Mode mode); 493 virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint); 494 virtual status_t drawRoundRect(float left, float top, float right, float bottom, 495 float rx, float ry, SkPaint* paint); 496 virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint); 497 virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint); 498 virtual status_t drawArc(float left, float top, float right, float bottom, 499 float startAngle, float sweepAngle, bool useCenter, SkPaint* paint); 500 virtual status_t drawPath(SkPath* path, SkPaint* paint); 501 virtual status_t drawLines(float* points, int count, SkPaint* paint); 502 virtual status_t drawPoints(float* points, int count, SkPaint* paint); 503 virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, 504 float hOffset, float vOffset, SkPaint* paint); 505 virtual status_t drawPosText(const char* text, int bytesCount, int count, 506 const float* positions, SkPaint* paint); 507 virtual status_t drawText(const char* text, int bytesCount, int count, 508 float x, float y, const float* positions, SkPaint* paint, float length); 509 virtual status_t drawRects(const float* rects, int count, SkPaint* paint); 510 511 virtual void resetShader(); 512 virtual void setupShader(SkiaShader* shader); 513 514 virtual void resetColorFilter(); 515 virtual void setupColorFilter(SkiaColorFilter* filter); 516 517 virtual void resetShadow(); 518 virtual void setupShadow(float radius, float dx, float dy, int color); 519 520 virtual void resetPaintFilter(); 521 virtual void setupPaintFilter(int clearBits, int setBits); 522 523 ANDROID_API void reset(); 524 525 sp<DisplayListData> getDisplayListData() const { 526 return mDisplayListData; 527 } 528 529 const Vector<SkBitmap*>& getBitmapResources() const { 530 return mBitmapResources; 531 } 532 533 const Vector<SkBitmap*>& getOwnedBitmapResources() const { 534 return mOwnedBitmapResources; 535 } 536 537 const Vector<SkiaColorFilter*>& getFilterResources() const { 538 return mFilterResources; 539 } 540 541 const Vector<SkiaShader*>& getShaders() const { 542 return mShaders; 543 } 544 545 const Vector<SkPaint*>& getPaints() const { 546 return mPaints; 547 } 548 549 const Vector<SkPath*>& getPaths() const { 550 return mPaths; 551 } 552 553 const SortedVector<SkPath*>& getSourcePaths() const { 554 return mSourcePaths; 555 } 556 557 const Vector<SkRegion*>& getRegions() const { 558 return mRegions; 559 } 560 561 const Vector<Layer*>& getLayers() const { 562 return mLayers; 563 } 564 565 const Vector<SkMatrix*>& getMatrices() const { 566 return mMatrices; 567 } 568 569 uint32_t getFunctorCount() const { 570 return mFunctorCount; 571 } 572 573private: 574 void insertRestoreToCount(); 575 void insertTranslate(); 576 577 LinearAllocator& alloc() { return mDisplayListData->allocator; } 578 void addStateOp(StateOp* op); 579 bool addDrawOp(DrawOp* op); // returns true if op not rejected 580 void addOpInternal(DisplayListOp* op) { 581 insertRestoreToCount(); 582 insertTranslate(); 583 mDisplayListData->displayListOps.add(op); 584 } 585 586 template<class T> 587 inline T* refBuffer(const T* srcBuffer, int32_t count) { 588 if (srcBuffer == NULL) return NULL; 589 T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T)); 590 memcpy(dstBuffer, srcBuffer, count * sizeof(T)); 591 return dstBuffer; 592 } 593 594 inline char* refText(const char* text, size_t byteLength) { 595 return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength); 596 } 597 598 inline SkPath* refPath(SkPath* path) { 599 if (!path) return NULL; 600 601 SkPath* pathCopy = mPathMap.valueFor(path); 602 if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { 603 pathCopy = new SkPath(*path); 604 pathCopy->setSourcePath(path); 605 // replaceValueFor() performs an add if the entry doesn't exist 606 mPathMap.replaceValueFor(path, pathCopy); 607 mPaths.add(pathCopy); 608 } 609 if (mSourcePaths.indexOf(path) < 0) { 610 mCaches.resourceCache.incrementRefcount(path); 611 mSourcePaths.add(path); 612 } 613 return pathCopy; 614 } 615 616 inline SkPaint* refPaint(SkPaint* paint) { 617 if (!paint) { 618 return paint; 619 } 620 621 SkPaint* paintCopy = mPaintMap.valueFor(paint); 622 if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { 623 paintCopy = new SkPaint(*paint); 624 // replaceValueFor() performs an add if the entry doesn't exist 625 mPaintMap.replaceValueFor(paint, paintCopy); 626 mPaints.add(paintCopy); 627 } 628 629 return paintCopy; 630 } 631 632 inline SkRegion* refRegion(SkRegion* region) { 633 if (!region) { 634 return region; 635 } 636 637 SkRegion* regionCopy = mRegionMap.valueFor(region); 638 // TODO: Add generation ID to SkRegion 639 if (regionCopy == NULL) { 640 regionCopy = new SkRegion(*region); 641 // replaceValueFor() performs an add if the entry doesn't exist 642 mRegionMap.replaceValueFor(region, regionCopy); 643 mRegions.add(regionCopy); 644 } 645 646 return regionCopy; 647 } 648 649 inline SkMatrix* refMatrix(SkMatrix* matrix) { 650 // Copying the matrix is cheap and prevents against the user changing the original 651 // matrix before the operation that uses it 652 SkMatrix* copy = new SkMatrix(*matrix); 653 mMatrices.add(copy); 654 return copy; 655 } 656 657 inline SkBitmap* refBitmap(SkBitmap* bitmap) { 658 // Note that this assumes the bitmap is immutable. There are cases this won't handle 659 // correctly, such as creating the bitmap from scratch, drawing with it, changing its 660 // contents, and drawing again. The only fix would be to always copy it the first time, 661 // which doesn't seem worth the extra cycles for this unlikely case. 662 mBitmapResources.add(bitmap); 663 mCaches.resourceCache.incrementRefcount(bitmap); 664 return bitmap; 665 } 666 667 inline SkBitmap* refBitmapData(SkBitmap* bitmap) { 668 mOwnedBitmapResources.add(bitmap); 669 mCaches.resourceCache.incrementRefcount(bitmap); 670 return bitmap; 671 } 672 673 inline SkiaShader* refShader(SkiaShader* shader) { 674 if (!shader) return NULL; 675 676 SkiaShader* shaderCopy = mShaderMap.valueFor(shader); 677 // TODO: We also need to handle generation ID changes in compose shaders 678 if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { 679 shaderCopy = shader->copy(); 680 // replaceValueFor() performs an add if the entry doesn't exist 681 mShaderMap.replaceValueFor(shader, shaderCopy); 682 mShaders.add(shaderCopy); 683 mCaches.resourceCache.incrementRefcount(shaderCopy); 684 } 685 return shaderCopy; 686 } 687 688 inline SkiaColorFilter* refColorFilter(SkiaColorFilter* colorFilter) { 689 mFilterResources.add(colorFilter); 690 mCaches.resourceCache.incrementRefcount(colorFilter); 691 return colorFilter; 692 } 693 694 Vector<SkBitmap*> mBitmapResources; 695 Vector<SkBitmap*> mOwnedBitmapResources; 696 Vector<SkiaColorFilter*> mFilterResources; 697 698 Vector<SkPaint*> mPaints; 699 DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; 700 701 Vector<SkPath*> mPaths; 702 DefaultKeyedVector<SkPath*, SkPath*> mPathMap; 703 704 SortedVector<SkPath*> mSourcePaths; 705 706 Vector<SkRegion*> mRegions; 707 DefaultKeyedVector<SkRegion*, SkRegion*> mRegionMap; 708 709 Vector<SkiaShader*> mShaders; 710 DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; 711 712 Vector<SkMatrix*> mMatrices; 713 714 Vector<Layer*> mLayers; 715 716 int mRestoreSaveCount; 717 718 Caches& mCaches; 719 sp<DisplayListData> mDisplayListData; 720 721 float mTranslateX; 722 float mTranslateY; 723 bool mHasTranslate; 724 bool mHasDrawOps; 725 726 uint32_t mFunctorCount; 727 728 friend class DisplayList; 729 730}; // class DisplayListRenderer 731 732}; // namespace uirenderer 733}; // namespace android 734 735#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H 736