blob: f50e514f5d5de1ca49ccba60b7820df82220a947 [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 Reckacb6f072014-03-12 16:11:23 -0700212 alpha = fminf(1.0f, fmaxf(0.0f, 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) {
Chris Craikfe02b4b2014-06-16 16:34:29 -0700316 LOG_ALWAYS_FATAL_IF(scaleX > 1000000, "invalid scaleX %e", scaleX);
John Reck79c7de72014-05-23 10:33:31 -0700317 return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleX, scaleX);
John Reckacb6f072014-03-12 16:11:23 -0700318 }
319
320 float getScaleX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700321 return mPrimitiveFields.mScaleX;
John Reckacb6f072014-03-12 16:11:23 -0700322 }
323
John Reck79c7de72014-05-23 10:33:31 -0700324 bool setScaleY(float scaleY) {
Chris Craikfe02b4b2014-06-16 16:34:29 -0700325 LOG_ALWAYS_FATAL_IF(scaleY > 1000000, "invalid scaleY %e", scaleY);
John Reck79c7de72014-05-23 10:33:31 -0700326 return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleY, scaleY);
John Reckacb6f072014-03-12 16:11:23 -0700327 }
328
329 float getScaleY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700330 return mPrimitiveFields.mScaleY;
John Reckacb6f072014-03-12 16:11:23 -0700331 }
332
John Reck79c7de72014-05-23 10:33:31 -0700333 bool setPivotX(float pivotX) {
334 if (RP_SET(mPrimitiveFields.mPivotX, pivotX)
335 || !mPrimitiveFields.mPivotExplicitlySet) {
336 mPrimitiveFields.mMatrixOrPivotDirty = true;
337 mPrimitiveFields.mPivotExplicitlySet = true;
338 return true;
339 }
340 return false;
John Reckacb6f072014-03-12 16:11:23 -0700341 }
342
John Reckd0a0b2a2014-03-20 16:28:56 -0700343 /* Note that getPivotX and getPivotY are adjusted by updateMatrix(),
John Reck79c7de72014-05-23 10:33:31 -0700344 * so the value returned may be stale if the RenderProperties has been
345 * modified since the last call to updateMatrix()
John Reckd0a0b2a2014-03-20 16:28:56 -0700346 */
347 float getPivotX() const {
348 return mPrimitiveFields.mPivotX;
349 }
John Reckacb6f072014-03-12 16:11:23 -0700350
John Reck79c7de72014-05-23 10:33:31 -0700351 bool setPivotY(float pivotY) {
352 if (RP_SET(mPrimitiveFields.mPivotY, pivotY)
353 || !mPrimitiveFields.mPivotExplicitlySet) {
354 mPrimitiveFields.mMatrixOrPivotDirty = true;
355 mPrimitiveFields.mPivotExplicitlySet = true;
356 return true;
357 }
358 return false;
John Reckacb6f072014-03-12 16:11:23 -0700359 }
360
John Reckd0a0b2a2014-03-20 16:28:56 -0700361 float getPivotY() const {
362 return mPrimitiveFields.mPivotY;
363 }
John Reckacb6f072014-03-12 16:11:23 -0700364
Chris Craik49e6c7392014-03-31 12:34:11 -0700365 bool isPivotExplicitlySet() const {
366 return mPrimitiveFields.mPivotExplicitlySet;
367 }
368
John Reck79c7de72014-05-23 10:33:31 -0700369 bool setCameraDistance(float distance) {
Chris Craik49e6c7392014-03-31 12:34:11 -0700370 if (distance != getCameraDistance()) {
John Reckf7483e32014-04-11 08:54:47 -0700371 mPrimitiveFields.mMatrixOrPivotDirty = true;
Chris Craik49e6c7392014-03-31 12:34:11 -0700372 mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance);
John Reck79c7de72014-05-23 10:33:31 -0700373 return true;
John Reckacb6f072014-03-12 16:11:23 -0700374 }
John Reck79c7de72014-05-23 10:33:31 -0700375 return false;
John Reckacb6f072014-03-12 16:11:23 -0700376 }
377
378 float getCameraDistance() const {
Chris Craik49e6c7392014-03-31 12:34:11 -0700379 // TODO: update getCameraLocationZ() to be const
380 return const_cast<Sk3DView*>(&mComputedFields.mTransformCamera)->getCameraLocationZ();
John Reckacb6f072014-03-12 16:11:23 -0700381 }
382
John Reck79c7de72014-05-23 10:33:31 -0700383 bool setLeft(int left) {
384 if (RP_SET(mPrimitiveFields.mLeft, left)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700385 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
John Reckf7483e32014-04-11 08:54:47 -0700386 if (!mPrimitiveFields.mPivotExplicitlySet) {
387 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700388 }
John Reck79c7de72014-05-23 10:33:31 -0700389 return true;
John Reckacb6f072014-03-12 16:11:23 -0700390 }
John Reck79c7de72014-05-23 10:33:31 -0700391 return false;
John Reckacb6f072014-03-12 16:11:23 -0700392 }
393
394 float getLeft() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700395 return mPrimitiveFields.mLeft;
John Reckacb6f072014-03-12 16:11:23 -0700396 }
397
John Reck79c7de72014-05-23 10:33:31 -0700398 bool setTop(int top) {
399 if (RP_SET(mPrimitiveFields.mTop, top)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700400 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700401 if (!mPrimitiveFields.mPivotExplicitlySet) {
402 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700403 }
John Reck79c7de72014-05-23 10:33:31 -0700404 return true;
John Reckacb6f072014-03-12 16:11:23 -0700405 }
John Reck79c7de72014-05-23 10:33:31 -0700406 return false;
John Reckacb6f072014-03-12 16:11:23 -0700407 }
408
409 float getTop() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700410 return mPrimitiveFields.mTop;
John Reckacb6f072014-03-12 16:11:23 -0700411 }
412
John Reck79c7de72014-05-23 10:33:31 -0700413 bool setRight(int right) {
414 if (RP_SET(mPrimitiveFields.mRight, right)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700415 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
John Reckf7483e32014-04-11 08:54:47 -0700416 if (!mPrimitiveFields.mPivotExplicitlySet) {
417 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700418 }
John Reck79c7de72014-05-23 10:33:31 -0700419 return true;
John Reckacb6f072014-03-12 16:11:23 -0700420 }
John Reck79c7de72014-05-23 10:33:31 -0700421 return false;
John Reckacb6f072014-03-12 16:11:23 -0700422 }
423
424 float getRight() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700425 return mPrimitiveFields.mRight;
John Reckacb6f072014-03-12 16:11:23 -0700426 }
427
John Reck79c7de72014-05-23 10:33:31 -0700428 bool setBottom(int bottom) {
429 if (RP_SET(mPrimitiveFields.mBottom, bottom)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700430 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700431 if (!mPrimitiveFields.mPivotExplicitlySet) {
432 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700433 }
John Reck79c7de72014-05-23 10:33:31 -0700434 return true;
John Reckacb6f072014-03-12 16:11:23 -0700435 }
John Reck79c7de72014-05-23 10:33:31 -0700436 return false;
John Reckacb6f072014-03-12 16:11:23 -0700437 }
438
439 float getBottom() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700440 return mPrimitiveFields.mBottom;
John Reckacb6f072014-03-12 16:11:23 -0700441 }
442
John Reck79c7de72014-05-23 10:33:31 -0700443 bool setLeftTop(int left, int top) {
444 bool leftResult = setLeft(left);
445 bool topResult = setTop(top);
446 return leftResult || topResult;
John Reckacb6f072014-03-12 16:11:23 -0700447 }
448
John Reck79c7de72014-05-23 10:33:31 -0700449 bool setLeftTopRightBottom(int left, int top, int right, int bottom) {
Chris Craikcc39e162014-04-25 18:34:11 -0700450 if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop
451 || right != mPrimitiveFields.mRight || bottom != mPrimitiveFields.mBottom) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700452 mPrimitiveFields.mLeft = left;
453 mPrimitiveFields.mTop = top;
454 mPrimitiveFields.mRight = right;
455 mPrimitiveFields.mBottom = bottom;
456 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
457 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700458 if (!mPrimitiveFields.mPivotExplicitlySet) {
459 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700460 }
John Reck79c7de72014-05-23 10:33:31 -0700461 return true;
John Reckacb6f072014-03-12 16:11:23 -0700462 }
John Reck79c7de72014-05-23 10:33:31 -0700463 return false;
John Reckacb6f072014-03-12 16:11:23 -0700464 }
465
Chris Craika753f4c2014-07-24 12:39:17 -0700466 bool offsetLeftRight(int offset) {
John Reckacb6f072014-03-12 16:11:23 -0700467 if (offset != 0) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700468 mPrimitiveFields.mLeft += offset;
469 mPrimitiveFields.mRight += offset;
John Reck79c7de72014-05-23 10:33:31 -0700470 return true;
John Reckacb6f072014-03-12 16:11:23 -0700471 }
John Reck79c7de72014-05-23 10:33:31 -0700472 return false;
John Reckacb6f072014-03-12 16:11:23 -0700473 }
474
Chris Craika753f4c2014-07-24 12:39:17 -0700475 bool offsetTopBottom(int offset) {
John Reckacb6f072014-03-12 16:11:23 -0700476 if (offset != 0) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700477 mPrimitiveFields.mTop += offset;
478 mPrimitiveFields.mBottom += offset;
John Reck79c7de72014-05-23 10:33:31 -0700479 return true;
John Reckacb6f072014-03-12 16:11:23 -0700480 }
John Reck79c7de72014-05-23 10:33:31 -0700481 return false;
John Reckacb6f072014-03-12 16:11:23 -0700482 }
483
Chris Craikb49f4462014-03-20 12:44:20 -0700484 int getWidth() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700485 return mPrimitiveFields.mWidth;
John Reckacb6f072014-03-12 16:11:23 -0700486 }
487
Chris Craikb49f4462014-03-20 12:44:20 -0700488 int getHeight() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700489 return mPrimitiveFields.mHeight;
John Reckacb6f072014-03-12 16:11:23 -0700490 }
491
John Reckd0a0b2a2014-03-20 16:28:56 -0700492 const SkMatrix* getAnimationMatrix() const {
493 return mAnimationMatrix;
494 }
495
John Reckf7483e32014-04-11 08:54:47 -0700496 bool hasTransformMatrix() const {
497 return getTransformMatrix() && !getTransformMatrix()->isIdentity();
498 }
499
500 // May only call this if hasTransformMatrix() is true
501 bool isTransformTranslateOnly() const {
502 return getTransformMatrix()->getType() == SkMatrix::kTranslate_Mask;
John Reckd0a0b2a2014-03-20 16:28:56 -0700503 }
504
Chris Craik49e6c7392014-03-31 12:34:11 -0700505 const SkMatrix* getTransformMatrix() const {
John Reckf7483e32014-04-11 08:54:47 -0700506 LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mMatrixOrPivotDirty, "Cannot get a dirty matrix!");
John Reckd0a0b2a2014-03-20 16:28:56 -0700507 return mComputedFields.mTransformMatrix;
508 }
509
Chris Craika753f4c2014-07-24 12:39:17 -0700510 int getClippingFlags() const {
511 return mPrimitiveFields.mClippingFlags;
512 }
513
John Reckd0a0b2a2014-03-20 16:28:56 -0700514 bool getClipToBounds() const {
Chris Craika753f4c2014-07-24 12:39:17 -0700515 return mPrimitiveFields.mClippingFlags & CLIP_TO_BOUNDS;
516 }
517
518 void getClippingRectForFlags(uint32_t flags, Rect* outRect) const {
519 if (flags & CLIP_TO_BOUNDS) {
520 outRect->set(0, 0, getWidth(), getHeight());
521 if (flags & CLIP_TO_CLIP_BOUNDS) {
522 outRect->intersect(mPrimitiveFields.mClipBounds);
523 }
524 } else {
525 outRect->set(mPrimitiveFields.mClipBounds);
526 }
John Reckd0a0b2a2014-03-20 16:28:56 -0700527 }
528
529 bool getHasOverlappingRendering() const {
530 return mPrimitiveFields.mHasOverlappingRendering;
531 }
532
533 const Outline& getOutline() const {
534 return mPrimitiveFields.mOutline;
535 }
536
Chris Craik8c271ca2014-03-25 10:33:01 -0700537 const RevealClip& getRevealClip() const {
538 return mPrimitiveFields.mRevealClip;
539 }
540
John Reckd0a0b2a2014-03-20 16:28:56 -0700541 bool getProjectBackwards() const {
542 return mPrimitiveFields.mProjectBackwards;
543 }
544
545 void debugOutputProperties(const int level) const;
546
John Reck25fbb3f2014-06-12 13:46:45 -0700547 void updateMatrix();
John Reckd0a0b2a2014-03-20 16:28:56 -0700548
Chris Craik8c271ca2014-03-25 10:33:01 -0700549 bool hasClippingPath() const {
Chris Craik2bcad172014-05-14 18:11:23 -0700550 return mPrimitiveFields.mRevealClip.willClip();
Chris Craik8c271ca2014-03-25 10:33:01 -0700551 }
552
553 const SkPath* getClippingPath() const {
Chris Craik2bcad172014-05-14 18:11:23 -0700554 return mPrimitiveFields.mRevealClip.getPath();
Chris Craik8c271ca2014-03-25 10:33:01 -0700555 }
556
557 SkRegion::Op getClippingPathOp() const {
Chris Craik2bcad172014-05-14 18:11:23 -0700558 return mPrimitiveFields.mRevealClip.isInverseClip()
559 ? SkRegion::kDifference_Op : SkRegion::kIntersect_Op;
Chris Craik8c271ca2014-03-25 10:33:01 -0700560 }
561
John Reckd0a0b2a2014-03-20 16:28:56 -0700562 Outline& mutableOutline() {
563 return mPrimitiveFields.mOutline;
Chris Craikb49f4462014-03-20 12:44:20 -0700564 }
565
Chris Craik8c271ca2014-03-25 10:33:01 -0700566 RevealClip& mutableRevealClip() {
567 return mPrimitiveFields.mRevealClip;
568 }
569
John Reck25fbb3f2014-06-12 13:46:45 -0700570 const LayerProperties& layerProperties() const {
571 return mLayerProperties;
572 }
573
574 LayerProperties& mutateLayerProperties() {
575 return mLayerProperties;
576 }
577
John Reck293e8682014-06-17 10:34:02 -0700578 // Returns true if damage calculations should be clipped to bounds
579 // TODO: Figure out something better for getZ(), as children should still be
580 // clipped to this RP's bounds. But as we will damage -INT_MAX to INT_MAX
581 // for this RP's getZ() anyway, this can be optimized when we have a
582 // Z damage estimate instead of INT_MAX
583 bool getClipDamageToBounds() const {
584 return getClipToBounds() && (getZ() <= 0 || getOutline().isEmpty());
585 }
586
John Reckacb6f072014-03-12 16:11:23 -0700587private:
John Reckacb6f072014-03-12 16:11:23 -0700588 // Rendering properties
John Reckd0a0b2a2014-03-20 16:28:56 -0700589 struct PrimitiveFields {
590 PrimitiveFields();
John Reckacb6f072014-03-12 16:11:23 -0700591
John Reckd0a0b2a2014-03-20 16:28:56 -0700592 Outline mOutline;
Chris Craik8c271ca2014-03-25 10:33:01 -0700593 RevealClip mRevealClip;
Chris Craika753f4c2014-07-24 12:39:17 -0700594 int mClippingFlags;
John Reckd0a0b2a2014-03-20 16:28:56 -0700595 bool mProjectBackwards;
596 bool mProjectionReceiver;
597 float mAlpha;
598 bool mHasOverlappingRendering;
Chris Craikcc39e162014-04-25 18:34:11 -0700599 float mElevation;
John Reckd0a0b2a2014-03-20 16:28:56 -0700600 float mTranslationX, mTranslationY, mTranslationZ;
601 float mRotation, mRotationX, mRotationY;
602 float mScaleX, mScaleY;
603 float mPivotX, mPivotY;
604 int mLeft, mTop, mRight, mBottom;
605 int mWidth, mHeight;
John Reckd0a0b2a2014-03-20 16:28:56 -0700606 bool mPivotExplicitlySet;
John Reckf7483e32014-04-11 08:54:47 -0700607 bool mMatrixOrPivotDirty;
Chris Craika753f4c2014-07-24 12:39:17 -0700608 Rect mClipBounds;
John Reckd0a0b2a2014-03-20 16:28:56 -0700609 } mPrimitiveFields;
610
John Reckacb6f072014-03-12 16:11:23 -0700611 SkMatrix* mStaticMatrix;
612 SkMatrix* mAnimationMatrix;
John Reck25fbb3f2014-06-12 13:46:45 -0700613 LayerProperties mLayerProperties;
John Reckacb6f072014-03-12 16:11:23 -0700614
John Reckd0a0b2a2014-03-20 16:28:56 -0700615 /**
616 * These fields are all generated from other properties and are not set directly.
617 */
618 struct ComputedFields {
619 ComputedFields();
620 ~ComputedFields();
621
622 /**
623 * Stores the total transformation of the DisplayList based upon its scalar
624 * translate/rotate/scale properties.
625 *
Chris Craik49e6c7392014-03-31 12:34:11 -0700626 * In the common translation-only case, the matrix isn't necessarily allocated,
627 * and the mTranslation properties are used directly.
John Reckd0a0b2a2014-03-20 16:28:56 -0700628 */
Chris Craik49e6c7392014-03-31 12:34:11 -0700629 SkMatrix* mTransformMatrix;
630
631 Sk3DView mTransformCamera;
John Reckd0a0b2a2014-03-20 16:28:56 -0700632 } mComputedFields;
John Reckacb6f072014-03-12 16:11:23 -0700633};
634
635} /* namespace uirenderer */
636} /* namespace android */
637
Chris Craikb49f4462014-03-20 12:44:20 -0700638#endif /* RENDERNODEPROPERTIES_H */