RenderProperties.h revision 0334c314a5721f49b4d172a9cefe10f157cb28a4
1/*
2 * Copyright (C) 2014 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#ifndef RENDERNODEPROPERTIES_H_
17#define RENDERNODEPROPERTIES_H_
18
19#include <stddef.h>
20#include <cutils/compiler.h>
21#include <androidfw/ResourceTypes.h>
22
23#include <SkCamera.h>
24#include <SkMatrix.h>
25#include <SkPath.h>
26
27#define TRANSLATION 0x0001
28#define ROTATION    0x0002
29#define ROTATION_3D 0x0004
30#define SCALE       0x0008
31#define PIVOT       0x0010
32
33class SkBitmap;
34class SkPaint;
35class SkRegion;
36
37namespace android {
38namespace uirenderer {
39
40class Matrix4;
41class RenderNode;
42
43/*
44 * Data structure that holds the properties for a RenderNode
45 */
46class RenderProperties {
47public:
48    RenderProperties();
49    virtual ~RenderProperties();
50
51    void setClipToBounds(bool clipToBounds) {
52        mClipToBounds = clipToBounds;
53    }
54
55    void setProjectBackwards(bool shouldProject) {
56        mProjectBackwards = shouldProject;
57    }
58
59    void setProjectionReceiver(bool shouldRecieve) {
60        mProjectionReceiver = shouldRecieve;
61    }
62
63    bool isProjectionReceiver() {
64        return mProjectionReceiver;
65    }
66
67    void setOutline(const SkPath* outline) {
68        if (!outline) {
69            mOutline.reset();
70        } else {
71            mOutline = *outline;
72        }
73    }
74
75    void setClipToOutline(bool clipToOutline) {
76        mClipToOutline = clipToOutline;
77    }
78
79    void setStaticMatrix(SkMatrix* matrix) {
80        delete mStaticMatrix;
81        mStaticMatrix = new SkMatrix(*matrix);
82    }
83
84    // Can return NULL
85    SkMatrix* getStaticMatrix() {
86        return mStaticMatrix;
87    }
88
89    void setAnimationMatrix(SkMatrix* matrix) {
90        delete mAnimationMatrix;
91        if (matrix) {
92            mAnimationMatrix = new SkMatrix(*matrix);
93        } else {
94            mAnimationMatrix = NULL;
95        }
96    }
97
98    void setAlpha(float alpha) {
99        alpha = fminf(1.0f, fmaxf(0.0f, alpha));
100        if (alpha != mAlpha) {
101            mAlpha = alpha;
102        }
103    }
104
105    float getAlpha() const {
106        return mAlpha;
107    }
108
109    void setHasOverlappingRendering(bool hasOverlappingRendering) {
110        mHasOverlappingRendering = hasOverlappingRendering;
111    }
112
113    bool hasOverlappingRendering() const {
114        return mHasOverlappingRendering;
115    }
116
117    void setTranslationX(float translationX) {
118        if (translationX != mTranslationX) {
119            mTranslationX = translationX;
120            onTranslationUpdate();
121        }
122    }
123
124    float getTranslationX() const {
125        return mTranslationX;
126    }
127
128    void setTranslationY(float translationY) {
129        if (translationY != mTranslationY) {
130            mTranslationY = translationY;
131            onTranslationUpdate();
132        }
133    }
134
135    float getTranslationY() const {
136        return mTranslationY;
137    }
138
139    void setTranslationZ(float translationZ) {
140        if (translationZ != mTranslationZ) {
141            mTranslationZ = translationZ;
142            onTranslationUpdate();
143        }
144    }
145
146    float getTranslationZ() const {
147        return mTranslationZ;
148    }
149
150    void setRotation(float rotation) {
151        if (rotation != mRotation) {
152            mRotation = rotation;
153            mMatrixDirty = true;
154            if (mRotation == 0.0f) {
155                mMatrixFlags &= ~ROTATION;
156            } else {
157                mMatrixFlags |= ROTATION;
158            }
159        }
160    }
161
162    float getRotation() const {
163        return mRotation;
164    }
165
166    void setRotationX(float rotationX) {
167        if (rotationX != mRotationX) {
168            mRotationX = rotationX;
169            mMatrixDirty = true;
170            if (mRotationX == 0.0f && mRotationY == 0.0f) {
171                mMatrixFlags &= ~ROTATION_3D;
172            } else {
173                mMatrixFlags |= ROTATION_3D;
174            }
175        }
176    }
177
178    float getRotationX() const {
179        return mRotationX;
180    }
181
182    void setRotationY(float rotationY) {
183        if (rotationY != mRotationY) {
184            mRotationY = rotationY;
185            mMatrixDirty = true;
186            if (mRotationX == 0.0f && mRotationY == 0.0f) {
187                mMatrixFlags &= ~ROTATION_3D;
188            } else {
189                mMatrixFlags |= ROTATION_3D;
190            }
191        }
192    }
193
194    float getRotationY() const {
195        return mRotationY;
196    }
197
198    void setScaleX(float scaleX) {
199        if (scaleX != mScaleX) {
200            mScaleX = scaleX;
201            mMatrixDirty = true;
202            if (mScaleX == 1.0f && mScaleY == 1.0f) {
203                mMatrixFlags &= ~SCALE;
204            } else {
205                mMatrixFlags |= SCALE;
206            }
207        }
208    }
209
210    float getScaleX() const {
211        return mScaleX;
212    }
213
214    void setScaleY(float scaleY) {
215        if (scaleY != mScaleY) {
216            mScaleY = scaleY;
217            mMatrixDirty = true;
218            if (mScaleX == 1.0f && mScaleY == 1.0f) {
219                mMatrixFlags &= ~SCALE;
220            } else {
221                mMatrixFlags |= SCALE;
222            }
223        }
224    }
225
226    float getScaleY() const {
227        return mScaleY;
228    }
229
230    void setPivotX(float pivotX) {
231        mPivotX = pivotX;
232        mMatrixDirty = true;
233        if (mPivotX == 0.0f && mPivotY == 0.0f) {
234            mMatrixFlags &= ~PIVOT;
235        } else {
236            mMatrixFlags |= PIVOT;
237        }
238        mPivotExplicitlySet = true;
239    }
240
241    ANDROID_API float getPivotX();
242
243    void setPivotY(float pivotY) {
244        mPivotY = pivotY;
245        mMatrixDirty = true;
246        if (mPivotX == 0.0f && mPivotY == 0.0f) {
247            mMatrixFlags &= ~PIVOT;
248        } else {
249            mMatrixFlags |= PIVOT;
250        }
251        mPivotExplicitlySet = true;
252    }
253
254    ANDROID_API float getPivotY();
255
256    void setCameraDistance(float distance) {
257        if (distance != mCameraDistance) {
258            mCameraDistance = distance;
259            mMatrixDirty = true;
260            if (!mTransformCamera) {
261                mTransformCamera = new Sk3DView();
262                mTransformMatrix3D = new SkMatrix();
263            }
264            mTransformCamera->setCameraLocation(0, 0, distance);
265        }
266    }
267
268    float getCameraDistance() const {
269        return mCameraDistance;
270    }
271
272    void setLeft(int left) {
273        if (left != mLeft) {
274            mLeft = left;
275            mWidth = mRight - mLeft;
276            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
277                mMatrixDirty = true;
278            }
279        }
280    }
281
282    float getLeft() const {
283        return mLeft;
284    }
285
286    void setTop(int top) {
287        if (top != mTop) {
288            mTop = top;
289            mHeight = mBottom - mTop;
290            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
291                mMatrixDirty = true;
292            }
293        }
294    }
295
296    float getTop() const {
297        return mTop;
298    }
299
300    void setRight(int right) {
301        if (right != mRight) {
302            mRight = right;
303            mWidth = mRight - mLeft;
304            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
305                mMatrixDirty = true;
306            }
307        }
308    }
309
310    float getRight() const {
311        return mRight;
312    }
313
314    void setBottom(int bottom) {
315        if (bottom != mBottom) {
316            mBottom = bottom;
317            mHeight = mBottom - mTop;
318            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
319                mMatrixDirty = true;
320            }
321        }
322    }
323
324    float getBottom() const {
325        return mBottom;
326    }
327
328    void setLeftTop(int left, int top) {
329        if (left != mLeft || top != mTop) {
330            mLeft = left;
331            mTop = top;
332            mWidth = mRight - mLeft;
333            mHeight = mBottom - mTop;
334            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
335                mMatrixDirty = true;
336            }
337        }
338    }
339
340    void setLeftTopRightBottom(int left, int top, int right, int bottom) {
341        if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
342            mLeft = left;
343            mTop = top;
344            mRight = right;
345            mBottom = bottom;
346            mWidth = mRight - mLeft;
347            mHeight = mBottom - mTop;
348            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
349                mMatrixDirty = true;
350            }
351        }
352    }
353
354    void offsetLeftRight(float offset) {
355        if (offset != 0) {
356            mLeft += offset;
357            mRight += offset;
358            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
359                mMatrixDirty = true;
360            }
361        }
362    }
363
364    void offsetTopBottom(float offset) {
365        if (offset != 0) {
366            mTop += offset;
367            mBottom += offset;
368            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
369                mMatrixDirty = true;
370            }
371        }
372    }
373
374    void setCaching(bool caching) {
375        mCaching = caching;
376    }
377
378    int getWidth() {
379        return mWidth;
380    }
381
382    int getHeight() {
383        return mHeight;
384    }
385
386private:
387    void onTranslationUpdate() {
388        mMatrixDirty = true;
389        if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) {
390            mMatrixFlags &= ~TRANSLATION;
391        } else {
392            mMatrixFlags |= TRANSLATION;
393        }
394    }
395
396    void updateMatrix();
397
398    // Rendering properties
399    bool mClipToBounds;
400    bool mProjectBackwards;
401    bool mProjectionReceiver;
402    SkPath mOutline;
403    bool mClipToOutline;
404    float mAlpha;
405    bool mHasOverlappingRendering;
406    float mTranslationX, mTranslationY, mTranslationZ;
407    float mRotation, mRotationX, mRotationY;
408    float mScaleX, mScaleY;
409    float mPivotX, mPivotY;
410    float mCameraDistance;
411    int mLeft, mTop, mRight, mBottom;
412    int mWidth, mHeight;
413    int mPrevWidth, mPrevHeight;
414    bool mPivotExplicitlySet;
415    bool mMatrixDirty;
416    bool mMatrixIsIdentity;
417
418    /**
419     * Stores the total transformation of the DisplayList based upon its scalar
420     * translate/rotate/scale properties.
421     *
422     * In the common translation-only case, the matrix isn't allocated and the mTranslation
423     * properties are used directly.
424     */
425    Matrix4* mTransformMatrix;
426    uint32_t mMatrixFlags;
427    Sk3DView* mTransformCamera;
428    SkMatrix* mTransformMatrix3D;
429    SkMatrix* mStaticMatrix;
430    SkMatrix* mAnimationMatrix;
431    bool mCaching;
432
433    friend class RenderNode;
434};
435
436} /* namespace uirenderer */
437} /* namespace android */
438
439#endif /* RENDERNODEPROPERTIES_H_ */
440