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