blob: a43566d91a5de7336c647837f4eba3525d0369dc [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>
Tom Hudson2dc236b2014-10-15 15:46:42 -040029#include <SkXfermode.h>
Chris Craikb49f4462014-03-20 12:44:20 -070030
31#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_*
Chris Craik182952f2015-03-09 14:17:29 -070052enum class LayerType {
53 None = 0,
John Reck25fbb3f2014-06-12 13:46:45 -070054 // Although we cannot build the software layer directly (must be done at
55 // record time), this information is used when applying alpha.
Chris Craik182952f2015-03-09 14:17:29 -070056 Software = 1,
57 RenderLayer = 2,
John Reck25fbb3f2014-06-12 13:46:45 -070058 // 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
John Reck25fbb3f2014-06-12 13:46:45 -070076 bool setOpaque(bool opaque) {
77 return RP_SET(mOpaque, opaque);
78 }
79
80 bool opaque() const {
81 return mOpaque;
82 }
83
84 bool setAlpha(uint8_t alpha) {
85 return RP_SET(mAlpha, alpha);
86 }
87
88 uint8_t alpha() const {
89 return mAlpha;
90 }
91
92 bool setXferMode(SkXfermode::Mode mode) {
93 return RP_SET(mMode, mode);
94 }
95
96 SkXfermode::Mode xferMode() const {
97 return mMode;
98 }
99
100 bool setColorFilter(SkColorFilter* filter);
101
102 SkColorFilter* colorFilter() const {
103 return mColorFilter;
104 }
105
106 // Sets alpha, xfermode, and colorfilter from an SkPaint
107 // paint may be NULL, in which case defaults will be set
108 bool setFromPaint(const SkPaint* paint);
109
110 bool needsBlending() const {
111 return !opaque() || alpha() < 255;
112 }
113
114 LayerProperties& operator=(const LayerProperties& other);
115
116private:
117 LayerProperties();
118 ~LayerProperties();
119 void reset();
120
Chris Craik856f0cc2015-04-21 15:13:29 -0700121 // Private since external users should go through properties().effectiveLayerType()
122 LayerType type() const {
123 return mType;
124 }
125
John Reck25fbb3f2014-06-12 13:46:45 -0700126 friend class RenderProperties;
127
Chris Craik182952f2015-03-09 14:17:29 -0700128 LayerType mType = LayerType::None;
John Reck25fbb3f2014-06-12 13:46:45 -0700129 // Whether or not that Layer's content is opaque, doesn't include alpha
130 bool mOpaque;
131 uint8_t mAlpha;
132 SkXfermode::Mode mMode;
Chris Craik182952f2015-03-09 14:17:29 -0700133 SkColorFilter* mColorFilter = nullptr;
John Reck25fbb3f2014-06-12 13:46:45 -0700134};
135
John Reckacb6f072014-03-12 16:11:23 -0700136/*
137 * Data structure that holds the properties for a RenderNode
138 */
John Reck25fbb3f2014-06-12 13:46:45 -0700139class ANDROID_API RenderProperties {
John Reckacb6f072014-03-12 16:11:23 -0700140public:
141 RenderProperties();
142 virtual ~RenderProperties();
143
Chris Craika753f4c2014-07-24 12:39:17 -0700144 static bool setFlag(int flag, bool newValue, int* outFlags) {
145 if (newValue) {
146 if (!(flag & *outFlags)) {
147 *outFlags |= flag;
148 return true;
149 }
150 return false;
151 } else {
152 if (flag & *outFlags) {
153 *outFlags &= ~flag;
154 return true;
155 }
156 return false;
157 }
158 }
159
John Reckd0a0b2a2014-03-20 16:28:56 -0700160 RenderProperties& operator=(const RenderProperties& other);
161
John Reck79c7de72014-05-23 10:33:31 -0700162 bool setClipToBounds(bool clipToBounds) {
Chris Craika753f4c2014-07-24 12:39:17 -0700163 return setFlag(CLIP_TO_BOUNDS, clipToBounds, &mPrimitiveFields.mClippingFlags);
164 }
165
166 bool setClipBounds(const Rect& clipBounds) {
167 bool ret = setFlag(CLIP_TO_CLIP_BOUNDS, true, &mPrimitiveFields.mClippingFlags);
168 return RP_SET(mPrimitiveFields.mClipBounds, clipBounds) || ret;
169 }
170
171 bool setClipBoundsEmpty() {
172 return setFlag(CLIP_TO_CLIP_BOUNDS, false, &mPrimitiveFields.mClippingFlags);
John Reckacb6f072014-03-12 16:11:23 -0700173 }
174
John Reck79c7de72014-05-23 10:33:31 -0700175 bool setProjectBackwards(bool shouldProject) {
176 return RP_SET(mPrimitiveFields.mProjectBackwards, shouldProject);
John Reckacb6f072014-03-12 16:11:23 -0700177 }
178
John Reck79c7de72014-05-23 10:33:31 -0700179 bool setProjectionReceiver(bool shouldRecieve) {
180 return RP_SET(mPrimitiveFields.mProjectionReceiver, shouldRecieve);
John Reckacb6f072014-03-12 16:11:23 -0700181 }
182
John Reckd0a0b2a2014-03-20 16:28:56 -0700183 bool isProjectionReceiver() const {
184 return mPrimitiveFields.mProjectionReceiver;
John Reckacb6f072014-03-12 16:11:23 -0700185 }
186
John Reck79c7de72014-05-23 10:33:31 -0700187 bool setStaticMatrix(const SkMatrix* matrix) {
John Reckacb6f072014-03-12 16:11:23 -0700188 delete mStaticMatrix;
John Reckd0a0b2a2014-03-20 16:28:56 -0700189 if (matrix) {
190 mStaticMatrix = new SkMatrix(*matrix);
191 } else {
Chris Craike84a2082014-12-22 14:28:49 -0800192 mStaticMatrix = nullptr;
John Reckd0a0b2a2014-03-20 16:28:56 -0700193 }
John Reck79c7de72014-05-23 10:33:31 -0700194 return true;
John Reckacb6f072014-03-12 16:11:23 -0700195 }
196
197 // Can return NULL
John Reckd0a0b2a2014-03-20 16:28:56 -0700198 const SkMatrix* getStaticMatrix() const {
John Reckacb6f072014-03-12 16:11:23 -0700199 return mStaticMatrix;
200 }
201
John Reck79c7de72014-05-23 10:33:31 -0700202 bool setAnimationMatrix(const SkMatrix* matrix) {
John Reckacb6f072014-03-12 16:11:23 -0700203 delete mAnimationMatrix;
204 if (matrix) {
205 mAnimationMatrix = new SkMatrix(*matrix);
206 } else {
Chris Craike84a2082014-12-22 14:28:49 -0800207 mAnimationMatrix = nullptr;
John Reckacb6f072014-03-12 16:11:23 -0700208 }
John Reck79c7de72014-05-23 10:33:31 -0700209 return true;
John Reckacb6f072014-03-12 16:11:23 -0700210 }
211
John Reck79c7de72014-05-23 10:33:31 -0700212 bool setAlpha(float alpha) {
John Reck3b52c032014-08-06 10:19:32 -0700213 alpha = MathUtils::clampAlpha(alpha);
John Reck79c7de72014-05-23 10:33:31 -0700214 return RP_SET(mPrimitiveFields.mAlpha, alpha);
John Reckacb6f072014-03-12 16:11:23 -0700215 }
216
217 float getAlpha() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700218 return mPrimitiveFields.mAlpha;
John Reckacb6f072014-03-12 16:11:23 -0700219 }
220
John Reck79c7de72014-05-23 10:33:31 -0700221 bool setHasOverlappingRendering(bool hasOverlappingRendering) {
222 return RP_SET(mPrimitiveFields.mHasOverlappingRendering, hasOverlappingRendering);
John Reckacb6f072014-03-12 16:11:23 -0700223 }
224
225 bool hasOverlappingRendering() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700226 return mPrimitiveFields.mHasOverlappingRendering;
John Reckacb6f072014-03-12 16:11:23 -0700227 }
228
John Reck79c7de72014-05-23 10:33:31 -0700229 bool setElevation(float elevation) {
230 return RP_SET(mPrimitiveFields.mElevation, elevation);
231 // Don't dirty matrix/pivot, since they don't respect Z
Chris Craikcc39e162014-04-25 18:34:11 -0700232 }
233
234 float getElevation() const {
235 return mPrimitiveFields.mElevation;
236 }
237
John Reck79c7de72014-05-23 10:33:31 -0700238 bool setTranslationX(float translationX) {
239 return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationX, translationX);
John Reckacb6f072014-03-12 16:11:23 -0700240 }
241
242 float getTranslationX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700243 return mPrimitiveFields.mTranslationX;
John Reckacb6f072014-03-12 16:11:23 -0700244 }
245
John Reck79c7de72014-05-23 10:33:31 -0700246 bool setTranslationY(float translationY) {
247 return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationY, translationY);
John Reckacb6f072014-03-12 16:11:23 -0700248 }
249
250 float getTranslationY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700251 return mPrimitiveFields.mTranslationY;
John Reckacb6f072014-03-12 16:11:23 -0700252 }
253
John Reck79c7de72014-05-23 10:33:31 -0700254 bool setTranslationZ(float translationZ) {
255 return RP_SET(mPrimitiveFields.mTranslationZ, translationZ);
256 // mMatrixOrPivotDirty not set, since matrix doesn't respect Z
John Reckacb6f072014-03-12 16:11:23 -0700257 }
258
259 float getTranslationZ() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700260 return mPrimitiveFields.mTranslationZ;
John Reckacb6f072014-03-12 16:11:23 -0700261 }
262
John Recke45b1fd2014-04-15 09:50:16 -0700263 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700264 bool setX(float value) {
265 return setTranslationX(value - getLeft());
John Recke45b1fd2014-04-15 09:50:16 -0700266 }
267
268 // Animation helper
269 float getX() const {
270 return getLeft() + getTranslationX();
271 }
272
273 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700274 bool setY(float value) {
275 return setTranslationY(value - getTop());
John Recke45b1fd2014-04-15 09:50:16 -0700276 }
277
278 // Animation helper
279 float getY() const {
280 return getTop() + getTranslationY();
281 }
282
283 // Animation helper
John Reck79c7de72014-05-23 10:33:31 -0700284 bool setZ(float value) {
285 return setTranslationZ(value - getElevation());
John Recke45b1fd2014-04-15 09:50:16 -0700286 }
287
Chris Craikcc39e162014-04-25 18:34:11 -0700288 float getZ() const {
289 return getElevation() + getTranslationZ();
290 }
291
John Reck79c7de72014-05-23 10:33:31 -0700292 bool setRotation(float rotation) {
293 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotation, rotation);
John Reckacb6f072014-03-12 16:11:23 -0700294 }
295
296 float getRotation() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700297 return mPrimitiveFields.mRotation;
John Reckacb6f072014-03-12 16:11:23 -0700298 }
299
John Reck79c7de72014-05-23 10:33:31 -0700300 bool setRotationX(float rotationX) {
301 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationX, rotationX);
John Reckacb6f072014-03-12 16:11:23 -0700302 }
303
304 float getRotationX() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700305 return mPrimitiveFields.mRotationX;
John Reckacb6f072014-03-12 16:11:23 -0700306 }
307
John Reck79c7de72014-05-23 10:33:31 -0700308 bool setRotationY(float rotationY) {
309 return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationY, rotationY);
John Reckacb6f072014-03-12 16:11:23 -0700310 }
311
312 float getRotationY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700313 return mPrimitiveFields.mRotationY;
John Reckacb6f072014-03-12 16:11:23 -0700314 }
315
John Reck79c7de72014-05-23 10:33:31 -0700316 bool setScaleX(float scaleX) {
317 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) {
325 return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleY, scaleY);
John Reckacb6f072014-03-12 16:11:23 -0700326 }
327
328 float getScaleY() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700329 return mPrimitiveFields.mScaleY;
John Reckacb6f072014-03-12 16:11:23 -0700330 }
331
John Reck79c7de72014-05-23 10:33:31 -0700332 bool setPivotX(float pivotX) {
333 if (RP_SET(mPrimitiveFields.mPivotX, pivotX)
334 || !mPrimitiveFields.mPivotExplicitlySet) {
335 mPrimitiveFields.mMatrixOrPivotDirty = true;
336 mPrimitiveFields.mPivotExplicitlySet = true;
337 return true;
338 }
339 return false;
John Reckacb6f072014-03-12 16:11:23 -0700340 }
341
John Reckd0a0b2a2014-03-20 16:28:56 -0700342 /* Note that getPivotX and getPivotY are adjusted by updateMatrix(),
John Reck79c7de72014-05-23 10:33:31 -0700343 * so the value returned may be stale if the RenderProperties has been
344 * modified since the last call to updateMatrix()
John Reckd0a0b2a2014-03-20 16:28:56 -0700345 */
346 float getPivotX() const {
347 return mPrimitiveFields.mPivotX;
348 }
John Reckacb6f072014-03-12 16:11:23 -0700349
John Reck79c7de72014-05-23 10:33:31 -0700350 bool setPivotY(float pivotY) {
351 if (RP_SET(mPrimitiveFields.mPivotY, pivotY)
352 || !mPrimitiveFields.mPivotExplicitlySet) {
353 mPrimitiveFields.mMatrixOrPivotDirty = true;
354 mPrimitiveFields.mPivotExplicitlySet = true;
355 return true;
356 }
357 return false;
John Reckacb6f072014-03-12 16:11:23 -0700358 }
359
John Reckd0a0b2a2014-03-20 16:28:56 -0700360 float getPivotY() const {
361 return mPrimitiveFields.mPivotY;
362 }
John Reckacb6f072014-03-12 16:11:23 -0700363
Chris Craik49e6c732014-03-31 12:34:11 -0700364 bool isPivotExplicitlySet() const {
365 return mPrimitiveFields.mPivotExplicitlySet;
366 }
367
John Reck79c7de72014-05-23 10:33:31 -0700368 bool setCameraDistance(float distance) {
Chris Craik49e6c732014-03-31 12:34:11 -0700369 if (distance != getCameraDistance()) {
John Reckf7483e32014-04-11 08:54:47 -0700370 mPrimitiveFields.mMatrixOrPivotDirty = true;
Chris Craik49e6c732014-03-31 12:34:11 -0700371 mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance);
John Reck79c7de72014-05-23 10:33:31 -0700372 return true;
John Reckacb6f072014-03-12 16:11:23 -0700373 }
John Reck79c7de72014-05-23 10:33:31 -0700374 return false;
John Reckacb6f072014-03-12 16:11:23 -0700375 }
376
377 float getCameraDistance() const {
Chris Craik49e6c732014-03-31 12:34:11 -0700378 // TODO: update getCameraLocationZ() to be const
379 return const_cast<Sk3DView*>(&mComputedFields.mTransformCamera)->getCameraLocationZ();
John Reckacb6f072014-03-12 16:11:23 -0700380 }
381
John Reck79c7de72014-05-23 10:33:31 -0700382 bool setLeft(int left) {
383 if (RP_SET(mPrimitiveFields.mLeft, left)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700384 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
John Reckf7483e32014-04-11 08:54:47 -0700385 if (!mPrimitiveFields.mPivotExplicitlySet) {
386 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700387 }
John Reck79c7de72014-05-23 10:33:31 -0700388 return true;
John Reckacb6f072014-03-12 16:11:23 -0700389 }
John Reck79c7de72014-05-23 10:33:31 -0700390 return false;
John Reckacb6f072014-03-12 16:11:23 -0700391 }
392
393 float getLeft() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700394 return mPrimitiveFields.mLeft;
John Reckacb6f072014-03-12 16:11:23 -0700395 }
396
John Reck79c7de72014-05-23 10:33:31 -0700397 bool setTop(int top) {
398 if (RP_SET(mPrimitiveFields.mTop, top)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700399 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700400 if (!mPrimitiveFields.mPivotExplicitlySet) {
401 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700402 }
John Reck79c7de72014-05-23 10:33:31 -0700403 return true;
John Reckacb6f072014-03-12 16:11:23 -0700404 }
John Reck79c7de72014-05-23 10:33:31 -0700405 return false;
John Reckacb6f072014-03-12 16:11:23 -0700406 }
407
408 float getTop() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700409 return mPrimitiveFields.mTop;
John Reckacb6f072014-03-12 16:11:23 -0700410 }
411
John Reck79c7de72014-05-23 10:33:31 -0700412 bool setRight(int right) {
413 if (RP_SET(mPrimitiveFields.mRight, right)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700414 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
John Reckf7483e32014-04-11 08:54:47 -0700415 if (!mPrimitiveFields.mPivotExplicitlySet) {
416 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700417 }
John Reck79c7de72014-05-23 10:33:31 -0700418 return true;
John Reckacb6f072014-03-12 16:11:23 -0700419 }
John Reck79c7de72014-05-23 10:33:31 -0700420 return false;
John Reckacb6f072014-03-12 16:11:23 -0700421 }
422
423 float getRight() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700424 return mPrimitiveFields.mRight;
John Reckacb6f072014-03-12 16:11:23 -0700425 }
426
John Reck79c7de72014-05-23 10:33:31 -0700427 bool setBottom(int bottom) {
428 if (RP_SET(mPrimitiveFields.mBottom, bottom)) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700429 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700430 if (!mPrimitiveFields.mPivotExplicitlySet) {
431 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700432 }
John Reck79c7de72014-05-23 10:33:31 -0700433 return true;
John Reckacb6f072014-03-12 16:11:23 -0700434 }
John Reck79c7de72014-05-23 10:33:31 -0700435 return false;
John Reckacb6f072014-03-12 16:11:23 -0700436 }
437
438 float getBottom() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700439 return mPrimitiveFields.mBottom;
John Reckacb6f072014-03-12 16:11:23 -0700440 }
441
John Reck79c7de72014-05-23 10:33:31 -0700442 bool setLeftTop(int left, int top) {
443 bool leftResult = setLeft(left);
444 bool topResult = setTop(top);
445 return leftResult || topResult;
John Reckacb6f072014-03-12 16:11:23 -0700446 }
447
John Reck79c7de72014-05-23 10:33:31 -0700448 bool setLeftTopRightBottom(int left, int top, int right, int bottom) {
Chris Craikcc39e162014-04-25 18:34:11 -0700449 if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop
450 || right != mPrimitiveFields.mRight || bottom != mPrimitiveFields.mBottom) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700451 mPrimitiveFields.mLeft = left;
452 mPrimitiveFields.mTop = top;
453 mPrimitiveFields.mRight = right;
454 mPrimitiveFields.mBottom = bottom;
455 mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
456 mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
John Reckf7483e32014-04-11 08:54:47 -0700457 if (!mPrimitiveFields.mPivotExplicitlySet) {
458 mPrimitiveFields.mMatrixOrPivotDirty = true;
John Reckacb6f072014-03-12 16:11:23 -0700459 }
John Reck79c7de72014-05-23 10:33:31 -0700460 return true;
John Reckacb6f072014-03-12 16:11:23 -0700461 }
John Reck79c7de72014-05-23 10:33:31 -0700462 return false;
John Reckacb6f072014-03-12 16:11:23 -0700463 }
464
Chris Craika753f4c2014-07-24 12:39:17 -0700465 bool offsetLeftRight(int offset) {
John Reckacb6f072014-03-12 16:11:23 -0700466 if (offset != 0) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700467 mPrimitiveFields.mLeft += offset;
468 mPrimitiveFields.mRight += offset;
John Reck79c7de72014-05-23 10:33:31 -0700469 return true;
John Reckacb6f072014-03-12 16:11:23 -0700470 }
John Reck79c7de72014-05-23 10:33:31 -0700471 return false;
John Reckacb6f072014-03-12 16:11:23 -0700472 }
473
Chris Craika753f4c2014-07-24 12:39:17 -0700474 bool offsetTopBottom(int offset) {
John Reckacb6f072014-03-12 16:11:23 -0700475 if (offset != 0) {
John Reckd0a0b2a2014-03-20 16:28:56 -0700476 mPrimitiveFields.mTop += offset;
477 mPrimitiveFields.mBottom += offset;
John Reck79c7de72014-05-23 10:33:31 -0700478 return true;
John Reckacb6f072014-03-12 16:11:23 -0700479 }
John Reck79c7de72014-05-23 10:33:31 -0700480 return false;
John Reckacb6f072014-03-12 16:11:23 -0700481 }
482
Chris Craikb49f4462014-03-20 12:44:20 -0700483 int getWidth() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700484 return mPrimitiveFields.mWidth;
John Reckacb6f072014-03-12 16:11:23 -0700485 }
486
Chris Craikb49f4462014-03-20 12:44:20 -0700487 int getHeight() const {
John Reckd0a0b2a2014-03-20 16:28:56 -0700488 return mPrimitiveFields.mHeight;
John Reckacb6f072014-03-12 16:11:23 -0700489 }
490
John Reckd0a0b2a2014-03-20 16:28:56 -0700491 const SkMatrix* getAnimationMatrix() const {
492 return mAnimationMatrix;
493 }
494
John Reckf7483e32014-04-11 08:54:47 -0700495 bool hasTransformMatrix() const {
496 return getTransformMatrix() && !getTransformMatrix()->isIdentity();
497 }
498
499 // May only call this if hasTransformMatrix() is true
500 bool isTransformTranslateOnly() const {
501 return getTransformMatrix()->getType() == SkMatrix::kTranslate_Mask;
John Reckd0a0b2a2014-03-20 16:28:56 -0700502 }
503
Chris Craik49e6c732014-03-31 12:34:11 -0700504 const SkMatrix* getTransformMatrix() const {
John Reckf7483e32014-04-11 08:54:47 -0700505 LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mMatrixOrPivotDirty, "Cannot get a dirty matrix!");
John Reckd0a0b2a2014-03-20 16:28:56 -0700506 return mComputedFields.mTransformMatrix;
507 }
508
Chris Craika753f4c2014-07-24 12:39:17 -0700509 int getClippingFlags() const {
510 return mPrimitiveFields.mClippingFlags;
511 }
512
John Reckd0a0b2a2014-03-20 16:28:56 -0700513 bool getClipToBounds() const {
Chris Craika753f4c2014-07-24 12:39:17 -0700514 return mPrimitiveFields.mClippingFlags & CLIP_TO_BOUNDS;
515 }
516
517 void getClippingRectForFlags(uint32_t flags, Rect* outRect) const {
518 if (flags & CLIP_TO_BOUNDS) {
519 outRect->set(0, 0, getWidth(), getHeight());
520 if (flags & CLIP_TO_CLIP_BOUNDS) {
521 outRect->intersect(mPrimitiveFields.mClipBounds);
522 }
523 } else {
524 outRect->set(mPrimitiveFields.mClipBounds);
525 }
John Reckd0a0b2a2014-03-20 16:28:56 -0700526 }
527
528 bool getHasOverlappingRendering() const {
529 return mPrimitiveFields.mHasOverlappingRendering;
530 }
531
532 const Outline& getOutline() const {
533 return mPrimitiveFields.mOutline;
534 }
535
Chris Craik8c271ca2014-03-25 10:33:01 -0700536 const RevealClip& getRevealClip() const {
537 return mPrimitiveFields.mRevealClip;
538 }
539
John Reckd0a0b2a2014-03-20 16:28:56 -0700540 bool getProjectBackwards() const {
541 return mPrimitiveFields.mProjectBackwards;
542 }
543
544 void debugOutputProperties(const int level) const;
545
John Reck25fbb3f2014-06-12 13:46:45 -0700546 void updateMatrix();
John Reckd0a0b2a2014-03-20 16:28:56 -0700547
548 Outline& mutableOutline() {
549 return mPrimitiveFields.mOutline;
Chris Craikb49f4462014-03-20 12:44:20 -0700550 }
551
Chris Craik8c271ca2014-03-25 10:33:01 -0700552 RevealClip& mutableRevealClip() {
553 return mPrimitiveFields.mRevealClip;
554 }
555
John Reck25fbb3f2014-06-12 13:46:45 -0700556 const LayerProperties& layerProperties() const {
557 return mLayerProperties;
558 }
559
560 LayerProperties& mutateLayerProperties() {
561 return mLayerProperties;
562 }
563
John Reck293e8682014-06-17 10:34:02 -0700564 // Returns true if damage calculations should be clipped to bounds
565 // TODO: Figure out something better for getZ(), as children should still be
566 // clipped to this RP's bounds. But as we will damage -INT_MAX to INT_MAX
567 // for this RP's getZ() anyway, this can be optimized when we have a
568 // Z damage estimate instead of INT_MAX
569 bool getClipDamageToBounds() const {
570 return getClipToBounds() && (getZ() <= 0 || getOutline().isEmpty());
571 }
572
Chris Craik5c75c522014-09-05 14:08:08 -0700573 bool hasShadow() const {
Chris Craikb5a54352014-11-21 14:54:35 -0800574 return getZ() > 0.0f
Chris Craike84a2082014-12-22 14:28:49 -0800575 && getOutline().getPath() != nullptr
Chris Craik9fa364d2014-09-19 16:04:45 -0700576 && getOutline().getAlpha() != 0.0f;
Chris Craik5c75c522014-09-05 14:08:08 -0700577 }
578
Chris Craik856f0cc2015-04-21 15:13:29 -0700579 LayerType effectiveLayerType() const {
580 LayerType type = mLayerProperties.mType;
581 if (type == LayerType::None
582 && !MathUtils::isZero(mPrimitiveFields.mAlpha)
583 && mPrimitiveFields.mAlpha < 1
584 && mPrimitiveFields.mHasOverlappingRendering) {
585 return LayerType::RenderLayer;
586 }
587 return type;
588 }
589
John Reckacb6f072014-03-12 16:11:23 -0700590private:
John Reckacb6f072014-03-12 16:11:23 -0700591 // Rendering properties
John Reckd0a0b2a2014-03-20 16:28:56 -0700592 struct PrimitiveFields {
593 PrimitiveFields();
John Reckacb6f072014-03-12 16:11:23 -0700594
John Reckd0a0b2a2014-03-20 16:28:56 -0700595 Outline mOutline;
Chris Craik8c271ca2014-03-25 10:33:01 -0700596 RevealClip mRevealClip;
Chris Craika753f4c2014-07-24 12:39:17 -0700597 int mClippingFlags;
John Reckd0a0b2a2014-03-20 16:28:56 -0700598 bool mProjectBackwards;
599 bool mProjectionReceiver;
600 float mAlpha;
601 bool mHasOverlappingRendering;
Chris Craikcc39e162014-04-25 18:34:11 -0700602 float mElevation;
John Reckd0a0b2a2014-03-20 16:28:56 -0700603 float mTranslationX, mTranslationY, mTranslationZ;
604 float mRotation, mRotationX, mRotationY;
605 float mScaleX, mScaleY;
606 float mPivotX, mPivotY;
607 int mLeft, mTop, mRight, mBottom;
608 int mWidth, mHeight;
John Reckd0a0b2a2014-03-20 16:28:56 -0700609 bool mPivotExplicitlySet;
John Reckf7483e32014-04-11 08:54:47 -0700610 bool mMatrixOrPivotDirty;
Chris Craika753f4c2014-07-24 12:39:17 -0700611 Rect mClipBounds;
John Reckd0a0b2a2014-03-20 16:28:56 -0700612 } mPrimitiveFields;
613
John Reckacb6f072014-03-12 16:11:23 -0700614 SkMatrix* mStaticMatrix;
615 SkMatrix* mAnimationMatrix;
John Reck25fbb3f2014-06-12 13:46:45 -0700616 LayerProperties mLayerProperties;
John Reckacb6f072014-03-12 16:11:23 -0700617
John Reckd0a0b2a2014-03-20 16:28:56 -0700618 /**
619 * These fields are all generated from other properties and are not set directly.
620 */
621 struct ComputedFields {
622 ComputedFields();
623 ~ComputedFields();
624
625 /**
626 * Stores the total transformation of the DisplayList based upon its scalar
627 * translate/rotate/scale properties.
628 *
Chris Craik49e6c732014-03-31 12:34:11 -0700629 * In the common translation-only case, the matrix isn't necessarily allocated,
630 * and the mTranslation properties are used directly.
John Reckd0a0b2a2014-03-20 16:28:56 -0700631 */
Chris Craik49e6c732014-03-31 12:34:11 -0700632 SkMatrix* mTransformMatrix;
633
634 Sk3DView mTransformCamera;
John Reckd0a0b2a2014-03-20 16:28:56 -0700635 } mComputedFields;
John Reckacb6f072014-03-12 16:11:23 -0700636};
637
638} /* namespace uirenderer */
639} /* namespace android */
640
Chris Craikb49f4462014-03-20 12:44:20 -0700641#endif /* RENDERNODEPROPERTIES_H */