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