blob: 227d56eb3bd6c705c8dcdfd151cd03004d7eb793 [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
61class ANDROID_API LayerProperties {
62public:
63 bool setType(LayerType type) {
64 if (RP_SET(mType, type)) {
65 reset();
66 return true;
67 }
68 return false;
69 }
70
71 LayerType type() const {
72 return mType;
73 }
74
75 bool setOpaque(bool opaque) {
76 return RP_SET(mOpaque, opaque);
77 }
78
79 bool opaque() const {
80 return mOpaque;
81 }
82
83 bool setAlpha(uint8_t alpha) {
84 return RP_SET(mAlpha, alpha);
85 }
86
87 uint8_t alpha() const {
88 return mAlpha;
89 }
90
91 bool setXferMode(SkXfermode::Mode mode) {
92 return RP_SET(mMode, mode);
93 }
94
95 SkXfermode::Mode xferMode() const {
96 return mMode;
97 }
98
99 bool setColorFilter(SkColorFilter* filter);
100
101 SkColorFilter* colorFilter() const {
102 return mColorFilter;
103 }
104
105 // Sets alpha, xfermode, and colorfilter from an SkPaint
106 // paint may be NULL, in which case defaults will be set
107 bool setFromPaint(const SkPaint* paint);
108
109 bool needsBlending() const {
110 return !opaque() || alpha() < 255;
111 }
112
113 LayerProperties& operator=(const LayerProperties& other);
114
115private:
116 LayerProperties();
117 ~LayerProperties();
118 void reset();
119
120 friend class RenderProperties;
121
122 LayerType mType;
123 // Whether or not that Layer's content is opaque, doesn't include alpha
124 bool mOpaque;
125 uint8_t mAlpha;
126 SkXfermode::Mode mMode;
127 SkColorFilter* mColorFilter;
128};
129
John Reckacb6f072014-03-12 16:11:23 -0700130/*
131 * Data structure that holds the properties for a RenderNode
132 */
John Reck25fbb3f2014-06-12 13:46:45 -0700133class ANDROID_API RenderProperties {
John Reckacb6f072014-03-12 16:11:23 -0700134public:
135 RenderProperties();
136 virtual ~RenderProperties();
137
John Reckd0a0b2a2014-03-20 16:28:56 -0700138 RenderProperties& operator=(const RenderProperties& other);
139
John Reck79c7de72014-05-23 10:33:31 -0700140 bool setClipToBounds(bool clipToBounds) {
141 return RP_SET(mPrimitiveFields.mClipToBounds, clipToBounds);
John Reckacb6f072014-03-12 16:11:23 -0700142 }
143
John Reck79c7de72014-05-23 10:33:31 -0700144 bool setProjectBackwards(bool shouldProject) {
145 return RP_SET(mPrimitiveFields.mProjectBackwards, shouldProject);
John Reckacb6f072014-03-12 16:11:23 -0700146 }
147
John Reck79c7de72014-05-23 10:33:31 -0700148 bool setProjectionReceiver(bool shouldRecieve) {
149 return RP_SET(mPrimitiveFields.mProjectionReceiver, shouldRecieve);
John Reckacb6f072014-03-12 16:11:23 -0700150 }
151
John Reckd0a0b2a2014-03-20 16:28:56 -0700152 bool isProjectionReceiver() const {
153 return mPrimitiveFields.mProjectionReceiver;
John Reckacb6f072014-03-12 16:11:23 -0700154 }
155
John Reck79c7de72014-05-23 10:33:31 -0700156 bool setStaticMatrix(const SkMatrix* matrix) {
John Reckacb6f072014-03-12 16:11:23 -0700157 delete mStaticMatrix;
John Reckd0a0b2a2014-03-20 16:28:56 -0700158 if (matrix) {
159 mStaticMatrix = new SkMatrix(*matrix);
160 } else {
161 mStaticMatrix = NULL;
162 }
John Reck79c7de72014-05-23 10:33:31 -0700163 return true;
John Reckacb6f072014-03-12 16:11:23 -0700164 }
165
166 // Can return NULL
John Reckd0a0b2a2014-03-20 16:28:56 -0700167 const SkMatrix* getStaticMatrix() const {
John Reckacb6f072014-03-12 16:11:23 -0700168 return mStaticMatrix;
169 }
170
John Reck79c7de72014-05-23 10:33:31 -0700171 bool setAnimationMatrix(const SkMatrix* matrix) {
John Reckacb6f072014-03-12 16:11:23 -0700172 delete mAnimationMatrix;
173 if (matrix) {
174 mAnimationMatrix = new SkMatrix(*matrix);
175 } else {
176 mAnimationMatrix = NULL;
177 }
John Reck79c7de72014-05-23 10:33:31 -0700178 return true;
John Reckacb6f072014-03-12 16:11:23 -0700179 }
180
John Reck79c7de72014-05-23 10:33:31 -0700181 bool setAlpha(float alpha) {
John Reckacb6f072014-03-12 16:11:23 -0700182 alpha = fminf(1.0f, fmaxf(0.0f, alpha));
John Reck79c7de72014-05-23 10:33:31 -0700183 return RP_SET(mPrimitiveFields.mAlpha, alpha);
John Reckacb6f072014-03-12 16:11:23 -0700184 }
185
186 float getAlpha() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700187 return mPrimitiveFields.mAlpha;
John Reckacb6f072014-03-12 16:11:23 -0700188 }
189
John Reck79c7de72014-05-23 10:33:31 -0700190 bool setHasOverlappingRendering(bool hasOverlappingRendering) {
191 return RP_SET(mPrimitiveFields.mHasOverlappingRendering, hasOverlappingRendering);
John Reckacb6f072014-03-12 16:11:23 -0700192 }
193
194 bool hasOverlappingRendering() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700195 return mPrimitiveFields.mHasOverlappingRendering;
John Reckacb6f072014-03-12 16:11:23 -0700196 }
197
John Reck79c7de72014-05-23 10:33:31 -0700198 bool setElevation(float elevation) {
199 return RP_SET(mPrimitiveFields.mElevation, elevation);
200 // Don't dirty matrix/pivot, since they don't respect Z
Chris Craikcc39e162014-04-25 18:34:11 -0700201 }
202
203 float getElevation() const {
204 return mPrimitiveFields.mElevation;
205 }
206
John Reck79c7de72014-05-23 10:33:31 -0700207 bool setTranslationX(float translationX) {
208 return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationX, translationX);
John Reckacb6f072014-03-12 16:11:23 -0700209 }
210
211 float getTranslationX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700212 return mPrimitiveFields.mTranslationX;
John Reckacb6f072014-03-12 16:11:23 -0700213 }
214
John Reck79c7de72014-05-23 10:33:31 -0700215 bool setTranslationY(float translationY) {
216 return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationY, translationY);
John Reckacb6f072014-03-12 16:11:23 -0700217 }
218
219 float getTranslationY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700220 return mPrimitiveFields.mTranslationY;
John Reckacb6f072014-03-12 16:11:23 -0700221 }
222
John Reck79c7de72014-05-23 10:33:31 -0700223 bool setTranslationZ(float translationZ) {
224 return RP_SET(mPrimitiveFields.mTranslationZ, translationZ);
225 // mMatrixOrPivotDirty not set, since matrix doesn't respect Z
John Reckacb6f072014-03-12 16:11:23 -0700226 }
227
228 float getTranslationZ() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700229 return mPrimitiveFields.mTranslationZ;
John Reckacb6f072014-03-12 16:11:23 -0700230 }
231
John Recke45b1fd2014-04-15 09:50:16 -0700232 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700233 bool setX(float value) {
234 return setTranslationX(value - getLeft());
John Recke45b1fd2014-04-15 09:50:16 -0700235 }
236
237 // Animation helper
238 float getX() const {
239 return getLeft() + getTranslationX();
240 }
241
242 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700243 bool setY(float value) {
244 return setTranslationY(value - getTop());
John Recke45b1fd2014-04-15 09:50:16 -0700245 }
246
247 // Animation helper
248 float getY() const {
249 return getTop() + getTranslationY();
250 }
251
252 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700253 bool setZ(float value) {
254 return setTranslationZ(value - getElevation());
John Recke45b1fd2014-04-15 09:50:16 -0700255 }
256
Chris Craikcc39e162014-04-25 18:34:11 -0700257 float getZ() const {
258 return getElevation() + getTranslationZ();
259 }
260
John Reck79c7de72014-05-23 10:33:31 -0700261 bool setRotation(float rotation) {
262 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotation, rotation);
John Reckacb6f072014-03-12 16:11:23 -0700263 }
264
265 float getRotation() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700266 return mPrimitiveFields.mRotation;
John Reckacb6f072014-03-12 16:11:23 -0700267 }
268
John Reck79c7de72014-05-23 10:33:31 -0700269 bool setRotationX(float rotationX) {
270 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationX, rotationX);
John Reckacb6f072014-03-12 16:11:23 -0700271 }
272
273 float getRotationX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700274 return mPrimitiveFields.mRotationX;
John Reckacb6f072014-03-12 16:11:23 -0700275 }
276
John Reck79c7de72014-05-23 10:33:31 -0700277 bool setRotationY(float rotationY) {
278 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationY, rotationY);
John Reckacb6f072014-03-12 16:11:23 -0700279 }
280
281 float getRotationY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700282 return mPrimitiveFields.mRotationY;
John Reckacb6f072014-03-12 16:11:23 -0700283 }
284
John Reck79c7de72014-05-23 10:33:31 -0700285 bool setScaleX(float scaleX) {
Chris Craikfe02b4b2014-06-16 16:34:29 -0700286 LOG_ALWAYS_FATAL_IF(scaleX > 1000000, "invalid scaleX %e", scaleX);
John Reck79c7de72014-05-23 10:33:31 -0700287 return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleX, scaleX);
John Reckacb6f072014-03-12 16:11:23 -0700288 }
289
290 float getScaleX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700291 return mPrimitiveFields.mScaleX;
John Reckacb6f072014-03-12 16:11:23 -0700292 }
293
John Reck79c7de72014-05-23 10:33:31 -0700294 bool setScaleY(float scaleY) {
Chris Craikfe02b4b2014-06-16 16:34:29 -0700295 LOG_ALWAYS_FATAL_IF(scaleY > 1000000, "invalid scaleY %e", scaleY);
John Reck79c7de72014-05-23 10:33:31 -0700296 return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleY, scaleY);
John Reckacb6f072014-03-12 16:11:23 -0700297 }
298
299 float getScaleY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700300 return mPrimitiveFields.mScaleY;
John Reckacb6f072014-03-12 16:11:23 -0700301 }
302
John Reck79c7de72014-05-23 10:33:31 -0700303 bool setPivotX(float pivotX) {
304 if (RP_SET(mPrimitiveFields.mPivotX, pivotX)
305 || !mPrimitiveFields.mPivotExplicitlySet) {
306 mPrimitiveFields.mMatrixOrPivotDirty = true;
307 mPrimitiveFields.mPivotExplicitlySet = true;
308 return true;
309 }
310 return false;
John Reckacb6f072014-03-12 16:11:23 -0700311 }
312
John Reckd0a0b2a2014-03-20 16:28:56 -0700313 /* Note that getPivotX and getPivotY are adjusted by updateMatrix(),
John Reck79c7de72014-05-23 10:33:31 -0700314 * so the value returned may be stale if the RenderProperties has been
315 * modified since the last call to updateMatrix()
John Reckd0a0b2a2014-03-20 16:28:56 -0700316 */
317 float getPivotX() const {
318 return mPrimitiveFields.mPivotX;
319 }
John Reckacb6f072014-03-12 16:11:23 -0700320
John Reck79c7de72014-05-23 10:33:31 -0700321 bool setPivotY(float pivotY) {
322 if (RP_SET(mPrimitiveFields.mPivotY, pivotY)
323 || !mPrimitiveFields.mPivotExplicitlySet) {
324 mPrimitiveFields.mMatrixOrPivotDirty = true;
325 mPrimitiveFields.mPivotExplicitlySet = true;
326 return true;
327 }
328 return false;
John Reckacb6f072014-03-12 16:11:23 -0700329 }
330
John Reckd0a0b2a2014-03-20 16:28:56 -0700331 float getPivotY() const {
332 return mPrimitiveFields.mPivotY;
333 }
John Reckacb6f072014-03-12 16:11:23 -0700334
Chris Craik49e6c7392014-03-31 12:34:11 -0700335 bool isPivotExplicitlySet() const {
336 return mPrimitiveFields.mPivotExplicitlySet;
337 }
338
John Reck79c7de72014-05-23 10:33:31 -0700339 bool setCameraDistance(float distance) {
Chris Craik49e6c7392014-03-31 12:34:11 -0700340 if (distance != getCameraDistance()) {
John Reckf7483e32014-04-11 08:54:47 -0700341 mPrimitiveFields.mMatrixOrPivotDirty = true;
Chris Craik49e6c7392014-03-31 12:34:11 -0700342 mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance);
John Reck79c7de72014-05-23 10:33:31 -0700343 return true;
John Reckacb6f072014-03-12 16:11:23 -0700344 }
John Reck79c7de72014-05-23 10:33:31 -0700345 return false;
John Reckacb6f072014-03-12 16:11:23 -0700346 }
347
348 float getCameraDistance() const {
Chris Craik49e6c7392014-03-31 12:34:11 -0700349 // TODO: update getCameraLocationZ() to be const
350 return const_cast<Sk3DView*>(&mComputedFields.mTransformCamera)->getCameraLocationZ();
John Reckacb6f072014-03-12 16:11:23 -0700351 }
352
John Reck79c7de72014-05-23 10:33:31 -0700353 bool setLeft(int left) {
354 if (RP_SET(mPrimitiveFields.mLeft, left)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700355 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
John Reckf7483e32014-04-11 08:54:47 -0700356 if (!mPrimitiveFields.mPivotExplicitlySet) {
357 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700358 }
John Reck79c7de72014-05-23 10:33:31 -0700359 return true;
John Reckacb6f072014-03-12 16:11:23 -0700360 }
John Reck79c7de72014-05-23 10:33:31 -0700361 return false;
John Reckacb6f072014-03-12 16:11:23 -0700362 }
363
364 float getLeft() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700365 return mPrimitiveFields.mLeft;
John Reckacb6f072014-03-12 16:11:23 -0700366 }
367
John Reck79c7de72014-05-23 10:33:31 -0700368 bool setTop(int top) {
369 if (RP_SET(mPrimitiveFields.mTop, top)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700370 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700371 if (!mPrimitiveFields.mPivotExplicitlySet) {
372 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700373 }
John Reck79c7de72014-05-23 10:33:31 -0700374 return true;
John Reckacb6f072014-03-12 16:11:23 -0700375 }
John Reck79c7de72014-05-23 10:33:31 -0700376 return false;
John Reckacb6f072014-03-12 16:11:23 -0700377 }
378
379 float getTop() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700380 return mPrimitiveFields.mTop;
John Reckacb6f072014-03-12 16:11:23 -0700381 }
382
John Reck79c7de72014-05-23 10:33:31 -0700383 bool setRight(int right) {
384 if (RP_SET(mPrimitiveFields.mRight, right)) {
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 getRight() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700395 return mPrimitiveFields.mRight;
John Reckacb6f072014-03-12 16:11:23 -0700396 }
397
John Reck79c7de72014-05-23 10:33:31 -0700398 bool setBottom(int bottom) {
399 if (RP_SET(mPrimitiveFields.mBottom, bottom)) {
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 getBottom() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700410 return mPrimitiveFields.mBottom;
John Reckacb6f072014-03-12 16:11:23 -0700411 }
412
John Reck79c7de72014-05-23 10:33:31 -0700413 bool setLeftTop(int left, int top) {
414 bool leftResult = setLeft(left);
415 bool topResult = setTop(top);
416 return leftResult || topResult;
John Reckacb6f072014-03-12 16:11:23 -0700417 }
418
John Reck79c7de72014-05-23 10:33:31 -0700419 bool setLeftTopRightBottom(int left, int top, int right, int bottom) {
Chris Craikcc39e162014-04-25 18:34:11 -0700420 if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop
421 || right != mPrimitiveFields.mRight || bottom != mPrimitiveFields.mBottom) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700422 mPrimitiveFields.mLeft = left;
423 mPrimitiveFields.mTop = top;
424 mPrimitiveFields.mRight = right;
425 mPrimitiveFields.mBottom = bottom;
426 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
427 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700428 if (!mPrimitiveFields.mPivotExplicitlySet) {
429 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700430 }
John Reck79c7de72014-05-23 10:33:31 -0700431 return true;
John Reckacb6f072014-03-12 16:11:23 -0700432 }
John Reck79c7de72014-05-23 10:33:31 -0700433 return false;
John Reckacb6f072014-03-12 16:11:23 -0700434 }
435
John Reck79c7de72014-05-23 10:33:31 -0700436 bool offsetLeftRight(float offset) {
John Reckacb6f072014-03-12 16:11:23 -0700437 if (offset != 0) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700438 mPrimitiveFields.mLeft += offset;
439 mPrimitiveFields.mRight += offset;
John Reck79c7de72014-05-23 10:33:31 -0700440 return true;
John Reckacb6f072014-03-12 16:11:23 -0700441 }
John Reck79c7de72014-05-23 10:33:31 -0700442 return false;
John Reckacb6f072014-03-12 16:11:23 -0700443 }
444
John Reck79c7de72014-05-23 10:33:31 -0700445 bool offsetTopBottom(float offset) {
John Reckacb6f072014-03-12 16:11:23 -0700446 if (offset != 0) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700447 mPrimitiveFields.mTop += offset;
448 mPrimitiveFields.mBottom += offset;
John Reck79c7de72014-05-23 10:33:31 -0700449 return true;
John Reckacb6f072014-03-12 16:11:23 -0700450 }
John Reck79c7de72014-05-23 10:33:31 -0700451 return false;
John Reckacb6f072014-03-12 16:11:23 -0700452 }
453
Chris Craikb49f4462014-03-20 12:44:20 -0700454 int getWidth() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700455 return mPrimitiveFields.mWidth;
John Reckacb6f072014-03-12 16:11:23 -0700456 }
457
Chris Craikb49f4462014-03-20 12:44:20 -0700458 int getHeight() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700459 return mPrimitiveFields.mHeight;
John Reckacb6f072014-03-12 16:11:23 -0700460 }
461
John Reckd0a0b2a2014-03-20 16:28:56 -0700462 const SkMatrix* getAnimationMatrix() const {
463 return mAnimationMatrix;
464 }
465
John Reckf7483e32014-04-11 08:54:47 -0700466 bool hasTransformMatrix() const {
467 return getTransformMatrix() && !getTransformMatrix()->isIdentity();
468 }
469
470 // May only call this if hasTransformMatrix() is true
471 bool isTransformTranslateOnly() const {
472 return getTransformMatrix()->getType() == SkMatrix::kTranslate_Mask;
John Reckd0a0b2a2014-03-20 16:28:56 -0700473 }
474
Chris Craik49e6c7392014-03-31 12:34:11 -0700475 const SkMatrix* getTransformMatrix() const {
John Reckf7483e32014-04-11 08:54:47 -0700476 LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mMatrixOrPivotDirty, "Cannot get a dirty matrix!");
John Reckd0a0b2a2014-03-20 16:28:56 -0700477 return mComputedFields.mTransformMatrix;
478 }
479
John Reckd0a0b2a2014-03-20 16:28:56 -0700480 bool getClipToBounds() const {
481 return mPrimitiveFields.mClipToBounds;
482 }
483
484 bool getHasOverlappingRendering() const {
485 return mPrimitiveFields.mHasOverlappingRendering;
486 }
487
488 const Outline& getOutline() const {
489 return mPrimitiveFields.mOutline;
490 }
491
Chris Craik8c271ca2014-03-25 10:33:01 -0700492 const RevealClip& getRevealClip() const {
493 return mPrimitiveFields.mRevealClip;
494 }
495
John Reckd0a0b2a2014-03-20 16:28:56 -0700496 bool getProjectBackwards() const {
497 return mPrimitiveFields.mProjectBackwards;
498 }
499
500 void debugOutputProperties(const int level) const;
501
John Reck25fbb3f2014-06-12 13:46:45 -0700502 void updateMatrix();
John Reckd0a0b2a2014-03-20 16:28:56 -0700503
Chris Craik8c271ca2014-03-25 10:33:01 -0700504 bool hasClippingPath() const {
Chris Craik2bcad172014-05-14 18:11:23 -0700505 return mPrimitiveFields.mRevealClip.willClip();
Chris Craik8c271ca2014-03-25 10:33:01 -0700506 }
507
508 const SkPath* getClippingPath() const {
Chris Craik2bcad172014-05-14 18:11:23 -0700509 return mPrimitiveFields.mRevealClip.getPath();
Chris Craik8c271ca2014-03-25 10:33:01 -0700510 }
511
512 SkRegion::Op getClippingPathOp() const {
Chris Craik2bcad172014-05-14 18:11:23 -0700513 return mPrimitiveFields.mRevealClip.isInverseClip()
514 ? SkRegion::kDifference_Op : SkRegion::kIntersect_Op;
Chris Craik8c271ca2014-03-25 10:33:01 -0700515 }
516
John Reckd0a0b2a2014-03-20 16:28:56 -0700517 Outline& mutableOutline() {
518 return mPrimitiveFields.mOutline;
Chris Craikb49f4462014-03-20 12:44:20 -0700519 }
520
Chris Craik8c271ca2014-03-25 10:33:01 -0700521 RevealClip& mutableRevealClip() {
522 return mPrimitiveFields.mRevealClip;
523 }
524
John Reck25fbb3f2014-06-12 13:46:45 -0700525 const LayerProperties& layerProperties() const {
526 return mLayerProperties;
527 }
528
529 LayerProperties& mutateLayerProperties() {
530 return mLayerProperties;
531 }
532
John Reck293e8682014-06-17 10:34:02 -0700533 // Returns true if damage calculations should be clipped to bounds
534 // TODO: Figure out something better for getZ(), as children should still be
535 // clipped to this RP's bounds. But as we will damage -INT_MAX to INT_MAX
536 // for this RP's getZ() anyway, this can be optimized when we have a
537 // Z damage estimate instead of INT_MAX
538 bool getClipDamageToBounds() const {
539 return getClipToBounds() && (getZ() <= 0 || getOutline().isEmpty());
540 }
541
John Reckacb6f072014-03-12 16:11:23 -0700542private:
John Reckacb6f072014-03-12 16:11:23 -0700543
John Reckacb6f072014-03-12 16:11:23 -0700544 // Rendering properties
John Reckd0a0b2a2014-03-20 16:28:56 -0700545 struct PrimitiveFields {
546 PrimitiveFields();
John Reckacb6f072014-03-12 16:11:23 -0700547
John Reckd0a0b2a2014-03-20 16:28:56 -0700548 Outline mOutline;
Chris Craik8c271ca2014-03-25 10:33:01 -0700549 RevealClip mRevealClip;
John Reckd0a0b2a2014-03-20 16:28:56 -0700550 bool mClipToBounds;
551 bool mProjectBackwards;
552 bool mProjectionReceiver;
553 float mAlpha;
554 bool mHasOverlappingRendering;
Chris Craikcc39e162014-04-25 18:34:11 -0700555 float mElevation;
John Reckd0a0b2a2014-03-20 16:28:56 -0700556 float mTranslationX, mTranslationY, mTranslationZ;
557 float mRotation, mRotationX, mRotationY;
558 float mScaleX, mScaleY;
559 float mPivotX, mPivotY;
560 int mLeft, mTop, mRight, mBottom;
561 int mWidth, mHeight;
John Reckd0a0b2a2014-03-20 16:28:56 -0700562 bool mPivotExplicitlySet;
John Reckf7483e32014-04-11 08:54:47 -0700563 bool mMatrixOrPivotDirty;
John Reckd0a0b2a2014-03-20 16:28:56 -0700564 } mPrimitiveFields;
565
John Reckacb6f072014-03-12 16:11:23 -0700566 SkMatrix* mStaticMatrix;
567 SkMatrix* mAnimationMatrix;
John Reck25fbb3f2014-06-12 13:46:45 -0700568 LayerProperties mLayerProperties;
John Reckacb6f072014-03-12 16:11:23 -0700569
John Reckd0a0b2a2014-03-20 16:28:56 -0700570 /**
571 * These fields are all generated from other properties and are not set directly.
572 */
573 struct ComputedFields {
574 ComputedFields();
575 ~ComputedFields();
576
577 /**
578 * Stores the total transformation of the DisplayList based upon its scalar
579 * translate/rotate/scale properties.
580 *
Chris Craik49e6c7392014-03-31 12:34:11 -0700581 * In the common translation-only case, the matrix isn't necessarily allocated,
582 * and the mTranslation properties are used directly.
John Reckd0a0b2a2014-03-20 16:28:56 -0700583 */
Chris Craik49e6c7392014-03-31 12:34:11 -0700584 SkMatrix* mTransformMatrix;
585
586 Sk3DView mTransformCamera;
John Reckd0a0b2a2014-03-20 16:28:56 -0700587 } mComputedFields;
John Reckacb6f072014-03-12 16:11:23 -0700588};
589
590} /* namespace uirenderer */
591} /* namespace android */
592
Chris Craikb49f4462014-03-20 12:44:20 -0700593#endif /* RENDERNODEPROPERTIES_H */