RenderProperties.h revision 34f67f26e355925aa1e00a20bc11e09b8dc32988
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16#ifndef RENDERNODEPROPERTIES_H_ 17#define RENDERNODEPROPERTIES_H_ 18 19#include <stddef.h> 20#include <cutils/compiler.h> 21#include <androidfw/ResourceTypes.h> 22 23#include <SkCamera.h> 24#include <SkMatrix.h> 25#include <SkPath.h> 26 27#define TRANSLATION 0x0001 28#define ROTATION 0x0002 29#define ROTATION_3D 0x0004 30#define SCALE 0x0008 31#define PIVOT 0x0010 32 33class SkBitmap; 34class SkPaint; 35class SkRegion; 36 37namespace android { 38namespace uirenderer { 39 40class Matrix4; 41class RenderNode; 42 43/* 44 * Data structure that holds the properties for a RenderNode 45 */ 46class RenderProperties { 47public: 48 RenderProperties(); 49 virtual ~RenderProperties(); 50 51 void setClipToBounds(bool clipToBounds) { 52 mClipToBounds = clipToBounds; 53 } 54 55 void setProjectBackwards(bool shouldProject) { 56 mProjectBackwards = shouldProject; 57 } 58 59 void setProjectionReceiver(bool shouldRecieve) { 60 mProjectionReceiver = shouldRecieve; 61 } 62 63 bool isProjectionReceiver() { 64 return mProjectionReceiver; 65 } 66 67 void setOutline(const SkPath* outline) { 68 if (!outline) { 69 mOutline.reset(); 70 } else { 71 mOutline = *outline; 72 } 73 } 74 75 void setClipToOutline(bool clipToOutline) { 76 mClipToOutline = clipToOutline; 77 } 78 79 void setStaticMatrix(SkMatrix* matrix) { 80 delete mStaticMatrix; 81 mStaticMatrix = new SkMatrix(*matrix); 82 } 83 84 // Can return NULL 85 SkMatrix* getStaticMatrix() { 86 return mStaticMatrix; 87 } 88 89 void setAnimationMatrix(SkMatrix* matrix) { 90 delete mAnimationMatrix; 91 if (matrix) { 92 mAnimationMatrix = new SkMatrix(*matrix); 93 } else { 94 mAnimationMatrix = NULL; 95 } 96 } 97 98 void setAlpha(float alpha) { 99 alpha = fminf(1.0f, fmaxf(0.0f, alpha)); 100 if (alpha != mAlpha) { 101 mAlpha = alpha; 102 } 103 } 104 105 float getAlpha() const { 106 return mAlpha; 107 } 108 109 void setHasOverlappingRendering(bool hasOverlappingRendering) { 110 mHasOverlappingRendering = hasOverlappingRendering; 111 } 112 113 bool hasOverlappingRendering() const { 114 return mHasOverlappingRendering; 115 } 116 117 void setTranslationX(float translationX) { 118 if (translationX != mTranslationX) { 119 mTranslationX = translationX; 120 onTranslationUpdate(); 121 } 122 } 123 124 float getTranslationX() const { 125 return mTranslationX; 126 } 127 128 void setTranslationY(float translationY) { 129 if (translationY != mTranslationY) { 130 mTranslationY = translationY; 131 onTranslationUpdate(); 132 } 133 } 134 135 float getTranslationY() const { 136 return mTranslationY; 137 } 138 139 void setTranslationZ(float translationZ) { 140 if (translationZ != mTranslationZ) { 141 mTranslationZ = translationZ; 142 onTranslationUpdate(); 143 } 144 } 145 146 float getTranslationZ() const { 147 return mTranslationZ; 148 } 149 150 void setRotation(float rotation) { 151 if (rotation != mRotation) { 152 mRotation = rotation; 153 mMatrixDirty = true; 154 if (mRotation == 0.0f) { 155 mMatrixFlags &= ~ROTATION; 156 } else { 157 mMatrixFlags |= ROTATION; 158 } 159 } 160 } 161 162 float getRotation() const { 163 return mRotation; 164 } 165 166 void setRotationX(float rotationX) { 167 if (rotationX != mRotationX) { 168 mRotationX = rotationX; 169 mMatrixDirty = true; 170 if (mRotationX == 0.0f && mRotationY == 0.0f) { 171 mMatrixFlags &= ~ROTATION_3D; 172 } else { 173 mMatrixFlags |= ROTATION_3D; 174 } 175 } 176 } 177 178 float getRotationX() const { 179 return mRotationX; 180 } 181 182 void setRotationY(float rotationY) { 183 if (rotationY != mRotationY) { 184 mRotationY = rotationY; 185 mMatrixDirty = true; 186 if (mRotationX == 0.0f && mRotationY == 0.0f) { 187 mMatrixFlags &= ~ROTATION_3D; 188 } else { 189 mMatrixFlags |= ROTATION_3D; 190 } 191 } 192 } 193 194 float getRotationY() const { 195 return mRotationY; 196 } 197 198 void setScaleX(float scaleX) { 199 if (scaleX != mScaleX) { 200 mScaleX = scaleX; 201 mMatrixDirty = true; 202 if (mScaleX == 1.0f && mScaleY == 1.0f) { 203 mMatrixFlags &= ~SCALE; 204 } else { 205 mMatrixFlags |= SCALE; 206 } 207 } 208 } 209 210 float getScaleX() const { 211 return mScaleX; 212 } 213 214 void setScaleY(float scaleY) { 215 if (scaleY != mScaleY) { 216 mScaleY = scaleY; 217 mMatrixDirty = true; 218 if (mScaleX == 1.0f && mScaleY == 1.0f) { 219 mMatrixFlags &= ~SCALE; 220 } else { 221 mMatrixFlags |= SCALE; 222 } 223 } 224 } 225 226 float getScaleY() const { 227 return mScaleY; 228 } 229 230 void setPivotX(float pivotX) { 231 mPivotX = pivotX; 232 mMatrixDirty = true; 233 if (mPivotX == 0.0f && mPivotY == 0.0f) { 234 mMatrixFlags &= ~PIVOT; 235 } else { 236 mMatrixFlags |= PIVOT; 237 } 238 mPivotExplicitlySet = true; 239 } 240 241 ANDROID_API float getPivotX(); 242 243 void setPivotY(float pivotY) { 244 mPivotY = pivotY; 245 mMatrixDirty = true; 246 if (mPivotX == 0.0f && mPivotY == 0.0f) { 247 mMatrixFlags &= ~PIVOT; 248 } else { 249 mMatrixFlags |= PIVOT; 250 } 251 mPivotExplicitlySet = true; 252 } 253 254 ANDROID_API float getPivotY(); 255 256 void setCameraDistance(float distance) { 257 if (distance != mCameraDistance) { 258 mCameraDistance = distance; 259 mMatrixDirty = true; 260 if (!mTransformCamera) { 261 mTransformCamera = new Sk3DView(); 262 mTransformMatrix3D = new SkMatrix(); 263 } 264 mTransformCamera->setCameraLocation(0, 0, distance); 265 } 266 } 267 268 float getCameraDistance() const { 269 return mCameraDistance; 270 } 271 272 void setLeft(int left) { 273 if (left != mLeft) { 274 mLeft = left; 275 mWidth = mRight - mLeft; 276 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 277 mMatrixDirty = true; 278 } 279 } 280 } 281 282 float getLeft() const { 283 return mLeft; 284 } 285 286 void setTop(int top) { 287 if (top != mTop) { 288 mTop = top; 289 mHeight = mBottom - mTop; 290 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 291 mMatrixDirty = true; 292 } 293 } 294 } 295 296 float getTop() const { 297 return mTop; 298 } 299 300 void setRight(int right) { 301 if (right != mRight) { 302 mRight = right; 303 mWidth = mRight - mLeft; 304 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 305 mMatrixDirty = true; 306 } 307 } 308 } 309 310 float getRight() const { 311 return mRight; 312 } 313 314 void setBottom(int bottom) { 315 if (bottom != mBottom) { 316 mBottom = bottom; 317 mHeight = mBottom - mTop; 318 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 319 mMatrixDirty = true; 320 } 321 } 322 } 323 324 float getBottom() const { 325 return mBottom; 326 } 327 328 void setLeftTop(int left, int top) { 329 if (left != mLeft || top != mTop) { 330 mLeft = left; 331 mTop = top; 332 mWidth = mRight - mLeft; 333 mHeight = mBottom - mTop; 334 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 335 mMatrixDirty = true; 336 } 337 } 338 } 339 340 void setLeftTopRightBottom(int left, int top, int right, int bottom) { 341 if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) { 342 mLeft = left; 343 mTop = top; 344 mRight = right; 345 mBottom = bottom; 346 mWidth = mRight - mLeft; 347 mHeight = mBottom - mTop; 348 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 349 mMatrixDirty = true; 350 } 351 } 352 } 353 354 void offsetLeftRight(float offset) { 355 if (offset != 0) { 356 mLeft += offset; 357 mRight += offset; 358 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 359 mMatrixDirty = true; 360 } 361 } 362 } 363 364 void offsetTopBottom(float offset) { 365 if (offset != 0) { 366 mTop += offset; 367 mBottom += offset; 368 if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) { 369 mMatrixDirty = true; 370 } 371 } 372 } 373 374 void setCaching(bool caching) { 375 mCaching = caching; 376 } 377 378 int getWidth() { 379 return mWidth; 380 } 381 382 int getHeight() { 383 return mHeight; 384 } 385 386private: 387 void onTranslationUpdate() { 388 mMatrixDirty = true; 389 if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) { 390 mMatrixFlags &= ~TRANSLATION; 391 } else { 392 mMatrixFlags |= TRANSLATION; 393 } 394 } 395 396 void updateMatrix(); 397 398 // Rendering properties 399 bool mClipToBounds; 400 bool mProjectBackwards; 401 bool mProjectionReceiver; 402 SkPath mOutline; 403 bool mClipToOutline; 404 float mAlpha; 405 bool mHasOverlappingRendering; 406 float mTranslationX, mTranslationY, mTranslationZ; 407 float mRotation, mRotationX, mRotationY; 408 float mScaleX, mScaleY; 409 float mPivotX, mPivotY; 410 float mCameraDistance; 411 int mLeft, mTop, mRight, mBottom; 412 int mWidth, mHeight; 413 int mPrevWidth, mPrevHeight; 414 bool mPivotExplicitlySet; 415 bool mMatrixDirty; 416 bool mMatrixIsIdentity; 417 418 /** 419 * Stores the total transformation of the DisplayList based upon its scalar 420 * translate/rotate/scale properties. 421 * 422 * In the common translation-only case, the matrix isn't allocated and the mTranslation 423 * properties are used directly. 424 */ 425 Matrix4* mTransformMatrix; 426 uint32_t mMatrixFlags; 427 Sk3DView* mTransformCamera; 428 SkMatrix* mTransformMatrix3D; 429 SkMatrix* mStaticMatrix; 430 SkMatrix* mAnimationMatrix; 431 bool mCaching; 432 433 friend class RenderNode; 434}; 435 436} /* namespace uirenderer */ 437} /* namespace android */ 438 439#endif /* RENDERNODEPROPERTIES_H_ */ 440