blob: 6e3b8aebca3bcb3b19b28fd48f34c823c3e53f40 [file] [log] [blame]
John Reckacb6f072014-03-12 16:11:23 -07001/*
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
John Reckacb6f072014-03-12 16:11:23 -070055 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;
John Reckacb6f072014-03-12 16:11:23 -0700404 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_ */