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