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