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