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