blob: 0c8d07f83e2846747c702e05a742fa8e567d7d72 [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 */
Chris Craikb49f4462014-03-20 12:44:20 -070016#ifndef RENDERNODEPROPERTIES_H
17#define RENDERNODEPROPERTIES_H
John Reckacb6f072014-03-12 16:11:23 -070018
John Recke45b1fd2014-04-15 09:50:16 -070019#include <algorithm>
John Reckacb6f072014-03-12 16:11:23 -070020#include <stddef.h>
John Recke45b1fd2014-04-15 09:50:16 -070021#include <vector>
John Reckacb6f072014-03-12 16:11:23 -070022#include <cutils/compiler.h>
23#include <androidfw/ResourceTypes.h>
Chris Craikfe02b4b2014-06-16 16:34:29 -070024#include <utils/Log.h>
John Reckacb6f072014-03-12 16:11:23 -070025
26#include <SkCamera.h>
27#include <SkMatrix.h>
Chris Craik8c271ca2014-03-25 10:33:01 -070028#include <SkRegion.h>
Chris Craikb49f4462014-03-20 12:44:20 -070029
John Recke45b1fd2014-04-15 09:50:16 -070030#include "Animator.h"
Chris Craikb49f4462014-03-20 12:44:20 -070031#include "Rect.h"
Chris Craik8c271ca2014-03-25 10:33:01 -070032#include "RevealClip.h"
Chris Craikb49f4462014-03-20 12:44:20 -070033#include "Outline.h"
John Reck293e8682014-06-17 10:34:02 -070034#include "utils/MathUtils.h"
John Reckacb6f072014-03-12 16:11:23 -070035
John Reckacb6f072014-03-12 16:11:23 -070036class SkBitmap;
John Reck25fbb3f2014-06-12 13:46:45 -070037class SkColorFilter;
John Reckacb6f072014-03-12 16:11:23 -070038class SkPaint;
John Reckacb6f072014-03-12 16:11:23 -070039
40namespace android {
41namespace uirenderer {
42
43class Matrix4;
44class RenderNode;
John Reck25fbb3f2014-06-12 13:46:45 -070045class RenderProperties;
John Reckacb6f072014-03-12 16:11:23 -070046
John Reck79c7de72014-05-23 10:33:31 -070047// The __VA_ARGS__ will be executed if a & b are not equal
48#define RP_SET(a, b, ...) (a != b ? (a = b, ##__VA_ARGS__, true) : false)
49#define RP_SET_AND_DIRTY(a, b) RP_SET(a, b, mPrimitiveFields.mMatrixOrPivotDirty = true)
50
John Reck25fbb3f2014-06-12 13:46:45 -070051// Keep in sync with View.java:LAYER_TYPE_*
52enum LayerType {
53 kLayerTypeNone = 0,
54 // Although we cannot build the software layer directly (must be done at
55 // record time), this information is used when applying alpha.
56 kLayerTypeSoftware = 1,
57 kLayerTypeRenderLayer = 2,
58 // TODO: LayerTypeSurfaceTexture? Maybe?
59};
60
Chris Craika753f4c2014-07-24 12:39:17 -070061enum ClippingFlags {
62 CLIP_TO_BOUNDS = 0x1 << 0,
63 CLIP_TO_CLIP_BOUNDS = 0x1 << 1,
64};
65
John Reck25fbb3f2014-06-12 13:46:45 -070066class ANDROID_API LayerProperties {
67public:
68 bool setType(LayerType type) {
69 if (RP_SET(mType, type)) {
70 reset();
71 return true;
72 }
73 return false;
74 }
75
76 LayerType type() const {
77 return mType;
78 }
79
80 bool setOpaque(bool opaque) {
81 return RP_SET(mOpaque, opaque);
82 }
83
84 bool opaque() const {
85 return mOpaque;
86 }
87
88 bool setAlpha(uint8_t alpha) {
89 return RP_SET(mAlpha, alpha);
90 }
91
92 uint8_t alpha() const {
93 return mAlpha;
94 }
95
96 bool setXferMode(SkXfermode::Mode mode) {
97 return RP_SET(mMode, mode);
98 }
99
100 SkXfermode::Mode xferMode() const {
101 return mMode;
102 }
103
104 bool setColorFilter(SkColorFilter* filter);
105
106 SkColorFilter* colorFilter() const {
107 return mColorFilter;
108 }
109
110 // Sets alpha, xfermode, and colorfilter from an SkPaint
111 // paint may be NULL, in which case defaults will be set
112 bool setFromPaint(const SkPaint* paint);
113
114 bool needsBlending() const {
115 return !opaque() || alpha() < 255;
116 }
117
118 LayerProperties& operator=(const LayerProperties& other);
119
120private:
121 LayerProperties();
122 ~LayerProperties();
123 void reset();
124
125 friend class RenderProperties;
126
127 LayerType mType;
128 // Whether or not that Layer's content is opaque, doesn't include alpha
129 bool mOpaque;
130 uint8_t mAlpha;
131 SkXfermode::Mode mMode;
132 SkColorFilter* mColorFilter;
133};
134
John Reckacb6f072014-03-12 16:11:23 -0700135/*
136 * Data structure that holds the properties for a RenderNode
137 */
John Reck25fbb3f2014-06-12 13:46:45 -0700138class ANDROID_API RenderProperties {
John Reckacb6f072014-03-12 16:11:23 -0700139public:
140 RenderProperties();
141 virtual ~RenderProperties();
142
Chris Craika753f4c2014-07-24 12:39:17 -0700143 static bool setFlag(int flag, bool newValue, int* outFlags) {
144 if (newValue) {
145 if (!(flag & *outFlags)) {
146 *outFlags |= flag;
147 return true;
148 }
149 return false;
150 } else {
151 if (flag & *outFlags) {
152 *outFlags &= ~flag;
153 return true;
154 }
155 return false;
156 }
157 }
158
John Reckd0a0b2a2014-03-20 16:28:56 -0700159 RenderProperties& operator=(const RenderProperties& other);
160
John Reck79c7de72014-05-23 10:33:31 -0700161 bool setClipToBounds(bool clipToBounds) {
Chris Craika753f4c2014-07-24 12:39:17 -0700162 return setFlag(CLIP_TO_BOUNDS, clipToBounds, &mPrimitiveFields.mClippingFlags);
163 }
164
165 bool setClipBounds(const Rect& clipBounds) {
166 bool ret = setFlag(CLIP_TO_CLIP_BOUNDS, true, &mPrimitiveFields.mClippingFlags);
167 return RP_SET(mPrimitiveFields.mClipBounds, clipBounds) || ret;
168 }
169
170 bool setClipBoundsEmpty() {
171 return setFlag(CLIP_TO_CLIP_BOUNDS, false, &mPrimitiveFields.mClippingFlags);
John Reckacb6f072014-03-12 16:11:23 -0700172 }
173
John Reck79c7de72014-05-23 10:33:31 -0700174 bool setProjectBackwards(bool shouldProject) {
175 return RP_SET(mPrimitiveFields.mProjectBackwards, shouldProject);
John Reckacb6f072014-03-12 16:11:23 -0700176 }
177
John Reck79c7de72014-05-23 10:33:31 -0700178 bool setProjectionReceiver(bool shouldRecieve) {
179 return RP_SET(mPrimitiveFields.mProjectionReceiver, shouldRecieve);
John Reckacb6f072014-03-12 16:11:23 -0700180 }
181
John Reckd0a0b2a2014-03-20 16:28:56 -0700182 bool isProjectionReceiver() const {
183 return mPrimitiveFields.mProjectionReceiver;
John Reckacb6f072014-03-12 16:11:23 -0700184 }
185
John Reck79c7de72014-05-23 10:33:31 -0700186 bool setStaticMatrix(const SkMatrix* matrix) {
John Reckacb6f072014-03-12 16:11:23 -0700187 delete mStaticMatrix;
John Reckd0a0b2a2014-03-20 16:28:56 -0700188 if (matrix) {
189 mStaticMatrix = new SkMatrix(*matrix);
190 } else {
191 mStaticMatrix = NULL;
192 }
John Reck79c7de72014-05-23 10:33:31 -0700193 return true;
John Reckacb6f072014-03-12 16:11:23 -0700194 }
195
196 // Can return NULL
John Reckd0a0b2a2014-03-20 16:28:56 -0700197 const SkMatrix* getStaticMatrix() const {
John Reckacb6f072014-03-12 16:11:23 -0700198 return mStaticMatrix;
199 }
200
John Reck79c7de72014-05-23 10:33:31 -0700201 bool setAnimationMatrix(const SkMatrix* matrix) {
John Reckacb6f072014-03-12 16:11:23 -0700202 delete mAnimationMatrix;
203 if (matrix) {
204 mAnimationMatrix = new SkMatrix(*matrix);
205 } else {
206 mAnimationMatrix = NULL;
207 }
John Reck79c7de72014-05-23 10:33:31 -0700208 return true;
John Reckacb6f072014-03-12 16:11:23 -0700209 }
210
John Reck79c7de72014-05-23 10:33:31 -0700211 bool setAlpha(float alpha) {
John Reck3b52c032014-08-06 10:19:32 -0700212 alpha = MathUtils::clampAlpha(alpha);
John Reck79c7de72014-05-23 10:33:31 -0700213 return RP_SET(mPrimitiveFields.mAlpha, alpha);
John Reckacb6f072014-03-12 16:11:23 -0700214 }
215
216 float getAlpha() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700217 return mPrimitiveFields.mAlpha;
John Reckacb6f072014-03-12 16:11:23 -0700218 }
219
John Reck79c7de72014-05-23 10:33:31 -0700220 bool setHasOverlappingRendering(bool hasOverlappingRendering) {
221 return RP_SET(mPrimitiveFields.mHasOverlappingRendering, hasOverlappingRendering);
John Reckacb6f072014-03-12 16:11:23 -0700222 }
223
224 bool hasOverlappingRendering() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700225 return mPrimitiveFields.mHasOverlappingRendering;
John Reckacb6f072014-03-12 16:11:23 -0700226 }
227
John Reck79c7de72014-05-23 10:33:31 -0700228 bool setElevation(float elevation) {
229 return RP_SET(mPrimitiveFields.mElevation, elevation);
230 // Don't dirty matrix/pivot, since they don't respect Z
Chris Craikcc39e162014-04-25 18:34:11 -0700231 }
232
233 float getElevation() const {
234 return mPrimitiveFields.mElevation;
235 }
236
John Reck79c7de72014-05-23 10:33:31 -0700237 bool setTranslationX(float translationX) {
238 return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationX, translationX);
John Reckacb6f072014-03-12 16:11:23 -0700239 }
240
241 float getTranslationX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700242 return mPrimitiveFields.mTranslationX;
John Reckacb6f072014-03-12 16:11:23 -0700243 }
244
John Reck79c7de72014-05-23 10:33:31 -0700245 bool setTranslationY(float translationY) {
246 return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationY, translationY);
John Reckacb6f072014-03-12 16:11:23 -0700247 }
248
249 float getTranslationY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700250 return mPrimitiveFields.mTranslationY;
John Reckacb6f072014-03-12 16:11:23 -0700251 }
252
John Reck79c7de72014-05-23 10:33:31 -0700253 bool setTranslationZ(float translationZ) {
254 return RP_SET(mPrimitiveFields.mTranslationZ, translationZ);
255 // mMatrixOrPivotDirty not set, since matrix doesn't respect Z
John Reckacb6f072014-03-12 16:11:23 -0700256 }
257
258 float getTranslationZ() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700259 return mPrimitiveFields.mTranslationZ;
John Reckacb6f072014-03-12 16:11:23 -0700260 }
261
John Recke45b1fd2014-04-15 09:50:16 -0700262 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700263 bool setX(float value) {
264 return setTranslationX(value - getLeft());
John Recke45b1fd2014-04-15 09:50:16 -0700265 }
266
267 // Animation helper
268 float getX() const {
269 return getLeft() + getTranslationX();
270 }
271
272 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700273 bool setY(float value) {
274 return setTranslationY(value - getTop());
John Recke45b1fd2014-04-15 09:50:16 -0700275 }
276
277 // Animation helper
278 float getY() const {
279 return getTop() + getTranslationY();
280 }
281
282 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700283 bool setZ(float value) {
284 return setTranslationZ(value - getElevation());
John Recke45b1fd2014-04-15 09:50:16 -0700285 }
286
Chris Craikcc39e162014-04-25 18:34:11 -0700287 float getZ() const {
288 return getElevation() + getTranslationZ();
289 }
290
John Reck79c7de72014-05-23 10:33:31 -0700291 bool setRotation(float rotation) {
292 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotation, rotation);
John Reckacb6f072014-03-12 16:11:23 -0700293 }
294
295 float getRotation() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700296 return mPrimitiveFields.mRotation;
John Reckacb6f072014-03-12 16:11:23 -0700297 }
298
John Reck79c7de72014-05-23 10:33:31 -0700299 bool setRotationX(float rotationX) {
300 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationX, rotationX);
John Reckacb6f072014-03-12 16:11:23 -0700301 }
302
303 float getRotationX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700304 return mPrimitiveFields.mRotationX;
John Reckacb6f072014-03-12 16:11:23 -0700305 }
306
John Reck79c7de72014-05-23 10:33:31 -0700307 bool setRotationY(float rotationY) {
308 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationY, rotationY);
John Reckacb6f072014-03-12 16:11:23 -0700309 }
310
311 float getRotationY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700312 return mPrimitiveFields.mRotationY;
John Reckacb6f072014-03-12 16:11:23 -0700313 }
314
John Reck79c7de72014-05-23 10:33:31 -0700315 bool setScaleX(float scaleX) {
316 return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleX, scaleX);
John Reckacb6f072014-03-12 16:11:23 -0700317 }
318
319 float getScaleX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700320 return mPrimitiveFields.mScaleX;
John Reckacb6f072014-03-12 16:11:23 -0700321 }
322
John Reck79c7de72014-05-23 10:33:31 -0700323 bool setScaleY(float scaleY) {
324 return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleY, scaleY);
John Reckacb6f072014-03-12 16:11:23 -0700325 }
326
327 float getScaleY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700328 return mPrimitiveFields.mScaleY;
John Reckacb6f072014-03-12 16:11:23 -0700329 }
330
John Reck79c7de72014-05-23 10:33:31 -0700331 bool setPivotX(float pivotX) {
332 if (RP_SET(mPrimitiveFields.mPivotX, pivotX)
333 || !mPrimitiveFields.mPivotExplicitlySet) {
334 mPrimitiveFields.mMatrixOrPivotDirty = true;
335 mPrimitiveFields.mPivotExplicitlySet = true;
336 return true;
337 }
338 return false;
John Reckacb6f072014-03-12 16:11:23 -0700339 }
340
John Reckd0a0b2a2014-03-20 16:28:56 -0700341 /* Note that getPivotX and getPivotY are adjusted by updateMatrix(),
John Reck79c7de72014-05-23 10:33:31 -0700342 * so the value returned may be stale if the RenderProperties has been
343 * modified since the last call to updateMatrix()
John Reckd0a0b2a2014-03-20 16:28:56 -0700344 */
345 float getPivotX() const {
346 return mPrimitiveFields.mPivotX;
347 }
John Reckacb6f072014-03-12 16:11:23 -0700348
John Reck79c7de72014-05-23 10:33:31 -0700349 bool setPivotY(float pivotY) {
350 if (RP_SET(mPrimitiveFields.mPivotY, pivotY)
351 || !mPrimitiveFields.mPivotExplicitlySet) {
352 mPrimitiveFields.mMatrixOrPivotDirty = true;
353 mPrimitiveFields.mPivotExplicitlySet = true;
354 return true;
355 }
356 return false;
John Reckacb6f072014-03-12 16:11:23 -0700357 }
358
John Reckd0a0b2a2014-03-20 16:28:56 -0700359 float getPivotY() const {
360 return mPrimitiveFields.mPivotY;
361 }
John Reckacb6f072014-03-12 16:11:23 -0700362
Chris Craik49e6c732014-03-31 12:34:11 -0700363 bool isPivotExplicitlySet() const {
364 return mPrimitiveFields.mPivotExplicitlySet;
365 }
366
John Reck79c7de72014-05-23 10:33:31 -0700367 bool setCameraDistance(float distance) {
Chris Craik49e6c732014-03-31 12:34:11 -0700368 if (distance != getCameraDistance()) {
John Reckf7483e32014-04-11 08:54:47 -0700369 mPrimitiveFields.mMatrixOrPivotDirty = true;
Chris Craik49e6c732014-03-31 12:34:11 -0700370 mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance);
John Reck79c7de72014-05-23 10:33:31 -0700371 return true;
John Reckacb6f072014-03-12 16:11:23 -0700372 }
John Reck79c7de72014-05-23 10:33:31 -0700373 return false;
John Reckacb6f072014-03-12 16:11:23 -0700374 }
375
376 float getCameraDistance() const {
Chris Craik49e6c732014-03-31 12:34:11 -0700377 // TODO: update getCameraLocationZ() to be const
378 return const_cast<Sk3DView*>(&mComputedFields.mTransformCamera)->getCameraLocationZ();
John Reckacb6f072014-03-12 16:11:23 -0700379 }
380
John Reck79c7de72014-05-23 10:33:31 -0700381 bool setLeft(int left) {
382 if (RP_SET(mPrimitiveFields.mLeft, left)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700383 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
John Reckf7483e32014-04-11 08:54:47 -0700384 if (!mPrimitiveFields.mPivotExplicitlySet) {
385 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700386 }
John Reck79c7de72014-05-23 10:33:31 -0700387 return true;
John Reckacb6f072014-03-12 16:11:23 -0700388 }
John Reck79c7de72014-05-23 10:33:31 -0700389 return false;
John Reckacb6f072014-03-12 16:11:23 -0700390 }
391
392 float getLeft() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700393 return mPrimitiveFields.mLeft;
John Reckacb6f072014-03-12 16:11:23 -0700394 }
395
John Reck79c7de72014-05-23 10:33:31 -0700396 bool setTop(int top) {
397 if (RP_SET(mPrimitiveFields.mTop, top)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700398 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700399 if (!mPrimitiveFields.mPivotExplicitlySet) {
400 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700401 }
John Reck79c7de72014-05-23 10:33:31 -0700402 return true;
John Reckacb6f072014-03-12 16:11:23 -0700403 }
John Reck79c7de72014-05-23 10:33:31 -0700404 return false;
John Reckacb6f072014-03-12 16:11:23 -0700405 }
406
407 float getTop() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700408 return mPrimitiveFields.mTop;
John Reckacb6f072014-03-12 16:11:23 -0700409 }
410
John Reck79c7de72014-05-23 10:33:31 -0700411 bool setRight(int right) {
412 if (RP_SET(mPrimitiveFields.mRight, right)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700413 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
John Reckf7483e32014-04-11 08:54:47 -0700414 if (!mPrimitiveFields.mPivotExplicitlySet) {
415 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700416 }
John Reck79c7de72014-05-23 10:33:31 -0700417 return true;
John Reckacb6f072014-03-12 16:11:23 -0700418 }
John Reck79c7de72014-05-23 10:33:31 -0700419 return false;
John Reckacb6f072014-03-12 16:11:23 -0700420 }
421
422 float getRight() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700423 return mPrimitiveFields.mRight;
John Reckacb6f072014-03-12 16:11:23 -0700424 }
425
John Reck79c7de72014-05-23 10:33:31 -0700426 bool setBottom(int bottom) {
427 if (RP_SET(mPrimitiveFields.mBottom, bottom)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700428 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700429 if (!mPrimitiveFields.mPivotExplicitlySet) {
430 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700431 }
John Reck79c7de72014-05-23 10:33:31 -0700432 return true;
John Reckacb6f072014-03-12 16:11:23 -0700433 }
John Reck79c7de72014-05-23 10:33:31 -0700434 return false;
John Reckacb6f072014-03-12 16:11:23 -0700435 }
436
437 float getBottom() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700438 return mPrimitiveFields.mBottom;
John Reckacb6f072014-03-12 16:11:23 -0700439 }
440
John Reck79c7de72014-05-23 10:33:31 -0700441 bool setLeftTop(int left, int top) {
442 bool leftResult = setLeft(left);
443 bool topResult = setTop(top);
444 return leftResult || topResult;
John Reckacb6f072014-03-12 16:11:23 -0700445 }
446
John Reck79c7de72014-05-23 10:33:31 -0700447 bool setLeftTopRightBottom(int left, int top, int right, int bottom) {
Chris Craikcc39e162014-04-25 18:34:11 -0700448 if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop
449 || right != mPrimitiveFields.mRight || bottom != mPrimitiveFields.mBottom) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700450 mPrimitiveFields.mLeft = left;
451 mPrimitiveFields.mTop = top;
452 mPrimitiveFields.mRight = right;
453 mPrimitiveFields.mBottom = bottom;
454 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
455 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700456 if (!mPrimitiveFields.mPivotExplicitlySet) {
457 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700458 }
John Reck79c7de72014-05-23 10:33:31 -0700459 return true;
John Reckacb6f072014-03-12 16:11:23 -0700460 }
John Reck79c7de72014-05-23 10:33:31 -0700461 return false;
John Reckacb6f072014-03-12 16:11:23 -0700462 }
463
Chris Craika753f4c2014-07-24 12:39:17 -0700464 bool offsetLeftRight(int offset) {
John Reckacb6f072014-03-12 16:11:23 -0700465 if (offset != 0) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700466 mPrimitiveFields.mLeft += offset;
467 mPrimitiveFields.mRight += offset;
John Reck79c7de72014-05-23 10:33:31 -0700468 return true;
John Reckacb6f072014-03-12 16:11:23 -0700469 }
John Reck79c7de72014-05-23 10:33:31 -0700470 return false;
John Reckacb6f072014-03-12 16:11:23 -0700471 }
472
Chris Craika753f4c2014-07-24 12:39:17 -0700473 bool offsetTopBottom(int offset) {
John Reckacb6f072014-03-12 16:11:23 -0700474 if (offset != 0) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700475 mPrimitiveFields.mTop += offset;
476 mPrimitiveFields.mBottom += offset;
John Reck79c7de72014-05-23 10:33:31 -0700477 return true;
John Reckacb6f072014-03-12 16:11:23 -0700478 }
John Reck79c7de72014-05-23 10:33:31 -0700479 return false;
John Reckacb6f072014-03-12 16:11:23 -0700480 }
481
Chris Craikb49f4462014-03-20 12:44:20 -0700482 int getWidth() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700483 return mPrimitiveFields.mWidth;
John Reckacb6f072014-03-12 16:11:23 -0700484 }
485
Chris Craikb49f4462014-03-20 12:44:20 -0700486 int getHeight() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700487 return mPrimitiveFields.mHeight;
John Reckacb6f072014-03-12 16:11:23 -0700488 }
489
John Reckd0a0b2a2014-03-20 16:28:56 -0700490 const SkMatrix* getAnimationMatrix() const {
491 return mAnimationMatrix;
492 }
493
John Reckf7483e32014-04-11 08:54:47 -0700494 bool hasTransformMatrix() const {
495 return getTransformMatrix() && !getTransformMatrix()->isIdentity();
496 }
497
498 // May only call this if hasTransformMatrix() is true
499 bool isTransformTranslateOnly() const {
500 return getTransformMatrix()->getType() == SkMatrix::kTranslate_Mask;
John Reckd0a0b2a2014-03-20 16:28:56 -0700501 }
502
Chris Craik49e6c732014-03-31 12:34:11 -0700503 const SkMatrix* getTransformMatrix() const {
John Reckf7483e32014-04-11 08:54:47 -0700504 LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mMatrixOrPivotDirty, "Cannot get a dirty matrix!");
John Reckd0a0b2a2014-03-20 16:28:56 -0700505 return mComputedFields.mTransformMatrix;
506 }
507
Chris Craika753f4c2014-07-24 12:39:17 -0700508 int getClippingFlags() const {
509 return mPrimitiveFields.mClippingFlags;
510 }
511
John Reckd0a0b2a2014-03-20 16:28:56 -0700512 bool getClipToBounds() const {
Chris Craika753f4c2014-07-24 12:39:17 -0700513 return mPrimitiveFields.mClippingFlags & CLIP_TO_BOUNDS;
514 }
515
516 void getClippingRectForFlags(uint32_t flags, Rect* outRect) const {
517 if (flags & CLIP_TO_BOUNDS) {
518 outRect->set(0, 0, getWidth(), getHeight());
519 if (flags & CLIP_TO_CLIP_BOUNDS) {
520 outRect->intersect(mPrimitiveFields.mClipBounds);
521 }
522 } else {
523 outRect->set(mPrimitiveFields.mClipBounds);
524 }
John Reckd0a0b2a2014-03-20 16:28:56 -0700525 }
526
527 bool getHasOverlappingRendering() const {
528 return mPrimitiveFields.mHasOverlappingRendering;
529 }
530
531 const Outline& getOutline() const {
532 return mPrimitiveFields.mOutline;
533 }
534
Chris Craik8c271ca2014-03-25 10:33:01 -0700535 const RevealClip& getRevealClip() const {
536 return mPrimitiveFields.mRevealClip;
537 }
538
John Reckd0a0b2a2014-03-20 16:28:56 -0700539 bool getProjectBackwards() const {
540 return mPrimitiveFields.mProjectBackwards;
541 }
542
543 void debugOutputProperties(const int level) const;
544
John Reck25fbb3f2014-06-12 13:46:45 -0700545 void updateMatrix();
John Reckd0a0b2a2014-03-20 16:28:56 -0700546
547 Outline& mutableOutline() {
548 return mPrimitiveFields.mOutline;
Chris Craikb49f4462014-03-20 12:44:20 -0700549 }
550
Chris Craik8c271ca2014-03-25 10:33:01 -0700551 RevealClip& mutableRevealClip() {
552 return mPrimitiveFields.mRevealClip;
553 }
554
John Reck25fbb3f2014-06-12 13:46:45 -0700555 const LayerProperties& layerProperties() const {
556 return mLayerProperties;
557 }
558
559 LayerProperties& mutateLayerProperties() {
560 return mLayerProperties;
561 }
562
John Reck293e8682014-06-17 10:34:02 -0700563 // Returns true if damage calculations should be clipped to bounds
564 // TODO: Figure out something better for getZ(), as children should still be
565 // clipped to this RP's bounds. But as we will damage -INT_MAX to INT_MAX
566 // for this RP's getZ() anyway, this can be optimized when we have a
567 // Z damage estimate instead of INT_MAX
568 bool getClipDamageToBounds() const {
569 return getClipToBounds() && (getZ() <= 0 || getOutline().isEmpty());
570 }
571
John Reckacb6f072014-03-12 16:11:23 -0700572private:
John Reckacb6f072014-03-12 16:11:23 -0700573 // Rendering properties
John Reckd0a0b2a2014-03-20 16:28:56 -0700574 struct PrimitiveFields {
575 PrimitiveFields();
John Reckacb6f072014-03-12 16:11:23 -0700576
John Reckd0a0b2a2014-03-20 16:28:56 -0700577 Outline mOutline;
Chris Craik8c271ca2014-03-25 10:33:01 -0700578 RevealClip mRevealClip;
Chris Craika753f4c2014-07-24 12:39:17 -0700579 int mClippingFlags;
John Reckd0a0b2a2014-03-20 16:28:56 -0700580 bool mProjectBackwards;
581 bool mProjectionReceiver;
582 float mAlpha;
583 bool mHasOverlappingRendering;
Chris Craikcc39e162014-04-25 18:34:11 -0700584 float mElevation;
John Reckd0a0b2a2014-03-20 16:28:56 -0700585 float mTranslationX, mTranslationY, mTranslationZ;
586 float mRotation, mRotationX, mRotationY;
587 float mScaleX, mScaleY;
588 float mPivotX, mPivotY;
589 int mLeft, mTop, mRight, mBottom;
590 int mWidth, mHeight;
John Reckd0a0b2a2014-03-20 16:28:56 -0700591 bool mPivotExplicitlySet;
John Reckf7483e32014-04-11 08:54:47 -0700592 bool mMatrixOrPivotDirty;
Chris Craika753f4c2014-07-24 12:39:17 -0700593 Rect mClipBounds;
John Reckd0a0b2a2014-03-20 16:28:56 -0700594 } mPrimitiveFields;
595
John Reckacb6f072014-03-12 16:11:23 -0700596 SkMatrix* mStaticMatrix;
597 SkMatrix* mAnimationMatrix;
John Reck25fbb3f2014-06-12 13:46:45 -0700598 LayerProperties mLayerProperties;
John Reckacb6f072014-03-12 16:11:23 -0700599
John Reckd0a0b2a2014-03-20 16:28:56 -0700600 /**
601 * These fields are all generated from other properties and are not set directly.
602 */
603 struct ComputedFields {
604 ComputedFields();
605 ~ComputedFields();
606
607 /**
608 * Stores the total transformation of the DisplayList based upon its scalar
609 * translate/rotate/scale properties.
610 *
Chris Craik49e6c732014-03-31 12:34:11 -0700611 * In the common translation-only case, the matrix isn't necessarily allocated,
612 * and the mTranslation properties are used directly.
John Reckd0a0b2a2014-03-20 16:28:56 -0700613 */
Chris Craik49e6c732014-03-31 12:34:11 -0700614 SkMatrix* mTransformMatrix;
615
616 Sk3DView mTransformCamera;
John Reckd0a0b2a2014-03-20 16:28:56 -0700617 } mComputedFields;
John Reckacb6f072014-03-12 16:11:23 -0700618};
619
620} /* namespace uirenderer */
621} /* namespace android */
622
Chris Craikb49f4462014-03-20 12:44:20 -0700623#endif /* RENDERNODEPROPERTIES_H */