DisplayList.h revision e3b0a0117a2ab4118f868a731b238fe8f2430276
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/RefBase.h> 30#include <utils/SortedVector.h> 31#include <utils/String8.h> 32#include <utils/Vector.h> 33 34#include <cutils/compiler.h> 35 36#include <androidfw/ResourceTypes.h> 37 38#include "utils/LinearAllocator.h" 39 40#include "Debug.h" 41 42#define TRANSLATION 0x0001 43#define ROTATION 0x0002 44#define ROTATION_3D 0x0004 45#define SCALE 0x0008 46#define PIVOT 0x0010 47 48class SkBitmap; 49class SkPaint; 50class SkPath; 51class SkRegion; 52 53namespace android { 54namespace uirenderer { 55 56class DeferredDisplayList; 57class DisplayListOp; 58class DisplayListRenderer; 59class OpenGLRenderer; 60class Rect; 61class Layer; 62class SkiaColorFilter; 63class SkiaShader; 64 65class ClipRectOp; 66class SaveLayerOp; 67class SaveOp; 68class RestoreToCountOp; 69 70struct DeferStateStruct { 71 DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags) 72 : mDeferredList(deferredList), mRenderer(renderer), mReplayFlags(replayFlags) {} 73 DeferredDisplayList& mDeferredList; 74 OpenGLRenderer& mRenderer; 75 const int mReplayFlags; 76}; 77 78struct ReplayStateStruct { 79 ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags) 80 : mRenderer(renderer), mDirty(dirty), mReplayFlags(replayFlags), 81 mDrawGlStatus(DrawGlInfo::kStatusDone) {} 82 OpenGLRenderer& mRenderer; 83 Rect& mDirty; 84 const int mReplayFlags; 85 status_t mDrawGlStatus; 86}; 87 88/** 89 * Refcounted structure that holds data used in display list stream 90 */ 91class DisplayListData : public LightRefBase<DisplayListData> { 92public: 93 LinearAllocator allocator; 94 Vector<DisplayListOp*> displayListOps; 95}; 96 97/** 98 * Replays recorded drawing commands. 99 */ 100class DisplayList { 101public: 102 DisplayList(const DisplayListRenderer& recorder); 103 ANDROID_API ~DisplayList(); 104 105 // See flags defined in DisplayList.java 106 enum ReplayFlag { 107 kReplayFlag_ClipChildren = 0x1 108 }; 109 110 111 ANDROID_API size_t getSize(); 112 ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList); 113 ANDROID_API static void outputLogBuffer(int fd); 114 115 void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); 116 117 118 void defer(DeferStateStruct& deferStruct, const int level); 119 void replay(ReplayStateStruct& replayStruct, const int level); 120 121 void output(uint32_t level = 0); 122 123 ANDROID_API void reset(); 124 125 void setRenderable(bool renderable) { 126 mIsRenderable = renderable; 127 } 128 129 bool isRenderable() const { 130 return mIsRenderable; 131 } 132 133 void setName(const char* name) { 134 if (name) { 135 char* lastPeriod = strrchr(name, '.'); 136 if (lastPeriod) { 137 mName.setTo(lastPeriod + 1); 138 } else { 139 mName.setTo(name); 140 } 141 } 142 } 143 144 const char* getName() const { 145 return mName.string(); 146 } 147 148 void setClipToBounds(bool clipToBounds) { 149 mClipToBounds = clipToBounds; 150 } 151 152 void setStaticMatrix(SkMatrix* matrix) { 153 delete mStaticMatrix; 154 mStaticMatrix = new SkMatrix(*matrix); 155 } 156 157 // Can return NULL 158 SkMatrix* getStaticMatrix() { 159 return mStaticMatrix; 160 } 161 162 void setAnimationMatrix(SkMatrix* matrix) { 163 delete mAnimationMatrix; 164 if (matrix) { 165 mAnimationMatrix = new SkMatrix(*matrix); 166 } else { 167 mAnimationMatrix = NULL; 168 } 169 } 170 171 void setAlpha(float alpha) { 172 alpha = fminf(1.0f, fmaxf(0.0f, alpha)); 173 if (alpha != mAlpha) { 174 mAlpha = alpha; 175 } 176 } 177 178 float getAlpha() const { 179 return mAlpha; 180 } 181 182 void setHasOverlappingRendering(bool hasOverlappingRendering) { 183 mHasOverlappingRendering = hasOverlappingRendering; 184 } 185 186 bool hasOverlappingRendering() const { 187 return mHasOverlappingRendering; 188 } 189 190 void setTranslationX(float translationX) { 191 if (translationX != mTranslationX) { 192 mTranslationX = translationX; 193 mMatrixDirty = true; 194 if (mTranslationX == 0.0f && mTranslationY == 0.0f) { 195 mMatrixFlags &= ~TRANSLATION; 196 } else { 197 mMatrixFlags |= TRANSLATION; 198 } 199 } 200 } 201 202 float getTranslationX() const { 203 return mTranslationX; 204 } 205 206 void setTranslationY(float translationY) { 207 if (translationY != mTranslationY) { 208 mTranslationY = translationY; 209 mMatrixDirty = true; 210 if (mTranslationX == 0.0f && mTranslationY == 0.0f) { 211 mMatrixFlags &= ~TRANSLATION; 212 } else { 213 mMatrixFlags |= TRANSLATION; 214 } 215 } 216 } 217 218 float getTranslationY() const { 219 return mTranslationY; 220 } 221 222 void setRotation(float rotation) { 223 if (rotation != mRotation) { 224 mRotation = rotation; 225 mMatrixDirty = true; 226 if (mRotation == 0.0f) { 227 mMatrixFlags &= ~ROTATION; 228 } else { 229 mMatrixFlags |= ROTATION; 230 } 231 } 232 } 233 234 float getRotation() const { 235 return mRotation; 236 } 237 238 void setRotationX(float rotationX) { 239 if (rotationX != mRotationX) { 240 mRotationX = rotationX; 241 mMatrixDirty = true; 242 if (mRotationX == 0.0f && mRotationY == 0.0f) { 243 mMatrixFlags &= ~ROTATION_3D; 244 } else { 245 mMatrixFlags |= ROTATION_3D; 246 } 247 } 248 } 249 250 float getRotationX() const { 251 return mRotationX; 252 } 253 254 void setRotationY(float rotationY) { 255 if (rotationY != mRotationY) { 256 mRotationY = rotationY; 257 mMatrixDirty = true; 258 if (mRotationX == 0.0f && mRotationY == 0.0f) { 259 mMatrixFlags &= ~ROTATION_3D; 260 } else { 261 mMatrixFlags |= ROTATION_3D; 262 } 263 } 264 } 265 266 float getRotationY() const { 267 return mRotationY; 268 } 269 270 void setScaleX(float scaleX) { 271 if (scaleX != mScaleX) { 272 mScaleX = scaleX; 273 mMatrixDirty = true; 274 if (mScaleX == 1.0f && mScaleY == 1.0f) { 275 mMatrixFlags &= ~SCALE; 276 } else { 277 mMatrixFlags |= SCALE; 278 } 279 } 280 } 281 282 float getScaleX() const { 283 return mScaleX; 284 } 285 286 void setScaleY(float scaleY) { 287 if (scaleY != mScaleY) { 288 mScaleY = scaleY; 289 mMatrixDirty = true; 290 if (mScaleX == 1.0f && mScaleY == 1.0f) { 291 mMatrixFlags &= ~SCALE; 292 } else { 293 mMatrixFlags |= SCALE; 294 } 295 } 296 } 297 298 float getScaleY() const { 299 return mScaleY; 300 } 301 302 void setPivotX(float pivotX) { 303 mPivotX = pivotX; 304 mMatrixDirty = true; 305 if (mPivotX == 0.0f && mPivotY == 0.0f) { 306 mMatrixFlags &= ~PIVOT; 307 } else { 308 mMatrixFlags |= PIVOT; 309 } 310 mPivotExplicitlySet = true; 311 } 312 313 ANDROID_API float getPivotX(); 314 315 void setPivotY(float pivotY) { 316 mPivotY = pivotY; 317 mMatrixDirty = true; 318 if (mPivotX == 0.0f && mPivotY == 0.0f) { 319 mMatrixFlags &= ~PIVOT; 320 } else { 321 mMatrixFlags |= PIVOT; 322 } 323 mPivotExplicitlySet = true; 324 } 325 326 ANDROID_API float getPivotY(); 327 328 void setCameraDistance(float distance) { 329 if (distance != mCameraDistance) { 330 mCameraDistance = distance; 331 mMatrixDirty = true; 332 if (!mTransformCamera) { 333 mTransformCamera = new Sk3DView(); 334 mTransformMatrix3D = new SkMatrix(); 335 } 336 mTransformCamera->setCameraLocation(0, 0, distance); 337 } 338 } 339 340 float getCameraDistance() const { 341 return mCameraDistance; 342 } 343 344 void setLeft(int left) { 345 if (left != mLeft) { 346 mLeft = left; 347 mWidth = mRight - mLeft; 348 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 349 mMatrixDirty = true; 350 } 351 } 352 } 353 354 float getLeft() const { 355 return mLeft; 356 } 357 358 void setTop(int top) { 359 if (top != mTop) { 360 mTop = top; 361 mHeight = mBottom - mTop; 362 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 363 mMatrixDirty = true; 364 } 365 } 366 } 367 368 float getTop() const { 369 return mTop; 370 } 371 372 void setRight(int right) { 373 if (right != mRight) { 374 mRight = right; 375 mWidth = mRight - mLeft; 376 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 377 mMatrixDirty = true; 378 } 379 } 380 } 381 382 float getRight() const { 383 return mRight; 384 } 385 386 void setBottom(int bottom) { 387 if (bottom != mBottom) { 388 mBottom = bottom; 389 mHeight = mBottom - mTop; 390 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 391 mMatrixDirty = true; 392 } 393 } 394 } 395 396 float getBottom() const { 397 return mBottom; 398 } 399 400 void setLeftTop(int left, int top) { 401 if (left != mLeft || top != mTop) { 402 mLeft = left; 403 mTop = top; 404 mWidth = mRight - mLeft; 405 mHeight = mBottom - mTop; 406 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 407 mMatrixDirty = true; 408 } 409 } 410 } 411 412 void setLeftTopRightBottom(int left, int top, int right, int bottom) { 413 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) { 414 mLeft = left; 415 mTop = top; 416 mRight = right; 417 mBottom = bottom; 418 mWidth = mRight - mLeft; 419 mHeight = mBottom - mTop; 420 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 421 mMatrixDirty = true; 422 } 423 } 424 } 425 426 void offsetLeftRight(float offset) { 427 if (offset != 0) { 428 mLeft += offset; 429 mRight += offset; 430 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 431 mMatrixDirty = true; 432 } 433 } 434 } 435 436 void offsetTopBottom(float offset) { 437 if (offset != 0) { 438 mTop += offset; 439 mBottom += offset; 440 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 441 mMatrixDirty = true; 442 } 443 } 444 } 445 446 void setCaching(bool caching) { 447 mCaching = caching; 448 } 449 450 int getWidth() { 451 return mWidth; 452 } 453 454 int getHeight() { 455 return mHeight; 456 } 457 458private: 459 void outputViewProperties(const int level); 460 461 template <class T> 462 inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level); 463 464 template <class T> 465 inline void iterate(OpenGLRenderer& renderer, T& handler, const int level); 466 467 void init(); 468 469 void clearResources(); 470 471 void updateMatrix(); 472 473 class TextContainer { 474 public: 475 size_t length() const { 476 return mByteLength; 477 } 478 479 const char* text() const { 480 return (const char*) mText; 481 } 482 483 size_t mByteLength; 484 const char* mText; 485 }; 486 487 Vector<SkBitmap*> mBitmapResources; 488 Vector<SkBitmap*> mOwnedBitmapResources; 489 Vector<SkiaColorFilter*> mFilterResources; 490 Vector<Res_png_9patch*> mPatchResources; 491 492 Vector<SkPaint*> mPaints; 493 Vector<SkPath*> mPaths; 494 SortedVector<SkPath*> mSourcePaths; 495 Vector<SkRegion*> mRegions; 496 Vector<SkMatrix*> mMatrices; 497 Vector<SkiaShader*> mShaders; 498 Vector<Layer*> mLayers; 499 500 sp<DisplayListData> mDisplayListData; 501 502 size_t mSize; 503 504 bool mIsRenderable; 505 uint32_t mFunctorCount; 506 507 String8 mName; 508 bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed 509 510 // View properties 511 bool mClipToBounds; 512 float mAlpha; 513 bool mHasOverlappingRendering; 514 float mTranslationX, mTranslationY; 515 float mRotation, mRotationX, mRotationY; 516 float mScaleX, mScaleY; 517 float mPivotX, mPivotY; 518 float mCameraDistance; 519 int mLeft, mTop, mRight, mBottom; 520 int mWidth, mHeight; 521 int mPrevWidth, mPrevHeight; 522 bool mPivotExplicitlySet; 523 bool mMatrixDirty; 524 bool mMatrixIsIdentity; 525 uint32_t mMatrixFlags; 526 SkMatrix* mTransformMatrix; 527 Sk3DView* mTransformCamera; 528 SkMatrix* mTransformMatrix3D; 529 SkMatrix* mStaticMatrix; 530 SkMatrix* mAnimationMatrix; 531 bool mCaching; 532 533 /** 534 * State operations - needed to defer displayList property operations (for example, when setting 535 * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's 536 * allocation, or null if uninitialized. 537 * 538 * These are initialized (via friend re-constructors) when a displayList is issued in either 539 * replay or deferred mode. If replaying, the ops are not used until the next frame. If 540 * deferring, the ops may be stored in the DeferredDisplayList to be played back a second time. 541 * 542 * They should be used at most once per frame (one call to 'iterate') to avoid overwriting data 543 */ 544 ClipRectOp* mClipRectOp; 545 SaveLayerOp* mSaveLayerOp; 546 SaveOp* mSaveOp; 547 RestoreToCountOp* mRestoreToCountOp; 548}; // class DisplayList 549 550}; // namespace uirenderer 551}; // namespace android 552 553#endif // ANDROID_HWUI_OPENGL_RENDERER_H 554