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