DisplayList.h revision 1df26446b7eac7050767c38ca977fde03a41a033
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 setStaticMatrix(SkMatrix* matrix) { 217 delete mStaticMatrix; 218 mStaticMatrix = new SkMatrix(*matrix); 219 } 220 221 // Can return NULL 222 SkMatrix* getStaticMatrix() { 223 return mStaticMatrix; 224 } 225 226 void setAnimationMatrix(SkMatrix* matrix) { 227 delete mAnimationMatrix; 228 if (matrix) { 229 mAnimationMatrix = new SkMatrix(*matrix); 230 } else { 231 mAnimationMatrix = NULL; 232 } 233 } 234 235 void setAlpha(float alpha) { 236 alpha = fminf(1.0f, fmaxf(0.0f, alpha)); 237 if (alpha != mAlpha) { 238 mAlpha = alpha; 239 } 240 } 241 242 float getAlpha() const { 243 return mAlpha; 244 } 245 246 void setHasOverlappingRendering(bool hasOverlappingRendering) { 247 mHasOverlappingRendering = hasOverlappingRendering; 248 } 249 250 bool hasOverlappingRendering() const { 251 return mHasOverlappingRendering; 252 } 253 254 void setTranslationX(float translationX) { 255 if (translationX != mTranslationX) { 256 mTranslationX = translationX; 257 onTranslationUpdate(); 258 } 259 } 260 261 float getTranslationX() const { 262 return mTranslationX; 263 } 264 265 void setTranslationY(float translationY) { 266 if (translationY != mTranslationY) { 267 mTranslationY = translationY; 268 onTranslationUpdate(); 269 } 270 } 271 272 float getTranslationY() const { 273 return mTranslationY; 274 } 275 276 void setTranslationZ(float translationZ) { 277 if (translationZ != mTranslationZ) { 278 mTranslationZ = translationZ; 279 onTranslationUpdate(); 280 } 281 } 282 283 float getTranslationZ() const { 284 return mTranslationZ; 285 } 286 287 void setRotation(float rotation) { 288 if (rotation != mRotation) { 289 mRotation = rotation; 290 mMatrixDirty = true; 291 if (mRotation == 0.0f) { 292 mMatrixFlags &= ~ROTATION; 293 } else { 294 mMatrixFlags |= ROTATION; 295 } 296 } 297 } 298 299 float getRotation() const { 300 return mRotation; 301 } 302 303 void setRotationX(float rotationX) { 304 if (rotationX != mRotationX) { 305 mRotationX = rotationX; 306 mMatrixDirty = true; 307 if (mRotationX == 0.0f && mRotationY == 0.0f) { 308 mMatrixFlags &= ~ROTATION_3D; 309 } else { 310 mMatrixFlags |= ROTATION_3D; 311 } 312 } 313 } 314 315 float getRotationX() const { 316 return mRotationX; 317 } 318 319 void setRotationY(float rotationY) { 320 if (rotationY != mRotationY) { 321 mRotationY = rotationY; 322 mMatrixDirty = true; 323 if (mRotationX == 0.0f && mRotationY == 0.0f) { 324 mMatrixFlags &= ~ROTATION_3D; 325 } else { 326 mMatrixFlags |= ROTATION_3D; 327 } 328 } 329 } 330 331 float getRotationY() const { 332 return mRotationY; 333 } 334 335 void setScaleX(float scaleX) { 336 if (scaleX != mScaleX) { 337 mScaleX = scaleX; 338 mMatrixDirty = true; 339 if (mScaleX == 1.0f && mScaleY == 1.0f) { 340 mMatrixFlags &= ~SCALE; 341 } else { 342 mMatrixFlags |= SCALE; 343 } 344 } 345 } 346 347 float getScaleX() const { 348 return mScaleX; 349 } 350 351 void setScaleY(float scaleY) { 352 if (scaleY != mScaleY) { 353 mScaleY = scaleY; 354 mMatrixDirty = true; 355 if (mScaleX == 1.0f && mScaleY == 1.0f) { 356 mMatrixFlags &= ~SCALE; 357 } else { 358 mMatrixFlags |= SCALE; 359 } 360 } 361 } 362 363 float getScaleY() const { 364 return mScaleY; 365 } 366 367 void setPivotX(float pivotX) { 368 mPivotX = pivotX; 369 mMatrixDirty = true; 370 if (mPivotX == 0.0f && mPivotY == 0.0f) { 371 mMatrixFlags &= ~PIVOT; 372 } else { 373 mMatrixFlags |= PIVOT; 374 } 375 mPivotExplicitlySet = true; 376 } 377 378 ANDROID_API float getPivotX(); 379 380 void setPivotY(float pivotY) { 381 mPivotY = pivotY; 382 mMatrixDirty = true; 383 if (mPivotX == 0.0f && mPivotY == 0.0f) { 384 mMatrixFlags &= ~PIVOT; 385 } else { 386 mMatrixFlags |= PIVOT; 387 } 388 mPivotExplicitlySet = true; 389 } 390 391 ANDROID_API float getPivotY(); 392 393 void setCameraDistance(float distance) { 394 if (distance != mCameraDistance) { 395 mCameraDistance = distance; 396 mMatrixDirty = true; 397 if (!mTransformCamera) { 398 mTransformCamera = new Sk3DView(); 399 mTransformMatrix3D = new SkMatrix(); 400 } 401 mTransformCamera->setCameraLocation(0, 0, distance); 402 } 403 } 404 405 float getCameraDistance() const { 406 return mCameraDistance; 407 } 408 409 void setLeft(int left) { 410 if (left != mLeft) { 411 mLeft = left; 412 mWidth = mRight - mLeft; 413 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 414 mMatrixDirty = true; 415 } 416 } 417 } 418 419 float getLeft() const { 420 return mLeft; 421 } 422 423 void setTop(int top) { 424 if (top != mTop) { 425 mTop = top; 426 mHeight = mBottom - mTop; 427 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 428 mMatrixDirty = true; 429 } 430 } 431 } 432 433 float getTop() const { 434 return mTop; 435 } 436 437 void setRight(int right) { 438 if (right != mRight) { 439 mRight = right; 440 mWidth = mRight - mLeft; 441 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 442 mMatrixDirty = true; 443 } 444 } 445 } 446 447 float getRight() const { 448 return mRight; 449 } 450 451 void setBottom(int bottom) { 452 if (bottom != mBottom) { 453 mBottom = bottom; 454 mHeight = mBottom - mTop; 455 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 456 mMatrixDirty = true; 457 } 458 } 459 } 460 461 float getBottom() const { 462 return mBottom; 463 } 464 465 void setLeftTop(int left, int top) { 466 if (left != mLeft || top != mTop) { 467 mLeft = left; 468 mTop = top; 469 mWidth = mRight - mLeft; 470 mHeight = mBottom - mTop; 471 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 472 mMatrixDirty = true; 473 } 474 } 475 } 476 477 void setLeftTopRightBottom(int left, int top, int right, int bottom) { 478 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) { 479 mLeft = left; 480 mTop = top; 481 mRight = right; 482 mBottom = bottom; 483 mWidth = mRight - mLeft; 484 mHeight = mBottom - mTop; 485 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 486 mMatrixDirty = true; 487 } 488 } 489 } 490 491 void offsetLeftRight(float offset) { 492 if (offset != 0) { 493 mLeft += offset; 494 mRight += offset; 495 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 496 mMatrixDirty = true; 497 } 498 } 499 } 500 501 void offsetTopBottom(float offset) { 502 if (offset != 0) { 503 mTop += offset; 504 mBottom += offset; 505 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 506 mMatrixDirty = true; 507 } 508 } 509 } 510 511 void setCaching(bool caching) { 512 mCaching = caching; 513 } 514 515 int getWidth() { 516 return mWidth; 517 } 518 519 int getHeight() { 520 return mHeight; 521 } 522 523private: 524 typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair; 525 526 enum ChildrenSelectMode { 527 kNegativeZChildren, 528 kPositiveZChildren 529 }; 530 531 void onTranslationUpdate() { 532 mMatrixDirty = true; 533 if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) { 534 mMatrixFlags &= ~TRANSLATION; 535 } else { 536 mMatrixFlags |= TRANSLATION; 537 } 538 } 539 540 void outputViewProperties(const int level); 541 542 void applyViewPropertyTransforms(mat4& matrix); 543 544 void computeOrderingImpl(DrawDisplayListOp* opState, 545 Vector<ZDrawDisplayListOpPair>* compositedChildrenOf3dRoot, 546 const mat4* transformFrom3dRoot, 547 Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface, 548 const mat4* transformFromProjectionSurface); 549 550 template <class T> 551 inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level); 552 553 template <class T> 554 inline void iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& renderer, 555 T& handler, const int level); 556 557 template <class T> 558 inline void iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level); 559 560 template <class T> 561 inline void iterate(OpenGLRenderer& renderer, T& handler, const int level); 562 563 void init(); 564 565 void clearResources(); 566 567 void updateMatrix(); 568 569 class TextContainer { 570 public: 571 size_t length() const { 572 return mByteLength; 573 } 574 575 const char* text() const { 576 return (const char*) mText; 577 } 578 579 size_t mByteLength; 580 const char* mText; 581 }; 582 583 Vector<const SkBitmap*> mBitmapResources; 584 Vector<const SkBitmap*> mOwnedBitmapResources; 585 Vector<SkiaColorFilter*> mFilterResources; 586 Vector<const Res_png_9patch*> mPatchResources; 587 588 Vector<const SkPaint*> mPaints; 589 Vector<const SkPath*> mPaths; 590 SortedVector<const SkPath*> mSourcePaths; 591 Vector<const SkRegion*> mRegions; 592 Vector<const SkMatrix*> mMatrices; 593 Vector<SkiaShader*> mShaders; 594 Vector<Layer*> mLayers; 595 596 sp<DisplayListData> mDisplayListData; 597 598 size_t mSize; 599 600 bool mIsRenderable; 601 uint32_t mFunctorCount; 602 603 String8 mName; 604 bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed 605 606 // Rendering properties 607 bool mClipToBounds; 608 bool mIsolatedZVolume; 609 bool mProjectBackwards; 610 bool mProjectionReceiver; 611 SkPath mOutline; 612 float mAlpha; 613 bool mHasOverlappingRendering; 614 float mTranslationX, mTranslationY, mTranslationZ; 615 float mRotation, mRotationX, mRotationY; 616 float mScaleX, mScaleY; 617 float mPivotX, mPivotY; 618 float mCameraDistance; 619 int mLeft, mTop, mRight, mBottom; 620 int mWidth, mHeight; 621 int mPrevWidth, mPrevHeight; 622 bool mPivotExplicitlySet; 623 bool mMatrixDirty; 624 bool mMatrixIsIdentity; 625 uint32_t mMatrixFlags; 626 SkMatrix* mTransformMatrix; 627 Sk3DView* mTransformCamera; 628 SkMatrix* mTransformMatrix3D; 629 SkMatrix* mStaticMatrix; 630 SkMatrix* mAnimationMatrix; 631 Matrix4 mTransform; 632 bool mCaching; 633 634 /** 635 * Draw time state - these properties are only set and used during rendering 636 */ 637 638 // for 3d roots, contains a z sorted list of all children items 639 Vector<ZDrawDisplayListOpPair> m3dNodes; 640 641 // for projection surfaces, contains a list of all children items 642 Vector<DrawDisplayListOp*> mProjectedNodes; 643}; // class DisplayList 644 645}; // namespace uirenderer 646}; // namespace android 647 648#endif // ANDROID_HWUI_OPENGL_RENDERER_H 649