• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
DeferStateStructDeferStateStruct70     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 {
ReplayStateStructReplayStateStruct78     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 
setRenderable(bool renderable)123     void setRenderable(bool renderable) {
124         mIsRenderable = renderable;
125     }
126 
isRenderable()127     bool isRenderable() const {
128         return mIsRenderable;
129     }
130 
setName(const char * name)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 
getName()142     const char* getName() const {
143         return mName.string();
144     }
145 
setClipToBounds(bool clipToBounds)146     void setClipToBounds(bool clipToBounds) {
147         mClipToBounds = clipToBounds;
148     }
149 
setStaticMatrix(SkMatrix * matrix)150     void setStaticMatrix(SkMatrix* matrix) {
151         delete mStaticMatrix;
152         mStaticMatrix = new SkMatrix(*matrix);
153     }
154 
155     // Can return NULL
getStaticMatrix()156     SkMatrix* getStaticMatrix() {
157         return mStaticMatrix;
158     }
159 
setAnimationMatrix(SkMatrix * matrix)160     void setAnimationMatrix(SkMatrix* matrix) {
161         delete mAnimationMatrix;
162         if (matrix) {
163             mAnimationMatrix = new SkMatrix(*matrix);
164         } else {
165             mAnimationMatrix = NULL;
166         }
167     }
168 
setAlpha(float alpha)169     void setAlpha(float alpha) {
170         alpha = fminf(1.0f, fmaxf(0.0f, alpha));
171         if (alpha != mAlpha) {
172             mAlpha = alpha;
173         }
174     }
175 
getAlpha()176     float getAlpha() const {
177         return mAlpha;
178     }
179 
setHasOverlappingRendering(bool hasOverlappingRendering)180     void setHasOverlappingRendering(bool hasOverlappingRendering) {
181         mHasOverlappingRendering = hasOverlappingRendering;
182     }
183 
hasOverlappingRendering()184     bool hasOverlappingRendering() const {
185         return mHasOverlappingRendering;
186     }
187 
setTranslationX(float translationX)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 
getTranslationX()200     float getTranslationX() const {
201         return mTranslationX;
202     }
203 
setTranslationY(float translationY)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 
getTranslationY()216     float getTranslationY() const {
217         return mTranslationY;
218     }
219 
setRotation(float rotation)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 
getRotation()232     float getRotation() const {
233         return mRotation;
234     }
235 
setRotationX(float rotationX)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 
getRotationX()248     float getRotationX() const {
249         return mRotationX;
250     }
251 
setRotationY(float rotationY)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 
getRotationY()264     float getRotationY() const {
265         return mRotationY;
266     }
267 
setScaleX(float scaleX)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 
getScaleX()280     float getScaleX() const {
281         return mScaleX;
282     }
283 
setScaleY(float scaleY)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 
getScaleY()296     float getScaleY() const {
297         return mScaleY;
298     }
299 
setPivotX(float pivotX)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 
setPivotY(float pivotY)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 
setCameraDistance(float distance)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 
getCameraDistance()338     float getCameraDistance() const {
339         return mCameraDistance;
340     }
341 
setLeft(int left)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 
getLeft()352     float getLeft() const {
353         return mLeft;
354     }
355 
setTop(int top)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 
getTop()366     float getTop() const {
367         return mTop;
368     }
369 
setRight(int right)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 
getRight()380     float getRight() const {
381         return mRight;
382     }
383 
setBottom(int bottom)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 
getBottom()394     float getBottom() const {
395         return mBottom;
396     }
397 
setLeftTop(int left,int top)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 
setLeftTopRightBottom(int left,int top,int right,int bottom)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 
offsetLeftRight(float offset)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 
offsetTopBottom(float offset)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 
setCaching(bool caching)444     void setCaching(bool caching) {
445         mCaching = caching;
446     }
447 
getWidth()448     int getWidth() {
449         return mWidth;
450     }
451 
getHeight()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:
length()473         size_t length() const {
474             return mByteLength;
475         }
476 
text()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