summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2014-03-20 16:28:56 -0700
committerJohn Reck <jreck@google.com>2014-03-24 15:31:34 -0700
commitd0a0b2a3140bfb1819a116413ce9d81886697a07 (patch)
tree0040f371f29280deb83d1fd55f2db86e30d58c37 /libs
parentde02cdc1e95cea19b2ddef26d60ad1d109bd507c (diff)
downloadframeworks_base-d0a0b2a3140bfb1819a116413ce9d81886697a07.zip
frameworks_base-d0a0b2a3140bfb1819a116413ce9d81886697a07.tar.gz
frameworks_base-d0a0b2a3140bfb1819a116413ce9d81886697a07.tar.bz2
Add stagingProperties
Change-Id: Ic7de551f8843fd70a77f738e33028e25c020bb3c
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Layer.cpp1
-rw-r--r--libs/hwui/OpenGLRenderer.cpp1
-rw-r--r--libs/hwui/Outline.h2
-rw-r--r--libs/hwui/RenderNode.cpp190
-rw-r--r--libs/hwui/RenderNode.h18
-rw-r--r--libs/hwui/RenderProperties.cpp169
-rw-r--r--libs/hwui/RenderProperties.h392
7 files changed, 436 insertions, 337 deletions
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index bd9bfe9..3f6c7df 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -200,6 +200,7 @@ void Layer::defer() {
renderer->setupFrameState(dirtyRect.left, dirtyRect.top,
dirtyRect.right, dirtyRect.bottom, !isBlend());
+ displayList->updateProperties();
displayList->computeOrdering();
displayList->defer(deferredState, 0);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index cdd789d..5ef8abb 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1919,6 +1919,7 @@ status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty,
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
// compute 3d ordering
+ displayList->updateProperties();
displayList->computeOrdering();
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
status = startFrame();
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
index f42be50..4e496e7 100644
--- a/libs/hwui/Outline.h
+++ b/libs/hwui/Outline.h
@@ -64,7 +64,7 @@ public:
return mShouldClip && (mType == kOutlineType_RoundRect);
}
- const SkPath* getPath() {
+ const SkPath* getPath() const {
if (mType == kOutlineType_None) return NULL;
return &mPath;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 8aed857..62a9d71 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -49,7 +49,7 @@ void RenderNode::outputLogBuffer(int fd) {
fflush(file);
}
-RenderNode::RenderNode() : mDestroyed(false), mDisplayListData(0) {
+RenderNode::RenderNode() : mDestroyed(false), mNeedsPropertiesSync(false), mDisplayListData(0) {
}
RenderNode::~RenderNode() {
@@ -84,7 +84,7 @@ void RenderNode::output(uint32_t level) {
ALOGD("%*s%s %d", level * 2, "", "Save",
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
- outputViewProperties(level);
+ properties().debugOutputProperties(level);
int flags = DisplayListOp::kOpLogFlag_Recurse;
for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
mDisplayListData->displayListOps[i]->output(level, flags);
@@ -93,56 +93,22 @@ void RenderNode::output(uint32_t level) {
ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
}
-void RenderNode::outputViewProperties(const int level) {
- properties().updateMatrix();
- if (properties().mLeft != 0 || properties().mTop != 0) {
- ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", properties().mLeft, properties().mTop);
- }
- if (properties().mStaticMatrix) {
- ALOGD("%*sConcatMatrix (static) %p: " SK_MATRIX_STRING,
- level * 2, "", properties().mStaticMatrix, SK_MATRIX_ARGS(properties().mStaticMatrix));
- }
- if (properties().mAnimationMatrix) {
- ALOGD("%*sConcatMatrix (animation) %p: " SK_MATRIX_STRING,
- level * 2, "", properties().mAnimationMatrix, SK_MATRIX_ARGS(properties().mAnimationMatrix));
- }
- if (properties().mMatrixFlags != 0) {
- if (properties().mMatrixFlags == TRANSLATION) {
- ALOGD("%*sTranslate %.2f, %.2f, %.2f",
- level * 2, "", properties().mTranslationX, properties().mTranslationY, properties().mTranslationZ);
- } else {
- ALOGD("%*sConcatMatrix %p: " MATRIX_4_STRING,
- level * 2, "", properties().mTransformMatrix, MATRIX_4_ARGS(properties().mTransformMatrix));
- }
+void RenderNode::updateProperties() {
+ if (mNeedsPropertiesSync) {
+ mNeedsPropertiesSync = false;
+ mProperties = mStagingProperties;
}
- bool clipToBoundsNeeded = properties().mCaching ? false : properties().mClipToBounds;
- if (properties().mAlpha < 1) {
- if (properties().mCaching) {
- ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", properties().mAlpha);
- } else if (!properties().mHasOverlappingRendering) {
- ALOGD("%*sScaleAlpha %.2f", level * 2, "", properties().mAlpha);
- } else {
- int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
- if (clipToBoundsNeeded) {
- flags |= SkCanvas::kClipToLayer_SaveFlag;
- clipToBoundsNeeded = false; // clipping done by save layer
- }
- ALOGD("%*sSaveLayerAlpha %d, %d, %d, %d, %d, 0x%x", level * 2, "",
- 0, 0, properties().mWidth, properties().mHeight,
- (int)(properties().mAlpha * 255), flags);
- }
- }
- if (clipToBoundsNeeded) {
- ALOGD("%*sClipRect %d, %d, %d, %d", level * 2, "",
- 0, 0, properties().mWidth, properties().mHeight);
+ for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
+ RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
+ childNode->updateProperties();
}
}
/*
* For property operations, we pass a savecount of 0, since the operations aren't part of the
* displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in
- * base saveCount (i.e., how RestoreToCount uses saveCount + properties().mCount)
+ * base saveCount (i.e., how RestoreToCount uses saveCount + properties().getCount())
*/
#define PROPERTY_SAVECOUNT 0
@@ -150,30 +116,29 @@ template <class T>
void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler,
const int level) {
#if DEBUG_DISPLAY_LIST
- outputViewProperties(level);
+ properties().debugOutputProperties(level);
#endif
- properties().updateMatrix();
- if (properties().mLeft != 0 || properties().mTop != 0) {
- renderer.translate(properties().mLeft, properties().mTop);
+ if (properties().getLeft() != 0 || properties().getTop() != 0) {
+ renderer.translate(properties().getLeft(), properties().getTop());
}
- if (properties().mStaticMatrix) {
- renderer.concatMatrix(properties().mStaticMatrix);
- } else if (properties().mAnimationMatrix) {
- renderer.concatMatrix(properties().mAnimationMatrix);
+ if (properties().getStaticMatrix()) {
+ renderer.concatMatrix(properties().getStaticMatrix());
+ } else if (properties().getAnimationMatrix()) {
+ renderer.concatMatrix(properties().getAnimationMatrix());
}
- if (properties().mMatrixFlags != 0) {
- if (properties().mMatrixFlags == TRANSLATION) {
- renderer.translate(properties().mTranslationX, properties().mTranslationY);
+ if (properties().getMatrixFlags() != 0) {
+ if (properties().getMatrixFlags() == TRANSLATION) {
+ renderer.translate(properties().getTranslationX(), properties().getTranslationY());
} else {
- renderer.concatMatrix(*properties().mTransformMatrix);
+ renderer.concatMatrix(*properties().getTransformMatrix());
}
}
- bool clipToBoundsNeeded = properties().mCaching ? false : properties().mClipToBounds;
- if (properties().mAlpha < 1) {
- if (properties().mCaching) {
- renderer.setOverrideLayerAlpha(properties().mAlpha);
- } else if (!properties().mHasOverlappingRendering) {
- renderer.scaleAlpha(properties().mAlpha);
+ bool clipToBoundsNeeded = properties().getCaching() ? false : properties().getClipToBounds();
+ if (properties().getAlpha() < 1) {
+ if (properties().getCaching()) {
+ renderer.setOverrideLayerAlpha(properties().getAlpha());
+ } else if (!properties().getHasOverlappingRendering()) {
+ renderer.scaleAlpha(properties().getAlpha());
} else {
// TODO: should be able to store the size of a DL at record time and not
// have to pass it into this call. In fact, this information might be in the
@@ -185,21 +150,19 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler,
}
SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
- 0, 0, properties().mWidth, properties().mHeight,
- properties().mAlpha * 255, saveFlags);
- handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ 0, 0, properties().getWidth(), properties().getHeight(), properties().getAlpha() * 255, saveFlags);
+ handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
}
if (clipToBoundsNeeded) {
- ClipRectOp* op = new (handler.allocator()) ClipRectOp(
- 0, 0, properties().mWidth, properties().mHeight, SkRegion::kIntersect_Op);
- handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ ClipRectOp* op = new (handler.allocator()) ClipRectOp(0, 0,
+ properties().getWidth(), properties().getHeight(), SkRegion::kIntersect_Op);
+ handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
- if (CC_UNLIKELY(properties().mOutline.willClip())) {
- // TODO: optimize RR case
- ClipPathOp* op = new (handler.allocator()) ClipPathOp(properties().mOutline.getPath(),
+ if (CC_UNLIKELY(properties().getOutline().willClip())) {
+ ClipPathOp* op = new (handler.allocator()) ClipPathOp(properties().getOutline().getPath(),
SkRegion::kIntersect_Op);
- handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
}
@@ -210,35 +173,34 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler,
* matrix computation instead of the Skia 3x3 matrix + camera hackery.
*/
void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) {
- if (properties().mLeft != 0 || properties().mTop != 0) {
- matrix.translate(properties().mLeft, properties().mTop);
+ if (properties().getLeft() != 0 || properties().getTop() != 0) {
+ matrix.translate(properties().getLeft(), properties().getTop());
}
- if (properties().mStaticMatrix) {
- mat4 stat(*properties().mStaticMatrix);
+ if (properties().getStaticMatrix()) {
+ mat4 stat(*properties().getStaticMatrix());
matrix.multiply(stat);
- } else if (properties().mAnimationMatrix) {
- mat4 anim(*properties().mAnimationMatrix);
+ } else if (properties().getAnimationMatrix()) {
+ mat4 anim(*properties().getAnimationMatrix());
matrix.multiply(anim);
}
- if (properties().mMatrixFlags != 0) {
- properties().updateMatrix();
- if (properties().mMatrixFlags == TRANSLATION) {
- matrix.translate(properties().mTranslationX, properties().mTranslationY,
- true3dTransform ? properties().mTranslationZ : 0.0f);
+ if (properties().getMatrixFlags() != 0) {
+ if (properties().getMatrixFlags() == TRANSLATION) {
+ matrix.translate(properties().getTranslationX(), properties().getTranslationY(),
+ true3dTransform ? properties().getTranslationZ() : 0.0f);
} else {
if (!true3dTransform) {
- matrix.multiply(*properties().mTransformMatrix);
+ matrix.multiply(*properties().getTransformMatrix());
} else {
mat4 true3dMat;
true3dMat.loadTranslate(
- properties().mPivotX + properties().mTranslationX,
- properties().mPivotY + properties().mTranslationY,
- properties().mTranslationZ);
- true3dMat.rotate(properties().mRotationX, 1, 0, 0);
- true3dMat.rotate(properties().mRotationY, 0, 1, 0);
- true3dMat.rotate(properties().mRotation, 0, 0, 1);
- true3dMat.scale(properties().mScaleX, properties().mScaleY, 1);
- true3dMat.translate(-properties().mPivotX, -properties().mPivotY);
+ properties().getPivotX() + properties().getTranslationX(),
+ properties().getPivotY() + properties().getTranslationY(),
+ properties().getTranslationZ());
+ true3dMat.rotate(properties().getRotationX(), 1, 0, 0);
+ true3dMat.rotate(properties().getRotationY(), 0, 1, 0);
+ true3dMat.rotate(properties().getRotation(), 0, 0, 1);
+ true3dMat.scale(properties().getScaleX(), properties().getScaleY(), 1);
+ true3dMat.translate(-properties().getPivotX(), -properties().getPivotY());
matrix.multiply(true3dMat);
}
@@ -280,7 +242,7 @@ void RenderNode::computeOrderingImpl(
Matrix4 localTransformFromProjectionSurface(*transformFromProjectionSurface);
localTransformFromProjectionSurface.multiply(opState->mTransformFromParent);
- if (properties().mProjectBackwards) {
+ if (properties().getProjectBackwards()) {
// composited projectee, flag for out of order draw, save matrix, and store in proj surface
opState->mSkipInOrderDraw = true;
opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface);
@@ -299,7 +261,7 @@ void RenderNode::computeOrderingImpl(
Vector<DrawDisplayListOp*>* projectionChildren = NULL;
const mat4* projectionTransform = NULL;
- if (isProjectionReceiver && !child->properties().mProjectBackwards) {
+ if (isProjectionReceiver && !child->properties().getProjectBackwards()) {
// if receiving projections, collect projecting descendent
// Note that if a direct descendent is projecting backwards, we pass it's
@@ -346,7 +308,7 @@ public:
: mReplayStruct(replayStruct), mLevel(level) {}
inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
- properties().mReplayStruct.mRenderer.eventMark(operation->name());
+ properties().getReplayStruct().mRenderer.eventMark(operation->name());
#endif
operation->replay(mReplayStruct, saveCount, mLevel, clipToBounds);
}
@@ -374,12 +336,12 @@ void RenderNode::buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslat
for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
DrawDisplayListOp* childOp = mDisplayListData->children[i];
RenderNode* child = childOp->mDisplayList;
- float childZ = child->properties().mTranslationZ;
+ float childZ = child->properties().getTranslationZ();
if (childZ != 0.0f) {
zTranslatedNodes.add(ZDrawDisplayListOpPair(childZ, childOp));
childOp->mSkipInOrderDraw = true;
- } else if (!child->properties().mProjectBackwards) {
+ } else if (!child->properties().getProjectBackwards()) {
// regular, in order drawing DisplayList
childOp->mSkipInOrderDraw = false;
}
@@ -404,9 +366,9 @@ void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTransl
int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
LinearAllocator& alloc = handler.allocator();
- ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, properties().mWidth, properties().mHeight,
+ ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, properties().getWidth(), properties().getHeight(),
SkRegion::kIntersect_Op); // clip to 3d root bounds
- handler(clipOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ handler(clipOp, PROPERTY_SAVECOUNT, properties().getClipToBounds());
/**
* Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
@@ -436,7 +398,7 @@ void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTransl
// OR if its caster's Z value is similar to the previous potential caster
if (shadowIndex == drawIndex || casterZ - lastCasterZ < SHADOW_DELTA) {
- if (caster->properties().mAlpha > 0.0f) {
+ if (caster->properties().getAlpha() > 0.0f) {
mat4 shadowMatrixXY(casterOp->mTransformFromParent);
caster->applyViewPropertyTransforms(shadowMatrixXY);
@@ -446,9 +408,9 @@ void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTransl
DisplayListOp* shadowOp = new (alloc) DrawShadowOp(
shadowMatrixXY, shadowMatrixZ,
- caster->properties().mAlpha, caster->properties().mOutline.getPath(),
- caster->properties().mWidth, caster->properties().mHeight);
- handler(shadowOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ caster->properties().getAlpha(), caster->properties().getOutline().getPath(),
+ caster->properties().getWidth(), caster->properties().getHeight());
+ handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
lastCasterZ = casterZ; // must do this even if current caster not casting a shadow
@@ -466,22 +428,22 @@ void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTransl
renderer.concatMatrix(childOp->mTransformFromParent);
childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
- handler(childOp, renderer.getSaveCount() - 1, properties().mClipToBounds);
+ handler(childOp, renderer.getSaveCount() - 1, properties().getClipToBounds());
childOp->mSkipInOrderDraw = true;
renderer.restoreToCount(restoreTo);
drawIndex++;
}
- handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
template <class T>
void RenderNode::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) {
int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
LinearAllocator& alloc = handler.allocator();
- ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, properties().mWidth, properties().mHeight,
+ ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, properties().getWidth(), properties().getHeight(),
SkRegion::kReplace_Op); // clip to projection surface root bounds
- handler(clipOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ handler(clipOp, PROPERTY_SAVECOUNT, properties().getClipToBounds());
for (size_t i = 0; i < mProjectedNodes.size(); i++) {
DrawDisplayListOp* childOp = mProjectedNodes[i];
@@ -490,11 +452,11 @@ void RenderNode::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler,
int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
renderer.concatMatrix(childOp->mTransformFromCompositingAncestor);
childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
- handler(childOp, renderer.getSaveCount() - 1, properties().mClipToBounds);
+ handler(childOp, renderer.getSaveCount() - 1, properties().getClipToBounds());
childOp->mSkipInOrderDraw = true;
renderer.restoreToCount(restoreTo);
}
- handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
/**
@@ -512,7 +474,7 @@ void RenderNode::iterate(OpenGLRenderer& renderer, T& handler, const int level)
ALOGW("Error: %s is drawing after destruction", mName.string());
CRASH();
}
- if (mDisplayListData->isEmpty() || properties().mAlpha <= 0) {
+ if (mDisplayListData->isEmpty() || properties().getAlpha() <= 0) {
DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string());
return;
}
@@ -527,14 +489,14 @@ void RenderNode::iterate(OpenGLRenderer& renderer, T& handler, const int level)
LinearAllocator& alloc = handler.allocator();
int restoreTo = renderer.getSaveCount();
handler(new (alloc) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag),
- PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ PROPERTY_SAVECOUNT, properties().getClipToBounds());
DISPLAY_LIST_LOGD("%*sSave %d %d", (level + 1) * 2, "",
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
setViewProperties<T>(renderer, handler, level + 1);
- bool quickRejected = properties().mClipToBounds && renderer.quickRejectConservative(0, 0, properties().mWidth, properties().mHeight);
+ bool quickRejected = properties().getClipToBounds() && renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight());
if (!quickRejected) {
Vector<ZDrawDisplayListOpPair> zTranslatedNodes;
buildZSortedChildList(zTranslatedNodes);
@@ -553,7 +515,7 @@ void RenderNode::iterate(OpenGLRenderer& renderer, T& handler, const int level)
#endif
logBuffer.writeCommand(level, op->name());
- handler(op, saveCountOffset, properties().mClipToBounds);
+ handler(op, saveCountOffset, properties().getClipToBounds());
if (CC_UNLIKELY(i == projectionReceiveIndex && mProjectedNodes.size() > 0)) {
iterateProjectedChildren(renderer, handler, level);
@@ -566,7 +528,7 @@ void RenderNode::iterate(OpenGLRenderer& renderer, T& handler, const int level)
DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo);
handler(new (alloc) RestoreToCountOp(restoreTo),
- PROPERTY_SAVECOUNT, properties().mClipToBounds);
+ PROPERTY_SAVECOUNT, properties().getClipToBounds());
renderer.setOverrideLayerAlpha(1.0f);
}
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 177f33e..9a7f9b4 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -112,10 +112,19 @@ public:
}
}
- RenderProperties& properties() {
+ const RenderProperties& properties() {
return mProperties;
}
+ const RenderProperties& stagingProperties() {
+ return mStagingProperties;
+ }
+
+ RenderProperties& mutateStagingProperties() {
+ mNeedsPropertiesSync = true;
+ return mStagingProperties;
+ }
+
bool isProjectionReceiver() {
return properties().isProjectionReceiver();
}
@@ -128,6 +137,8 @@ public:
return properties().getHeight();
}
+ void updateProperties();
+
private:
typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair;
@@ -143,8 +154,6 @@ private:
kPositiveZChildren
};
- void outputViewProperties(const int level);
-
void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false);
void computeOrderingImpl(DrawDisplayListOp* opState,
@@ -183,7 +192,10 @@ private:
String8 mName;
bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
+ bool mNeedsPropertiesSync;
RenderProperties mProperties;
+ RenderProperties mStagingProperties;
+
DisplayListData* mDisplayListData;
/**
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index 902a748..8b69b08 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -2,8 +2,8 @@
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * you mPrimitiveFields.may not use this file except in compliance with the License.
+ * You mPrimitiveFields.may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
@@ -13,8 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#define LOG_TAG "OpenGLRenderer"
+
#include "RenderProperties.h"
+#include <utils/Trace.h>
+
+#include <SkCanvas.h>
#include <SkMatrix.h>
#include "Matrix.h"
@@ -22,7 +28,7 @@
namespace android {
namespace uirenderer {
-RenderProperties::RenderProperties()
+RenderProperties::PrimitiveFields::PrimitiveFields()
: mClipToBounds(true)
, mProjectBackwards(false)
, mProjectionReceiver(false)
@@ -32,89 +38,146 @@ RenderProperties::RenderProperties()
, mRotation(0), mRotationX(0), mRotationY(0)
, mScaleX(1), mScaleY(1)
, mPivotX(0), mPivotY(0)
- , mCameraDistance(0)
, mLeft(0), mTop(0), mRight(0), mBottom(0)
, mWidth(0), mHeight(0)
, mPrevWidth(-1), mPrevHeight(-1)
, mPivotExplicitlySet(false)
, mMatrixDirty(false)
, mMatrixIsIdentity(true)
- , mTransformMatrix(NULL)
, mMatrixFlags(0)
- , mTransformCamera(NULL)
- , mTransformMatrix3D(NULL)
- , mStaticMatrix(NULL)
- , mAnimationMatrix(NULL)
, mCaching(false) {
}
-RenderProperties::~RenderProperties() {
+RenderProperties::ComputedFields::ComputedFields()
+ : mTransformMatrix(NULL)
+ , mTransformCamera(NULL)
+ , mTransformMatrix3D(NULL) {
+}
+
+RenderProperties::ComputedFields::~ComputedFields() {
delete mTransformMatrix;
delete mTransformCamera;
delete mTransformMatrix3D;
+}
+
+RenderProperties::RenderProperties()
+ : mCameraDistance(0)
+ , mStaticMatrix(NULL)
+ , mAnimationMatrix(NULL) {
+}
+
+RenderProperties::~RenderProperties() {
delete mStaticMatrix;
delete mAnimationMatrix;
}
-float RenderProperties::getPivotX() {
- updateMatrix();
- return mPivotX;
+RenderProperties& RenderProperties::operator=(const RenderProperties& other) {
+ if (this != &other) {
+ mPrimitiveFields = other.mPrimitiveFields;
+ setStaticMatrix(other.getStaticMatrix());
+ setAnimationMatrix(other.getAnimationMatrix());
+ setCameraDistance(other.getCameraDistance());
+
+ // Update the computed fields
+ updateMatrix();
+ }
+ return *this;
}
-float RenderProperties::getPivotY() {
- updateMatrix();
- return mPivotY;
+void RenderProperties::debugOutputProperties(const int level) const {
+ if (mPrimitiveFields.mLeft != 0 || mPrimitiveFields.mTop != 0) {
+ ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mPrimitiveFields.mLeft, mPrimitiveFields.mTop);
+ }
+ if (mStaticMatrix) {
+ ALOGD("%*sConcatMatrix (static) %p: " SK_MATRIX_STRING,
+ level * 2, "", mStaticMatrix, SK_MATRIX_ARGS(mStaticMatrix));
+ }
+ if (mAnimationMatrix) {
+ ALOGD("%*sConcatMatrix (animation) %p: " SK_MATRIX_STRING,
+ level * 2, "", mAnimationMatrix, SK_MATRIX_ARGS(mAnimationMatrix));
+ }
+ if (mPrimitiveFields.mMatrixFlags != 0) {
+ if (mPrimitiveFields.mMatrixFlags == TRANSLATION) {
+ ALOGD("%*sTranslate %.2f, %.2f, %.2f",
+ level * 2, "", mPrimitiveFields.mTranslationX, mPrimitiveFields.mTranslationY, mPrimitiveFields.mTranslationZ);
+ } else {
+ ALOGD("%*sConcatMatrix %p: " MATRIX_4_STRING,
+ level * 2, "", mComputedFields.mTransformMatrix, MATRIX_4_ARGS(mComputedFields.mTransformMatrix));
+ }
+ }
+
+ bool clipToBoundsNeeded = mPrimitiveFields.mCaching ? false : mPrimitiveFields.mClipToBounds;
+ if (mPrimitiveFields.mAlpha < 1) {
+ if (mPrimitiveFields.mCaching) {
+ ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha);
+ } else if (!mPrimitiveFields.mHasOverlappingRendering) {
+ ALOGD("%*sScaleAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha);
+ } else {
+ int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
+ if (clipToBoundsNeeded) {
+ flags |= SkCanvas::kClipToLayer_SaveFlag;
+ clipToBoundsNeeded = false; // clipping done by save layer
+ }
+ ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
+ (float) 0, (float) 0, (float) mPrimitiveFields.mRight - mPrimitiveFields.mLeft, (float) mPrimitiveFields.mBottom - mPrimitiveFields.mTop,
+ (int)(mPrimitiveFields.mAlpha * 255), flags);
+ }
+ }
+ if (clipToBoundsNeeded) {
+ ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
+ (float) mPrimitiveFields.mRight - mPrimitiveFields.mLeft, (float) mPrimitiveFields.mBottom - mPrimitiveFields.mTop);
+ }
}
void RenderProperties::updateMatrix() {
- if (mMatrixDirty) {
- // NOTE: mTransformMatrix won't be up to date if a DisplayList goes from a complex transform
- // to a pure translate. This is safe because the matrix isn't read in pure translate cases.
- if (mMatrixFlags && mMatrixFlags != TRANSLATION) {
- if (!mTransformMatrix) {
- // only allocate a matrix if we have a complex transform
- mTransformMatrix = new Matrix4();
+ if (mPrimitiveFields.mMatrixDirty) {
+ // NOTE: mComputedFields.mTransformMatrix won't be up to date if a DisplayList goes from a complex transform
+ // to a pure translate. This is safe because the mPrimitiveFields.matrix isn't read in pure translate cases.
+ if (mPrimitiveFields.mMatrixFlags && mPrimitiveFields.mMatrixFlags != TRANSLATION) {
+ if (!mComputedFields.mTransformMatrix) {
+ // only allocate a mPrimitiveFields.matrix if we have a complex transform
+ mComputedFields.mTransformMatrix = new Matrix4();
}
- if (!mPivotExplicitlySet) {
- if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
- mPrevWidth = mWidth;
- mPrevHeight = mHeight;
- mPivotX = mPrevWidth / 2.0f;
- mPivotY = mPrevHeight / 2.0f;
+ if (!mPrimitiveFields.mPivotExplicitlySet) {
+ if (mPrimitiveFields.mWidth != mPrimitiveFields.mPrevWidth || mPrimitiveFields.mHeight != mPrimitiveFields.mPrevHeight) {
+ mPrimitiveFields.mPrevWidth = mPrimitiveFields.mWidth;
+ mPrimitiveFields.mPrevHeight = mPrimitiveFields.mHeight;
+ mPrimitiveFields.mPivotX = mPrimitiveFields.mPrevWidth / 2.0f;
+ mPrimitiveFields.mPivotY = mPrimitiveFields.mPrevHeight / 2.0f;
}
}
- if ((mMatrixFlags & ROTATION_3D) == 0) {
- mTransformMatrix->loadTranslate(
- mPivotX + mTranslationX,
- mPivotY + mTranslationY,
+ if ((mPrimitiveFields.mMatrixFlags & ROTATION_3D) == 0) {
+ mComputedFields.mTransformMatrix->loadTranslate(
+ mPrimitiveFields.mPivotX + mPrimitiveFields.mTranslationX,
+ mPrimitiveFields.mPivotY + mPrimitiveFields.mTranslationY,
0);
- mTransformMatrix->rotate(mRotation, 0, 0, 1);
- mTransformMatrix->scale(mScaleX, mScaleY, 1);
- mTransformMatrix->translate(-mPivotX, -mPivotY);
+ mComputedFields.mTransformMatrix->rotate(mPrimitiveFields.mRotation, 0, 0, 1);
+ mComputedFields.mTransformMatrix->scale(mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, 1);
+ mComputedFields.mTransformMatrix->translate(-mPrimitiveFields.mPivotX, -mPrimitiveFields.mPivotY);
} else {
- if (!mTransformCamera) {
- mTransformCamera = new Sk3DView();
- mTransformMatrix3D = new SkMatrix();
+ if (!mComputedFields.mTransformCamera) {
+ mComputedFields.mTransformCamera = new Sk3DView();
+ mComputedFields.mTransformMatrix3D = new SkMatrix();
}
SkMatrix transformMatrix;
transformMatrix.reset();
- mTransformCamera->save();
- transformMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
- mTransformCamera->rotateX(mRotationX);
- mTransformCamera->rotateY(mRotationY);
- mTransformCamera->rotateZ(-mRotation);
- mTransformCamera->getMatrix(mTransformMatrix3D);
- mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
- mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
- mPivotY + mTranslationY);
- transformMatrix.postConcat(*mTransformMatrix3D);
- mTransformCamera->restore();
-
- mTransformMatrix->load(transformMatrix);
+ mComputedFields.mTransformCamera->save();
+ transformMatrix.preScale(mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY);
+ mComputedFields.mTransformCamera->rotateX(mPrimitiveFields.mRotationX);
+ mComputedFields.mTransformCamera->rotateY(mPrimitiveFields.mRotationY);
+ mComputedFields.mTransformCamera->rotateZ(-mPrimitiveFields.mRotation);
+ mComputedFields.mTransformCamera->getMatrix(mComputedFields.mTransformMatrix3D);
+ mComputedFields.mTransformMatrix3D->preTranslate(-mPrimitiveFields.mPivotX, -mPrimitiveFields.mPivotY);
+ mComputedFields.mTransformMatrix3D->postTranslate(mPrimitiveFields.mPivotX + mPrimitiveFields.mTranslationX,
+ mPrimitiveFields.mPivotY + mPrimitiveFields.mTranslationY);
+ transformMatrix.postConcat(*mComputedFields.mTransformMatrix3D);
+ mComputedFields.mTransformCamera->restore();
+
+ mComputedFields.mTransformMatrix->load(transformMatrix);
}
}
- mMatrixDirty = false;
+ mPrimitiveFields.mMatrixDirty = false;
}
}
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 57fa4ba..504196d 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -50,33 +50,39 @@ public:
RenderProperties();
virtual ~RenderProperties();
+ RenderProperties& operator=(const RenderProperties& other);
+
void setClipToBounds(bool clipToBounds) {
- mClipToBounds = clipToBounds;
+ mPrimitiveFields.mClipToBounds = clipToBounds;
}
void setProjectBackwards(bool shouldProject) {
- mProjectBackwards = shouldProject;
+ mPrimitiveFields.mProjectBackwards = shouldProject;
}
void setProjectionReceiver(bool shouldRecieve) {
- mProjectionReceiver = shouldRecieve;
+ mPrimitiveFields.mProjectionReceiver = shouldRecieve;
}
- bool isProjectionReceiver() {
- return mProjectionReceiver;
+ bool isProjectionReceiver() const {
+ return mPrimitiveFields.mProjectionReceiver;
}
- void setStaticMatrix(SkMatrix* matrix) {
+ void setStaticMatrix(const SkMatrix* matrix) {
delete mStaticMatrix;
- mStaticMatrix = new SkMatrix(*matrix);
+ if (matrix) {
+ mStaticMatrix = new SkMatrix(*matrix);
+ } else {
+ mStaticMatrix = NULL;
+ }
}
// Can return NULL
- SkMatrix* getStaticMatrix() {
+ const SkMatrix* getStaticMatrix() const {
return mStaticMatrix;
}
- void setAnimationMatrix(SkMatrix* matrix) {
+ void setAnimationMatrix(const SkMatrix* matrix) {
delete mAnimationMatrix;
if (matrix) {
mAnimationMatrix = new SkMatrix(*matrix);
@@ -87,171 +93,179 @@ public:
void setAlpha(float alpha) {
alpha = fminf(1.0f, fmaxf(0.0f, alpha));
- if (alpha != mAlpha) {
- mAlpha = alpha;
+ if (alpha != mPrimitiveFields.mAlpha) {
+ mPrimitiveFields.mAlpha = alpha;
}
}
float getAlpha() const {
- return mAlpha;
+ return mPrimitiveFields.mAlpha;
}
void setHasOverlappingRendering(bool hasOverlappingRendering) {
- mHasOverlappingRendering = hasOverlappingRendering;
+ mPrimitiveFields.mHasOverlappingRendering = hasOverlappingRendering;
}
bool hasOverlappingRendering() const {
- return mHasOverlappingRendering;
+ return mPrimitiveFields.mHasOverlappingRendering;
}
void setTranslationX(float translationX) {
- if (translationX != mTranslationX) {
- mTranslationX = translationX;
+ if (translationX != mPrimitiveFields.mTranslationX) {
+ mPrimitiveFields.mTranslationX = translationX;
onTranslationUpdate();
}
}
float getTranslationX() const {
- return mTranslationX;
+ return mPrimitiveFields.mTranslationX;
}
void setTranslationY(float translationY) {
- if (translationY != mTranslationY) {
- mTranslationY = translationY;
+ if (translationY != mPrimitiveFields.mTranslationY) {
+ mPrimitiveFields.mTranslationY = translationY;
onTranslationUpdate();
}
}
float getTranslationY() const {
- return mTranslationY;
+ return mPrimitiveFields.mTranslationY;
}
void setTranslationZ(float translationZ) {
- if (translationZ != mTranslationZ) {
- mTranslationZ = translationZ;
+ if (translationZ != mPrimitiveFields.mTranslationZ) {
+ mPrimitiveFields.mTranslationZ = translationZ;
onTranslationUpdate();
}
}
float getTranslationZ() const {
- return mTranslationZ;
+ return mPrimitiveFields.mTranslationZ;
}
void setRotation(float rotation) {
- if (rotation != mRotation) {
- mRotation = rotation;
- mMatrixDirty = true;
- if (mRotation == 0.0f) {
- mMatrixFlags &= ~ROTATION;
+ if (rotation != mPrimitiveFields.mRotation) {
+ mPrimitiveFields.mRotation = rotation;
+ mPrimitiveFields.mMatrixDirty = true;
+ if (mPrimitiveFields.mRotation == 0.0f) {
+ mPrimitiveFields.mMatrixFlags &= ~ROTATION;
} else {
- mMatrixFlags |= ROTATION;
+ mPrimitiveFields.mMatrixFlags |= ROTATION;
}
}
}
float getRotation() const {
- return mRotation;
+ return mPrimitiveFields.mRotation;
}
void setRotationX(float rotationX) {
- if (rotationX != mRotationX) {
- mRotationX = rotationX;
- mMatrixDirty = true;
- if (mRotationX == 0.0f && mRotationY == 0.0f) {
- mMatrixFlags &= ~ROTATION_3D;
+ if (rotationX != mPrimitiveFields.mRotationX) {
+ mPrimitiveFields.mRotationX = rotationX;
+ mPrimitiveFields.mMatrixDirty = true;
+ if (mPrimitiveFields.mRotationX == 0.0f && mPrimitiveFields.mRotationY == 0.0f) {
+ mPrimitiveFields.mMatrixFlags &= ~ROTATION_3D;
} else {
- mMatrixFlags |= ROTATION_3D;
+ mPrimitiveFields.mMatrixFlags |= ROTATION_3D;
}
}
}
float getRotationX() const {
- return mRotationX;
+ return mPrimitiveFields.mRotationX;
}
void setRotationY(float rotationY) {
- if (rotationY != mRotationY) {
- mRotationY = rotationY;
- mMatrixDirty = true;
- if (mRotationX == 0.0f && mRotationY == 0.0f) {
- mMatrixFlags &= ~ROTATION_3D;
+ if (rotationY != mPrimitiveFields.mRotationY) {
+ mPrimitiveFields.mRotationY = rotationY;
+ mPrimitiveFields.mMatrixDirty = true;
+ if (mPrimitiveFields.mRotationX == 0.0f && mPrimitiveFields.mRotationY == 0.0f) {
+ mPrimitiveFields.mMatrixFlags &= ~ROTATION_3D;
} else {
- mMatrixFlags |= ROTATION_3D;
+ mPrimitiveFields.mMatrixFlags |= ROTATION_3D;
}
}
}
float getRotationY() const {
- return mRotationY;
+ return mPrimitiveFields.mRotationY;
}
void setScaleX(float scaleX) {
- if (scaleX != mScaleX) {
- mScaleX = scaleX;
- mMatrixDirty = true;
- if (mScaleX == 1.0f && mScaleY == 1.0f) {
- mMatrixFlags &= ~SCALE;
+ if (scaleX != mPrimitiveFields.mScaleX) {
+ mPrimitiveFields.mScaleX = scaleX;
+ mPrimitiveFields.mMatrixDirty = true;
+ if (mPrimitiveFields.mScaleX == 1.0f && mPrimitiveFields.mScaleY == 1.0f) {
+ mPrimitiveFields.mMatrixFlags &= ~SCALE;
} else {
- mMatrixFlags |= SCALE;
+ mPrimitiveFields.mMatrixFlags |= SCALE;
}
}
}
float getScaleX() const {
- return mScaleX;
+ return mPrimitiveFields.mScaleX;
}
void setScaleY(float scaleY) {
- if (scaleY != mScaleY) {
- mScaleY = scaleY;
- mMatrixDirty = true;
- if (mScaleX == 1.0f && mScaleY == 1.0f) {
- mMatrixFlags &= ~SCALE;
+ if (scaleY != mPrimitiveFields.mScaleY) {
+ mPrimitiveFields.mScaleY = scaleY;
+ mPrimitiveFields.mMatrixDirty = true;
+ if (mPrimitiveFields.mScaleX == 1.0f && mPrimitiveFields.mScaleY == 1.0f) {
+ mPrimitiveFields.mMatrixFlags &= ~SCALE;
} else {
- mMatrixFlags |= SCALE;
+ mPrimitiveFields.mMatrixFlags |= SCALE;
}
}
}
float getScaleY() const {
- return mScaleY;
+ return mPrimitiveFields.mScaleY;
}
void setPivotX(float pivotX) {
- mPivotX = pivotX;
- mMatrixDirty = true;
- if (mPivotX == 0.0f && mPivotY == 0.0f) {
- mMatrixFlags &= ~PIVOT;
+ mPrimitiveFields.mPivotX = pivotX;
+ mPrimitiveFields.mMatrixDirty = true;
+ if (mPrimitiveFields.mPivotX == 0.0f && mPrimitiveFields.mPivotY == 0.0f) {
+ mPrimitiveFields.mMatrixFlags &= ~PIVOT;
} else {
- mMatrixFlags |= PIVOT;
+ mPrimitiveFields.mMatrixFlags |= PIVOT;
}
- mPivotExplicitlySet = true;
+ mPrimitiveFields.mPivotExplicitlySet = true;
}
- ANDROID_API float getPivotX();
+ /* Note that getPivotX and getPivotY are adjusted by updateMatrix(),
+ * so the value returned mPrimitiveFields.may be stale if the RenderProperties has been
+ * mPrimitiveFields.modified since the last call to updateMatrix()
+ */
+ float getPivotX() const {
+ return mPrimitiveFields.mPivotX;
+ }
void setPivotY(float pivotY) {
- mPivotY = pivotY;
- mMatrixDirty = true;
- if (mPivotX == 0.0f && mPivotY == 0.0f) {
- mMatrixFlags &= ~PIVOT;
+ mPrimitiveFields.mPivotY = pivotY;
+ mPrimitiveFields.mMatrixDirty = true;
+ if (mPrimitiveFields.mPivotX == 0.0f && mPrimitiveFields.mPivotY == 0.0f) {
+ mPrimitiveFields.mMatrixFlags &= ~PIVOT;
} else {
- mMatrixFlags |= PIVOT;
+ mPrimitiveFields.mMatrixFlags |= PIVOT;
}
- mPivotExplicitlySet = true;
+ mPrimitiveFields.mPivotExplicitlySet = true;
}
- ANDROID_API float getPivotY();
+ float getPivotY() const {
+ return mPrimitiveFields.mPivotY;
+ }
void setCameraDistance(float distance) {
if (distance != mCameraDistance) {
mCameraDistance = distance;
- mMatrixDirty = true;
- if (!mTransformCamera) {
- mTransformCamera = new Sk3DView();
- mTransformMatrix3D = new SkMatrix();
+ mPrimitiveFields.mMatrixDirty = true;
+ if (!mComputedFields.mTransformCamera) {
+ mComputedFields.mTransformCamera = new Sk3DView();
+ mComputedFields.mTransformMatrix3D = new SkMatrix();
}
- mTransformCamera->setCameraLocation(0, 0, distance);
+ mComputedFields.mTransformCamera->setCameraLocation(0, 0, distance);
}
}
@@ -260,170 +274,216 @@ public:
}
void setLeft(int left) {
- if (left != mLeft) {
- mLeft = left;
- mWidth = mRight - mLeft;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
+ if (left != mPrimitiveFields.mLeft) {
+ mPrimitiveFields.mLeft = left;
+ mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
+ if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mMatrixDirty = true;
}
}
}
float getLeft() const {
- return mLeft;
+ return mPrimitiveFields.mLeft;
}
void setTop(int top) {
- if (top != mTop) {
- mTop = top;
- mHeight = mBottom - mTop;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
+ if (top != mPrimitiveFields.mTop) {
+ mPrimitiveFields.mTop = top;
+ mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
+ if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mMatrixDirty = true;
}
}
}
float getTop() const {
- return mTop;
+ return mPrimitiveFields.mTop;
}
void setRight(int right) {
- if (right != mRight) {
- mRight = right;
- mWidth = mRight - mLeft;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
+ if (right != mPrimitiveFields.mRight) {
+ mPrimitiveFields.mRight = right;
+ mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
+ if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mMatrixDirty = true;
}
}
}
float getRight() const {
- return mRight;
+ return mPrimitiveFields.mRight;
}
void setBottom(int bottom) {
- if (bottom != mBottom) {
- mBottom = bottom;
- mHeight = mBottom - mTop;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
+ if (bottom != mPrimitiveFields.mBottom) {
+ mPrimitiveFields.mBottom = bottom;
+ mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
+ if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mMatrixDirty = true;
}
}
}
float getBottom() const {
- return mBottom;
+ return mPrimitiveFields.mBottom;
}
void setLeftTop(int left, int top) {
- if (left != mLeft || top != mTop) {
- mLeft = left;
- mTop = top;
- mWidth = mRight - mLeft;
- mHeight = mBottom - mTop;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
+ if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop) {
+ mPrimitiveFields.mLeft = left;
+ mPrimitiveFields.mTop = top;
+ mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
+ mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
+ if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mMatrixDirty = true;
}
}
}
void setLeftTopRightBottom(int left, int top, int right, int bottom) {
- if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
- mLeft = left;
- mTop = top;
- mRight = right;
- mBottom = bottom;
- mWidth = mRight - mLeft;
- mHeight = mBottom - mTop;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
+ if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop || right != mPrimitiveFields.mRight || bottom != mPrimitiveFields.mBottom) {
+ mPrimitiveFields.mLeft = left;
+ mPrimitiveFields.mTop = top;
+ mPrimitiveFields.mRight = right;
+ mPrimitiveFields.mBottom = bottom;
+ mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
+ mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
+ if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mMatrixDirty = true;
}
}
}
void offsetLeftRight(float offset) {
if (offset != 0) {
- mLeft += offset;
- mRight += offset;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
+ mPrimitiveFields.mLeft += offset;
+ mPrimitiveFields.mRight += offset;
+ if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mMatrixDirty = true;
}
}
}
void offsetTopBottom(float offset) {
if (offset != 0) {
- mTop += offset;
- mBottom += offset;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
+ mPrimitiveFields.mTop += offset;
+ mPrimitiveFields.mBottom += offset;
+ if (mPrimitiveFields.mMatrixFlags > TRANSLATION && !mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mMatrixDirty = true;
}
}
}
void setCaching(bool caching) {
- mCaching = caching;
+ mPrimitiveFields.mCaching = caching;
}
int getWidth() const {
- return mWidth;
+ return mPrimitiveFields.mWidth;
}
int getHeight() const {
- return mHeight;
+ return mPrimitiveFields.mHeight;
+ }
+
+ const SkMatrix* getAnimationMatrix() const {
+ return mAnimationMatrix;
+ }
+
+ uint32_t getMatrixFlags() const {
+ return mPrimitiveFields.mMatrixFlags;
+ }
+
+ const Matrix4* getTransformMatrix() const {
+ return mComputedFields.mTransformMatrix;
+ }
+
+ bool getCaching() const {
+ return mPrimitiveFields.mCaching;
}
- Outline& outline() {
- return mOutline;
+ bool getClipToBounds() const {
+ return mPrimitiveFields.mClipToBounds;
+ }
+
+ bool getHasOverlappingRendering() const {
+ return mPrimitiveFields.mHasOverlappingRendering;
+ }
+
+ const Outline& getOutline() const {
+ return mPrimitiveFields.mOutline;
+ }
+
+ bool getProjectBackwards() const {
+ return mPrimitiveFields.mProjectBackwards;
+ }
+
+ void debugOutputProperties(const int level) const;
+
+ ANDROID_API void updateMatrix();
+
+ Outline& mutableOutline() {
+ return mPrimitiveFields.mOutline;
}
private:
void onTranslationUpdate() {
- mMatrixDirty = true;
- if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) {
- mMatrixFlags &= ~TRANSLATION;
+ mPrimitiveFields.mMatrixDirty = true;
+ if (mPrimitiveFields.mTranslationX == 0.0f && mPrimitiveFields.mTranslationY == 0.0f && mPrimitiveFields.mTranslationZ == 0.0f) {
+ mPrimitiveFields.mMatrixFlags &= ~TRANSLATION;
} else {
- mMatrixFlags |= TRANSLATION;
+ mPrimitiveFields.mMatrixFlags |= TRANSLATION;
}
}
- void updateMatrix();
-
// Rendering properties
- Outline mOutline;
- bool mClipToBounds;
- bool mProjectBackwards;
- bool mProjectionReceiver;
- float mAlpha;
- bool mHasOverlappingRendering;
- float mTranslationX, mTranslationY, mTranslationZ;
- float mRotation, mRotationX, mRotationY;
- float mScaleX, mScaleY;
- float mPivotX, mPivotY;
+ struct PrimitiveFields {
+ PrimitiveFields();
+
+ Outline mOutline;
+ bool mClipToBounds;
+ bool mProjectBackwards;
+ bool mProjectionReceiver;
+ float mAlpha;
+ bool mHasOverlappingRendering;
+ float mTranslationX, mTranslationY, mTranslationZ;
+ float mRotation, mRotationX, mRotationY;
+ float mScaleX, mScaleY;
+ float mPivotX, mPivotY;
+ int mLeft, mTop, mRight, mBottom;
+ int mWidth, mHeight;
+ int mPrevWidth, mPrevHeight;
+ bool mPivotExplicitlySet;
+ bool mMatrixDirty;
+ bool mMatrixIsIdentity;
+ uint32_t mMatrixFlags;
+ bool mCaching;
+ } mPrimitiveFields;
+
+ // mCameraDistance isn't in mPrimitiveFields as it has a complex setter
float mCameraDistance;
- int mLeft, mTop, mRight, mBottom;
- int mWidth, mHeight;
- int mPrevWidth, mPrevHeight;
- bool mPivotExplicitlySet;
- bool mMatrixDirty;
- bool mMatrixIsIdentity;
-
- /**
- * Stores the total transformation of the DisplayList based upon its scalar
- * translate/rotate/scale properties.
- *
- * In the common translation-only case, the matrix isn't allocated and the mTranslation
- * properties are used directly.
- */
- Matrix4* mTransformMatrix;
- uint32_t mMatrixFlags;
- Sk3DView* mTransformCamera;
- SkMatrix* mTransformMatrix3D;
SkMatrix* mStaticMatrix;
SkMatrix* mAnimationMatrix;
- bool mCaching;
- friend class RenderNode;
+ /**
+ * These fields are all generated from other properties and are not set directly.
+ */
+ struct ComputedFields {
+ ComputedFields();
+ ~ComputedFields();
+
+ /**
+ * Stores the total transformation of the DisplayList based upon its scalar
+ * translate/rotate/scale properties.
+ *
+ * In the common translation-only case, the matrix isn't allocated and the mTranslation
+ * properties are used directly.
+ */
+ Matrix4* mTransformMatrix;
+ Sk3DView* mTransformCamera;
+ SkMatrix* mTransformMatrix3D;
+ } mComputedFields;
};
} /* namespace uirenderer */