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