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