diff options
author | John Reck <jreck@google.com> | 2014-03-20 16:28:56 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-03-24 15:31:34 -0700 |
commit | d0a0b2a3140bfb1819a116413ce9d81886697a07 (patch) | |
tree | 0040f371f29280deb83d1fd55f2db86e30d58c37 /libs | |
parent | de02cdc1e95cea19b2ddef26d60ad1d109bd507c (diff) | |
download | frameworks_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.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/Outline.h | 2 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 190 | ||||
-rw-r--r-- | libs/hwui/RenderNode.h | 18 | ||||
-rw-r--r-- | libs/hwui/RenderProperties.cpp | 169 | ||||
-rw-r--r-- | libs/hwui/RenderProperties.h | 392 |
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 */ |