DisplayList.h revision 629f67709b84a6bebdecdc8a500bf83560f557d0
1/* 2 * Copyright (C) 2013 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_H 18#define ANDROID_HWUI_DISPLAY_LIST_H 19 20#ifndef LOG_TAG 21 #define LOG_TAG "OpenGLRenderer" 22#endif 23 24#include <SkCamera.h> 25#include <SkMatrix.h> 26 27#include <private/hwui/DrawGlInfo.h> 28 29#include <utils/KeyedVector.h> 30#include <utils/LinearAllocator.h> 31#include <utils/RefBase.h> 32#include <utils/SortedVector.h> 33#include <utils/String8.h> 34#include <utils/Vector.h> 35 36#include <cutils/compiler.h> 37 38#include <androidfw/ResourceTypes.h> 39 40#include "Debug.h" 41#include "Matrix.h" 42#include "DeferredDisplayList.h" 43 44#define TRANSLATION 0x0001 45#define ROTATION 0x0002 46#define ROTATION_3D 0x0004 47#define SCALE 0x0008 48#define PIVOT 0x0010 49 50class SkBitmap; 51class SkPaint; 52class SkPath; 53class SkRegion; 54 55namespace android { 56namespace uirenderer { 57 58class DeferredDisplayList; 59class DisplayListOp; 60class DisplayListRenderer; 61class OpenGLRenderer; 62class Rect; 63class Layer; 64class SkiaColorFilter; 65class SkiaShader; 66 67class ClipRectOp; 68class SaveLayerOp; 69class SaveOp; 70class RestoreToCountOp; 71class DrawDisplayListOp; 72 73/** 74 * Holds data used in the playback a tree of DisplayLists. 75 */ 76class PlaybackStateStruct { 77protected: 78 PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator) 79 : mRenderer(renderer), mReplayFlags(replayFlags), mAllocator(allocator){} 80 81public: 82 OpenGLRenderer& mRenderer; 83 const int mReplayFlags; 84 85 // Allocator with the lifetime of a single frame. 86 // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator 87 LinearAllocator * const mAllocator; 88}; 89 90class DeferStateStruct : public PlaybackStateStruct { 91public: 92 DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags) 93 : PlaybackStateStruct(renderer, replayFlags, &(deferredList.mAllocator)), 94 mDeferredList(deferredList) {} 95 96 DeferredDisplayList& mDeferredList; 97}; 98 99class ReplayStateStruct : public PlaybackStateStruct { 100public: 101 ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags) 102 : PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator), 103 mDirty(dirty), mDrawGlStatus(DrawGlInfo::kStatusDone) {} 104 105 Rect& mDirty; 106 status_t mDrawGlStatus; 107 LinearAllocator mReplayAllocator; 108}; 109 110/** 111 * Refcounted structure that holds the list of commands used in display list stream. 112 */ 113class DisplayListData : public LightRefBase<DisplayListData> { 114public: 115 DisplayListData() : projectionIndex(-1) {} 116 // allocator into which all ops were allocated 117 LinearAllocator allocator; 118 119 // pointers to all ops within display list, pointing into allocator data 120 Vector<DisplayListOp*> displayListOps; 121 122 // list of children display lists for quick, non-drawing traversal 123 Vector<DrawDisplayListOp*> children; 124 125 // index of DisplayListOp restore, after which projected descendents should be drawn 126 int projectionIndex; 127 Matrix4 projectionTransform; 128}; 129 130/** 131 * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties. 132 * 133 * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording 134 * functionality is split between DisplayListRenderer (which manages the recording), DisplayListData 135 * (which holds the actual data), and DisplayList (which holds properties and performs playback onto 136 * a renderer). 137 * 138 * Note that DisplayListData is swapped out from beneath an individual DisplayList when a view's 139 * recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay 140 * attached. 141 */ 142class DisplayList { 143public: 144 DisplayList(const DisplayListRenderer& recorder); 145 ANDROID_API ~DisplayList(); 146 147 // See flags defined in DisplayList.java 148 enum ReplayFlag { 149 kReplayFlag_ClipChildren = 0x1 150 }; 151 152 ANDROID_API size_t getSize(); 153 ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList); 154 ANDROID_API static void outputLogBuffer(int fd); 155 156 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); 157 158 void computeOrdering(); 159 void defer(DeferStateStruct& deferStruct, const int level); 160 void replay(ReplayStateStruct& replayStruct, const int level); 161 162 ANDROID_API void output(uint32_t level = 1); 163 164 ANDROID_API void reset(); 165 166 void setRenderable(bool renderable) { 167 mIsRenderable = renderable; 168 } 169 170 bool isRenderable() const { 171 return mIsRenderable; 172 } 173 174 void setName(const char* name) { 175 if (name) { 176 char* lastPeriod = strrchr(name, '.'); 177 if (lastPeriod) { 178 mName.setTo(lastPeriod + 1); 179 } else { 180 mName.setTo(name); 181 } 182 } 183 } 184 185 const char* getName() const { 186 return mName.string(); 187 } 188 189 void setClipToBounds(bool clipToBounds) { 190 mClipToBounds = clipToBounds; 191 } 192 193 void setIsolatedZVolume(bool shouldIsolate) { 194 mIsolatedZVolume = shouldIsolate; 195 } 196 197 void setProjectBackwards(bool shouldProject) { 198 mProjectBackwards = shouldProject; 199 } 200 201 void setOutline(const SkPath* outline) { 202 if (!outline) { 203 mOutline.reset(); 204 } else { 205 mOutline = *outline; 206 } 207 } 208 209 void setStaticMatrix(SkMatrix* matrix) { 210 delete mStaticMatrix; 211 mStaticMatrix = new SkMatrix(*matrix); 212 } 213 214 // Can return NULL 215 SkMatrix* getStaticMatrix() { 216 return mStaticMatrix; 217 } 218 219 void setAnimationMatrix(SkMatrix* matrix) { 220 delete mAnimationMatrix; 221 if (matrix) { 222 mAnimationMatrix = new SkMatrix(*matrix); 223 } else { 224 mAnimationMatrix = NULL; 225 } 226 } 227 228 void setAlpha(float alpha) { 229 alpha = fminf(1.0f, fmaxf(0.0f, alpha)); 230 if (alpha != mAlpha) { 231 mAlpha = alpha; 232 } 233 } 234 235 float getAlpha() const { 236 return mAlpha; 237 } 238 239 void setHasOverlappingRendering(bool hasOverlappingRendering) { 240 mHasOverlappingRendering = hasOverlappingRendering; 241 } 242 243 bool hasOverlappingRendering() const { 244 return mHasOverlappingRendering; 245 } 246 247 void setTranslationX(float translationX) { 248 if (translationX != mTranslationX) { 249 mTranslationX = translationX; 250 onTranslationUpdate(); 251 } 252 } 253 254 float getTranslationX() const { 255 return mTranslationX; 256 } 257 258 void setTranslationY(float translationY) { 259 if (translationY != mTranslationY) { 260 mTranslationY = translationY; 261 onTranslationUpdate(); 262 } 263 } 264 265 float getTranslationY() const { 266 return mTranslationY; 267 } 268 269 void setTranslationZ(float translationZ) { 270 if (translationZ != mTranslationZ) { 271 mTranslationZ = translationZ; 272 onTranslationUpdate(); 273 } 274 } 275 276 float getTranslationZ() const { 277 return mTranslationZ; 278 } 279 280 void setRotation(float rotation) { 281 if (rotation != mRotation) { 282 mRotation = rotation; 283 mMatrixDirty = true; 284 if (mRotation == 0.0f) { 285 mMatrixFlags &= ~ROTATION; 286 } else { 287 mMatrixFlags |= ROTATION; 288 } 289 } 290 } 291 292 float getRotation() const { 293 return mRotation; 294 } 295 296 void setRotationX(float rotationX) { 297 if (rotationX != mRotationX) { 298 mRotationX = rotationX; 299 mMatrixDirty = true; 300 if (mRotationX == 0.0f && mRotationY == 0.0f) { 301 mMatrixFlags &= ~ROTATION_3D; 302 } else { 303 mMatrixFlags |= ROTATION_3D; 304 } 305 } 306 } 307 308 float getRotationX() const { 309 return mRotationX; 310 } 311 312 void setRotationY(float rotationY) { 313 if (rotationY != mRotationY) { 314 mRotationY = rotationY; 315 mMatrixDirty = true; 316 if (mRotationX == 0.0f && mRotationY == 0.0f) { 317 mMatrixFlags &= ~ROTATION_3D; 318 } else { 319 mMatrixFlags |= ROTATION_3D; 320 } 321 } 322 } 323 324 float getRotationY() const { 325 return mRotationY; 326 } 327 328 void setScaleX(float scaleX) { 329 if (scaleX != mScaleX) { 330 mScaleX = scaleX; 331 mMatrixDirty = true; 332 if (mScaleX == 1.0f && mScaleY == 1.0f) { 333 mMatrixFlags &= ~SCALE; 334 } else { 335 mMatrixFlags |= SCALE; 336 } 337 } 338 } 339 340 float getScaleX() const { 341 return mScaleX; 342 } 343 344 void setScaleY(float scaleY) { 345 if (scaleY != mScaleY) { 346 mScaleY = scaleY; 347 mMatrixDirty = true; 348 if (mScaleX == 1.0f && mScaleY == 1.0f) { 349 mMatrixFlags &= ~SCALE; 350 } else { 351 mMatrixFlags |= SCALE; 352 } 353 } 354 } 355 356 float getScaleY() const { 357 return mScaleY; 358 } 359 360 void setPivotX(float pivotX) { 361 mPivotX = pivotX; 362 mMatrixDirty = true; 363 if (mPivotX == 0.0f && mPivotY == 0.0f) { 364 mMatrixFlags &= ~PIVOT; 365 } else { 366 mMatrixFlags |= PIVOT; 367 } 368 mPivotExplicitlySet = true; 369 } 370 371 ANDROID_API float getPivotX(); 372 373 void setPivotY(float pivotY) { 374 mPivotY = pivotY; 375 mMatrixDirty = true; 376 if (mPivotX == 0.0f && mPivotY == 0.0f) { 377 mMatrixFlags &= ~PIVOT; 378 } else { 379 mMatrixFlags |= PIVOT; 380 } 381 mPivotExplicitlySet = true; 382 } 383 384 ANDROID_API float getPivotY(); 385 386 void setCameraDistance(float distance) { 387 if (distance != mCameraDistance) { 388 mCameraDistance = distance; 389 mMatrixDirty = true; 390 if (!mTransformCamera) { 391 mTransformCamera = new Sk3DView(); 392 mTransformMatrix3D = new SkMatrix(); 393 } 394 mTransformCamera->setCameraLocation(0, 0, distance); 395 } 396 } 397 398 float getCameraDistance() const { 399 return mCameraDistance; 400 } 401 402 void setLeft(int left) { 403 if (left != mLeft) { 404 mLeft = left; 405 mWidth = mRight - mLeft; 406 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 407 mMatrixDirty = true; 408 } 409 } 410 } 411 412 float getLeft() const { 413 return mLeft; 414 } 415 416 void setTop(int top) { 417 if (top != mTop) { 418 mTop = top; 419 mHeight = mBottom - mTop; 420 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 421 mMatrixDirty = true; 422 } 423 } 424 } 425 426 float getTop() const { 427 return mTop; 428 } 429 430 void setRight(int right) { 431 if (right != mRight) { 432 mRight = right; 433 mWidth = mRight - mLeft; 434 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 435 mMatrixDirty = true; 436 } 437 } 438 } 439 440 float getRight() const { 441 return mRight; 442 } 443 444 void setBottom(int bottom) { 445 if (bottom != mBottom) { 446 mBottom = bottom; 447 mHeight = mBottom - mTop; 448 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 449 mMatrixDirty = true; 450 } 451 } 452 } 453 454 float getBottom() const { 455 return mBottom; 456 } 457 458 void setLeftTop(int left, int top) { 459 if (left != mLeft || top != mTop) { 460 mLeft = left; 461 mTop = top; 462 mWidth = mRight - mLeft; 463 mHeight = mBottom - mTop; 464 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 465 mMatrixDirty = true; 466 } 467 } 468 } 469 470 void setLeftTopRightBottom(int left, int top, int right, int bottom) { 471 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) { 472 mLeft = left; 473 mTop = top; 474 mRight = right; 475 mBottom = bottom; 476 mWidth = mRight - mLeft; 477 mHeight = mBottom - mTop; 478 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 479 mMatrixDirty = true; 480 } 481 } 482 } 483 484 void offsetLeftRight(float offset) { 485 if (offset != 0) { 486 mLeft += offset; 487 mRight += offset; 488 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 489 mMatrixDirty = true; 490 } 491 } 492 } 493 494 void offsetTopBottom(float offset) { 495 if (offset != 0) { 496 mTop += offset; 497 mBottom += offset; 498 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 499 mMatrixDirty = true; 500 } 501 } 502 } 503 504 void setCaching(bool caching) { 505 mCaching = caching; 506 } 507 508 int getWidth() { 509 return mWidth; 510 } 511 512 int getHeight() { 513 return mHeight; 514 } 515 516private: 517 typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair; 518 519 enum ChildrenSelectMode { 520 kNegativeZChildren, 521 kPositiveZChildren 522 }; 523 524 void onTranslationUpdate() { 525 mMatrixDirty = true; 526 if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) { 527 mMatrixFlags &= ~TRANSLATION; 528 } else { 529 mMatrixFlags |= TRANSLATION; 530 } 531 } 532 533 void outputViewProperties(const int level); 534 535 void applyViewPropertyTransforms(mat4& matrix); 536 537 void computeOrderingImpl(DrawDisplayListOp* opState, 538 Vector<ZDrawDisplayListOpPair>* compositedChildrenOf3dRoot, 539 const mat4* transformFrom3dRoot, 540 Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface, 541 const mat4* transformFromProjectionSurface); 542 543 template <class T> 544 inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level); 545 546 template <class T> 547 inline void iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& renderer, 548 T& handler, const int level); 549 550 template <class T> 551 inline void iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level); 552 553 template <class T> 554 inline void iterate(OpenGLRenderer& renderer, T& handler, const int level); 555 556 void init(); 557 558 void clearResources(); 559 560 void updateMatrix(); 561 562 class TextContainer { 563 public: 564 size_t length() const { 565 return mByteLength; 566 } 567 568 const char* text() const { 569 return (const char*) mText; 570 } 571 572 size_t mByteLength; 573 const char* mText; 574 }; 575 576 Vector<const SkBitmap*> mBitmapResources; 577 Vector<const SkBitmap*> mOwnedBitmapResources; 578 Vector<SkiaColorFilter*> mFilterResources; 579 Vector<const Res_png_9patch*> mPatchResources; 580 581 Vector<const SkPaint*> mPaints; 582 Vector<const SkPath*> mPaths; 583 SortedVector<const SkPath*> mSourcePaths; 584 Vector<const SkRegion*> mRegions; 585 Vector<const SkMatrix*> mMatrices; 586 Vector<SkiaShader*> mShaders; 587 Vector<Layer*> mLayers; 588 589 sp<DisplayListData> mDisplayListData; 590 591 size_t mSize; 592 593 bool mIsRenderable; 594 uint32_t mFunctorCount; 595 596 String8 mName; 597 bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed 598 599 // Rendering properties 600 bool mClipToBounds; 601 bool mIsolatedZVolume; 602 bool mProjectBackwards; 603 SkPath mOutline; 604 float mAlpha; 605 bool mHasOverlappingRendering; 606 float mTranslationX, mTranslationY, mTranslationZ; 607 float mRotation, mRotationX, mRotationY; 608 float mScaleX, mScaleY; 609 float mPivotX, mPivotY; 610 float mCameraDistance; 611 int mLeft, mTop, mRight, mBottom; 612 int mWidth, mHeight; 613 int mPrevWidth, mPrevHeight; 614 bool mPivotExplicitlySet; 615 bool mMatrixDirty; 616 bool mMatrixIsIdentity; 617 618 /** 619 * Stores the total transformation of the DisplayList based upon its scalar 620 * translate/rotate/scale properties. 621 * 622 * In the common translation-only case, the matrix isn't allocated and the mTranslation 623 * properties are used directly. 624 */ 625 Matrix4* mTransformMatrix; 626 uint32_t mMatrixFlags; 627 Sk3DView* mTransformCamera; 628 SkMatrix* mTransformMatrix3D; 629 SkMatrix* mStaticMatrix; 630 SkMatrix* mAnimationMatrix; 631 bool mCaching; 632 633 /** 634 * Draw time state - these properties are only set and used during rendering 635 */ 636 637 // for 3d roots, contains a z sorted list of all children items 638 Vector<ZDrawDisplayListOpPair> m3dNodes; 639 640 // for projection surfaces, contains a list of all children items 641 Vector<DrawDisplayListOp*> mProjectedNodes; 642}; // class DisplayList 643 644}; // namespace uirenderer 645}; // namespace android 646 647#endif // ANDROID_HWUI_OPENGL_RENDERER_H 648