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 45 class SkBitmap; 46 class SkPaint; 47 class SkPath; 48 class SkRegion; 49 50 namespace android { 51 namespace uirenderer { 52 53 class DeferredDisplayList; 54 class DisplayListOp; 55 class DisplayListRenderer; 56 class OpenGLRenderer; 57 class Rect; 58 class Layer; 59 class SkiaColorFilter; 60 class SkiaShader; 61 62 class ClipRectOp; 63 class SaveLayerOp; 64 class SaveOp; 65 class RestoreToCountOp; 66 67 struct 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 75 struct 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 */ 88 class DisplayListData : public LightRefBase<DisplayListData> { 89 public: 90 LinearAllocator allocator; 91 Vector<DisplayListOp*> displayListOps; 92 }; 93 94 /** 95 * Replays recorded drawing commands. 96 */ 97 class DisplayList { 98 public: 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 setClipToBounds(bool clipToBounds) { 141 mClipToBounds = clipToBounds; 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 } 168 } 169 170 float getAlpha() const { 171 return mAlpha; 172 } 173 174 void setHasOverlappingRendering(bool hasOverlappingRendering) { 175 mHasOverlappingRendering = hasOverlappingRendering; 176 } 177 178 bool hasOverlappingRendering() const { 179 return mHasOverlappingRendering; 180 } 181 182 void setTranslationX(float translationX) { 183 if (translationX != mTranslationX) { 184 mTranslationX = translationX; 185 mMatrixDirty = true; 186 if (mTranslationX == 0.0f && mTranslationY == 0.0f) { 187 mMatrixFlags &= ~TRANSLATION; 188 } else { 189 mMatrixFlags |= TRANSLATION; 190 } 191 } 192 } 193 194 float getTranslationX() const { 195 return mTranslationX; 196 } 197 198 void setTranslationY(float translationY) { 199 if (translationY != mTranslationY) { 200 mTranslationY = translationY; 201 mMatrixDirty = true; 202 if (mTranslationX == 0.0f && mTranslationY == 0.0f) { 203 mMatrixFlags &= ~TRANSLATION; 204 } else { 205 mMatrixFlags |= TRANSLATION; 206 } 207 } 208 } 209 210 float getTranslationY() const { 211 return mTranslationY; 212 } 213 214 void setRotation(float rotation) { 215 if (rotation != mRotation) { 216 mRotation = rotation; 217 mMatrixDirty = true; 218 if (mRotation == 0.0f) { 219 mMatrixFlags &= ~ROTATION; 220 } else { 221 mMatrixFlags |= ROTATION; 222 } 223 } 224 } 225 226 float getRotation() const { 227 return mRotation; 228 } 229 230 void setRotationX(float rotationX) { 231 if (rotationX != mRotationX) { 232 mRotationX = rotationX; 233 mMatrixDirty = true; 234 if (mRotationX == 0.0f && mRotationY == 0.0f) { 235 mMatrixFlags &= ~ROTATION_3D; 236 } else { 237 mMatrixFlags |= ROTATION_3D; 238 } 239 } 240 } 241 242 float getRotationX() const { 243 return mRotationX; 244 } 245 246 void setRotationY(float rotationY) { 247 if (rotationY != mRotationY) { 248 mRotationY = rotationY; 249 mMatrixDirty = true; 250 if (mRotationX == 0.0f && mRotationY == 0.0f) { 251 mMatrixFlags &= ~ROTATION_3D; 252 } else { 253 mMatrixFlags |= ROTATION_3D; 254 } 255 } 256 } 257 258 float getRotationY() const { 259 return mRotationY; 260 } 261 262 void setScaleX(float scaleX) { 263 if (scaleX != mScaleX) { 264 mScaleX = scaleX; 265 mMatrixDirty = true; 266 if (mScaleX == 1.0f && mScaleY == 1.0f) { 267 mMatrixFlags &= ~SCALE; 268 } else { 269 mMatrixFlags |= SCALE; 270 } 271 } 272 } 273 274 float getScaleX() const { 275 return mScaleX; 276 } 277 278 void setScaleY(float scaleY) { 279 if (scaleY != mScaleY) { 280 mScaleY = scaleY; 281 mMatrixDirty = true; 282 if (mScaleX == 1.0f && mScaleY == 1.0f) { 283 mMatrixFlags &= ~SCALE; 284 } else { 285 mMatrixFlags |= SCALE; 286 } 287 } 288 } 289 290 float getScaleY() const { 291 return mScaleY; 292 } 293 294 void setPivotX(float pivotX) { 295 mPivotX = pivotX; 296 mMatrixDirty = true; 297 if (mPivotX == 0.0f && mPivotY == 0.0f) { 298 mMatrixFlags &= ~PIVOT; 299 } else { 300 mMatrixFlags |= PIVOT; 301 } 302 mPivotExplicitlySet = true; 303 } 304 305 ANDROID_API float getPivotX(); 306 307 void setPivotY(float pivotY) { 308 mPivotY = pivotY; 309 mMatrixDirty = true; 310 if (mPivotX == 0.0f && mPivotY == 0.0f) { 311 mMatrixFlags &= ~PIVOT; 312 } else { 313 mMatrixFlags |= PIVOT; 314 } 315 mPivotExplicitlySet = true; 316 } 317 318 ANDROID_API float getPivotY(); 319 320 void setCameraDistance(float distance) { 321 if (distance != mCameraDistance) { 322 mCameraDistance = distance; 323 mMatrixDirty = true; 324 if (!mTransformCamera) { 325 mTransformCamera = new Sk3DView(); 326 mTransformMatrix3D = new SkMatrix(); 327 } 328 mTransformCamera->setCameraLocation(0, 0, distance); 329 } 330 } 331 332 float getCameraDistance() const { 333 return mCameraDistance; 334 } 335 336 void setLeft(int left) { 337 if (left != mLeft) { 338 mLeft = left; 339 mWidth = mRight - mLeft; 340 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 341 mMatrixDirty = true; 342 } 343 } 344 } 345 346 float getLeft() const { 347 return mLeft; 348 } 349 350 void setTop(int top) { 351 if (top != mTop) { 352 mTop = top; 353 mHeight = mBottom - mTop; 354 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 355 mMatrixDirty = true; 356 } 357 } 358 } 359 360 float getTop() const { 361 return mTop; 362 } 363 364 void setRight(int right) { 365 if (right != mRight) { 366 mRight = right; 367 mWidth = mRight - mLeft; 368 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 369 mMatrixDirty = true; 370 } 371 } 372 } 373 374 float getRight() const { 375 return mRight; 376 } 377 378 void setBottom(int bottom) { 379 if (bottom != mBottom) { 380 mBottom = bottom; 381 mHeight = mBottom - mTop; 382 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 383 mMatrixDirty = true; 384 } 385 } 386 } 387 388 float getBottom() const { 389 return mBottom; 390 } 391 392 void setLeftTop(int left, int top) { 393 if (left != mLeft || top != mTop) { 394 mLeft = left; 395 mTop = top; 396 mWidth = mRight - mLeft; 397 mHeight = mBottom - mTop; 398 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 399 mMatrixDirty = true; 400 } 401 } 402 } 403 404 void setLeftTopRightBottom(int left, int top, int right, int bottom) { 405 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) { 406 mLeft = left; 407 mTop = top; 408 mRight = right; 409 mBottom = bottom; 410 mWidth = mRight - mLeft; 411 mHeight = mBottom - mTop; 412 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 413 mMatrixDirty = true; 414 } 415 } 416 } 417 418 void offsetLeftRight(float offset) { 419 if (offset != 0) { 420 mLeft += offset; 421 mRight += offset; 422 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 423 mMatrixDirty = true; 424 } 425 } 426 } 427 428 void offsetTopBottom(float offset) { 429 if (offset != 0) { 430 mTop += offset; 431 mBottom += offset; 432 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 433 mMatrixDirty = true; 434 } 435 } 436 } 437 438 void setCaching(bool caching) { 439 mCaching = caching; 440 } 441 442 int getWidth() { 443 return mWidth; 444 } 445 446 int getHeight() { 447 return mHeight; 448 } 449 450 private: 451 void outputViewProperties(const int level); 452 453 template <class T> 454 inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level); 455 456 template <class T> 457 inline void iterate(OpenGLRenderer& renderer, T& handler, const int level); 458 459 void init(); 460 461 void clearResources(); 462 463 void updateMatrix(); 464 465 class TextContainer { 466 public: 467 size_t length() const { 468 return mByteLength; 469 } 470 471 const char* text() const { 472 return (const char*) mText; 473 } 474 475 size_t mByteLength; 476 const char* mText; 477 }; 478 479 Vector<SkBitmap*> mBitmapResources; 480 Vector<SkBitmap*> mOwnedBitmapResources; 481 Vector<SkiaColorFilter*> mFilterResources; 482 483 Vector<SkPaint*> mPaints; 484 Vector<SkPath*> mPaths; 485 SortedVector<SkPath*> mSourcePaths; 486 Vector<SkRegion*> mRegions; 487 Vector<SkMatrix*> mMatrices; 488 Vector<SkiaShader*> mShaders; 489 Vector<Layer*> mLayers; 490 491 sp<DisplayListData> mDisplayListData; 492 493 size_t mSize; 494 495 bool mIsRenderable; 496 uint32_t mFunctorCount; 497 498 String8 mName; 499 500 // View properties 501 bool mClipToBounds; 502 float mAlpha; 503 bool mHasOverlappingRendering; 504 float mTranslationX, mTranslationY; 505 float mRotation, mRotationX, mRotationY; 506 float mScaleX, mScaleY; 507 float mPivotX, mPivotY; 508 float mCameraDistance; 509 int mLeft, mTop, mRight, mBottom; 510 int mWidth, mHeight; 511 int mPrevWidth, mPrevHeight; 512 bool mPivotExplicitlySet; 513 bool mMatrixDirty; 514 bool mMatrixIsIdentity; 515 uint32_t mMatrixFlags; 516 SkMatrix* mTransformMatrix; 517 Sk3DView* mTransformCamera; 518 SkMatrix* mTransformMatrix3D; 519 SkMatrix* mStaticMatrix; 520 SkMatrix* mAnimationMatrix; 521 bool mCaching; 522 523 /** 524 * State operations - needed to defer displayList property operations (for example, when setting 525 * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's 526 * allocation, or null if uninitialized. 527 * 528 * These are initialized (via friend constructors) when a displayList is issued in either replay 529 * or deferred mode. If replaying, the ops are not used until the next frame. If deferring, the 530 * ops may be stored in the DeferredDisplayList to be played back a second time. 531 * 532 * They should be used at most once per frame (one call to iterate) 533 */ 534 ClipRectOp* mClipRectOp; 535 SaveLayerOp* mSaveLayerOp; 536 SaveOp* mSaveOp; 537 RestoreToCountOp* mRestoreToCountOp; 538 }; // class DisplayList 539 540 }; // namespace uirenderer 541 }; // namespace android 542 543 #endif // ANDROID_HWUI_OPENGL_RENDERER_H 544