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