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