summaryrefslogtreecommitdiff
path: root/libs/hwui/RenderProperties.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/RenderProperties.cpp')
-rw-r--r--libs/hwui/RenderProperties.cpp165
1 files changed, 165 insertions, 0 deletions
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
new file mode 100644
index 000000000000..6163df5aef3f
--- /dev/null
+++ b/libs/hwui/RenderProperties.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * 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 <SkPath.h>
+#include <SkPathOps.h>
+
+#include "Matrix.h"
+#include "utils/MathUtils.h"
+
+namespace android {
+namespace uirenderer {
+
+RenderProperties::PrimitiveFields::PrimitiveFields()
+ : mClipToBounds(true)
+ , mProjectBackwards(false)
+ , mProjectionReceiver(false)
+ , mAlpha(1)
+ , mHasOverlappingRendering(true)
+ , mElevation(0)
+ , mTranslationX(0), mTranslationY(0), mTranslationZ(0)
+ , mRotation(0), mRotationX(0), mRotationY(0)
+ , mScaleX(1), mScaleY(1)
+ , mPivotX(0), mPivotY(0)
+ , mLeft(0), mTop(0), mRight(0), mBottom(0)
+ , mWidth(0), mHeight(0)
+ , mScrollX(0), mScrollY(0)
+ , mPivotExplicitlySet(false)
+ , mMatrixOrPivotDirty(false)
+ , mCaching(false) {
+}
+
+RenderProperties::ComputedFields::ComputedFields()
+ : mTransformMatrix(NULL) {
+}
+
+RenderProperties::ComputedFields::~ComputedFields() {
+ delete mTransformMatrix;
+}
+
+RenderProperties::RenderProperties()
+ : mStaticMatrix(NULL)
+ , mAnimationMatrix(NULL) {
+}
+
+RenderProperties::~RenderProperties() {
+ delete mStaticMatrix;
+ delete mAnimationMatrix;
+}
+
+RenderProperties& RenderProperties::operator=(const RenderProperties& other) {
+ if (this != &other) {
+ mPrimitiveFields = other.mPrimitiveFields;
+ setStaticMatrix(other.getStaticMatrix());
+ setAnimationMatrix(other.getAnimationMatrix());
+ setCameraDistance(other.getCameraDistance());
+
+ // Force recalculation of the matrix, since other's dirty bit may be clear
+ mPrimitiveFields.mMatrixOrPivotDirty = true;
+ updateMatrix();
+ }
+ return *this;
+}
+
+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 (hasTransformMatrix()) {
+ if (isTransformTranslateOnly()) {
+ ALOGD("%*sTranslate %.2f, %.2f, %.2f",
+ level * 2, "", getTranslationX(), getTranslationY(), getZ());
+ } else {
+ ALOGD("%*sConcatMatrix %p: " SK_MATRIX_STRING,
+ level * 2, "", mComputedFields.mTransformMatrix, SK_MATRIX_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 %d, %d, %d, %d, %d, 0x%x", level * 2, "",
+ 0, 0, getWidth(), getHeight(),
+ (int)(mPrimitiveFields.mAlpha * 255), flags);
+ }
+ }
+ if (clipToBoundsNeeded) {
+ ALOGD("%*sClipRect %d, %d, %d, %d", level * 2, "",
+ 0, 0, getWidth(), getHeight());
+ }
+}
+
+void RenderProperties::updateMatrix() {
+ if (mPrimitiveFields.mMatrixOrPivotDirty) {
+ if (!mComputedFields.mTransformMatrix) {
+ // only allocate a mPrimitiveFields.matrix if we have a complex transform
+ mComputedFields.mTransformMatrix = new SkMatrix();
+ }
+ if (!mPrimitiveFields.mPivotExplicitlySet) {
+ mPrimitiveFields.mPivotX = mPrimitiveFields.mWidth / 2.0f;
+ mPrimitiveFields.mPivotY = mPrimitiveFields.mHeight / 2.0f;
+ }
+ SkMatrix* transform = mComputedFields.mTransformMatrix;
+ transform->reset();
+ if (MathUtils::isZero(getRotationX()) && MathUtils::isZero(getRotationY())) {
+ transform->setTranslate(getTranslationX(), getTranslationY());
+ transform->preRotate(getRotation(), getPivotX(), getPivotY());
+ transform->preScale(getScaleX(), getScaleY(), getPivotX(), getPivotY());
+ } else {
+ SkMatrix transform3D;
+ mComputedFields.mTransformCamera.save();
+ transform->preScale(getScaleX(), getScaleY(), getPivotX(), getPivotY());
+ mComputedFields.mTransformCamera.rotateX(mPrimitiveFields.mRotationX);
+ mComputedFields.mTransformCamera.rotateY(mPrimitiveFields.mRotationY);
+ mComputedFields.mTransformCamera.rotateZ(-mPrimitiveFields.mRotation);
+ mComputedFields.mTransformCamera.getMatrix(&transform3D);
+ transform3D.preTranslate(-getPivotX(), -getPivotY());
+ transform3D.postTranslate(getPivotX() + getTranslationX(),
+ getPivotY() + getTranslationY());
+ transform->postConcat(transform3D);
+ mComputedFields.mTransformCamera.restore();
+ }
+ mPrimitiveFields.mMatrixOrPivotDirty = false;
+ }
+}
+
+} /* namespace uirenderer */
+} /* namespace android */