RenderProperties.cpp revision 91eff22b5d7f8fe551bae01331948858ce932a96
1acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck/* 2acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * Copyright (C) 2014 The Android Open Source Project 3acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * 4acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck * you mPrimitiveFields.may not use this file except in compliance with the License. 6d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck * You mPrimitiveFields.may obtain a copy of the License at 7acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * 8acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * http://www.apache.org/licenses/LICENSE-2.0 9acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * 10acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * Unless required by applicable law or agreed to in writing, software 11acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * distributed under the License is distributed on an "AS IS" BASIS, 12acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * See the License for the specific language governing permissions and 14acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck * limitations under the License. 15acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck */ 16d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 17acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck#include "RenderProperties.h" 18acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck 19d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck#include <utils/Trace.h> 20d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 2125fbb3fa1138675379102a44405852555cefccbdJohn Reck#include <SkColorFilter.h> 22acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck#include <SkMatrix.h> 238c271ca63b62061fd22cfee78fd6a574b44476fdChris Craik#include <SkPath.h> 248c271ca63b62061fd22cfee78fd6a574b44476fdChris Craik#include <SkPathOps.h> 25acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck 26eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita#include "Canvas.h" 27acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck#include "Matrix.h" 2825fbb3fa1138675379102a44405852555cefccbdJohn Reck#include "OpenGLRenderer.h" 29e0bb87d4bdbd3b08ab6a8569c8e564ed59b8a5a7Chris Craik#include "utils/MathUtils.h" 30f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck 31acb6f07623b7df3d4179f70ae03ade574616ffa6John Recknamespace android { 32acb6f07623b7df3d4179f70ae03ade574616ffa6John Recknamespace uirenderer { 33acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck 34182952f5eeefc2a21d76d4664ada0e2d78c1105cChris CraikLayerProperties::LayerProperties() { 3525fbb3fa1138675379102a44405852555cefccbdJohn Reck reset(); 3625fbb3fa1138675379102a44405852555cefccbdJohn Reck} 3725fbb3fa1138675379102a44405852555cefccbdJohn Reck 3825fbb3fa1138675379102a44405852555cefccbdJohn ReckLayerProperties::~LayerProperties() { 39182952f5eeefc2a21d76d4664ada0e2d78c1105cChris Craik setType(LayerType::None); 4025fbb3fa1138675379102a44405852555cefccbdJohn Reck} 4125fbb3fa1138675379102a44405852555cefccbdJohn Reck 4225fbb3fa1138675379102a44405852555cefccbdJohn Reckvoid LayerProperties::reset() { 4325fbb3fa1138675379102a44405852555cefccbdJohn Reck mOpaque = false; 44d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik setFromPaint(nullptr); 4525fbb3fa1138675379102a44405852555cefccbdJohn Reck} 4625fbb3fa1138675379102a44405852555cefccbdJohn Reck 4725fbb3fa1138675379102a44405852555cefccbdJohn Reckbool LayerProperties::setColorFilter(SkColorFilter* filter) { 4825fbb3fa1138675379102a44405852555cefccbdJohn Reck if (mColorFilter == filter) return false; 4925fbb3fa1138675379102a44405852555cefccbdJohn Reck SkRefCnt_SafeAssign(mColorFilter, filter); 5025fbb3fa1138675379102a44405852555cefccbdJohn Reck return true; 5125fbb3fa1138675379102a44405852555cefccbdJohn Reck} 5225fbb3fa1138675379102a44405852555cefccbdJohn Reck 5325fbb3fa1138675379102a44405852555cefccbdJohn Reckbool LayerProperties::setFromPaint(const SkPaint* paint) { 5425fbb3fa1138675379102a44405852555cefccbdJohn Reck bool changed = false; 55bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik changed |= setAlpha(static_cast<uint8_t>(PaintUtils::getAlphaDirect(paint))); 56bf6f0f260886a04a1680c7f9917124a751322ca4Chris Craik changed |= setXferMode(PaintUtils::getXfermodeDirect(paint)); 57d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik changed |= setColorFilter(paint ? paint->getColorFilter() : nullptr); 5825fbb3fa1138675379102a44405852555cefccbdJohn Reck return changed; 5925fbb3fa1138675379102a44405852555cefccbdJohn Reck} 6025fbb3fa1138675379102a44405852555cefccbdJohn Reck 6125fbb3fa1138675379102a44405852555cefccbdJohn ReckLayerProperties& LayerProperties::operator=(const LayerProperties& other) { 6225fbb3fa1138675379102a44405852555cefccbdJohn Reck setType(other.type()); 6325fbb3fa1138675379102a44405852555cefccbdJohn Reck setOpaque(other.opaque()); 6425fbb3fa1138675379102a44405852555cefccbdJohn Reck setAlpha(other.alpha()); 6525fbb3fa1138675379102a44405852555cefccbdJohn Reck setXferMode(other.xferMode()); 6625fbb3fa1138675379102a44405852555cefccbdJohn Reck setColorFilter(other.colorFilter()); 6725fbb3fa1138675379102a44405852555cefccbdJohn Reck return *this; 6825fbb3fa1138675379102a44405852555cefccbdJohn Reck} 6925fbb3fa1138675379102a44405852555cefccbdJohn Reck 70d0a0b2a3140bfb1819a116413ce9d81886697a07John ReckRenderProperties::ComputedFields::ComputedFields() 71d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : mTransformMatrix(nullptr) { 72d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck} 73d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 74d0a0b2a3140bfb1819a116413ce9d81886697a07John ReckRenderProperties::ComputedFields::~ComputedFields() { 75acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck delete mTransformMatrix; 76d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck} 77d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 78d0a0b2a3140bfb1819a116413ce9d81886697a07John ReckRenderProperties::RenderProperties() 79d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik : mStaticMatrix(nullptr) 80d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mAnimationMatrix(nullptr) { 81d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck} 82d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 83d0a0b2a3140bfb1819a116413ce9d81886697a07John ReckRenderProperties::~RenderProperties() { 84acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck delete mStaticMatrix; 85acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck delete mAnimationMatrix; 86acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck} 87acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck 88d0a0b2a3140bfb1819a116413ce9d81886697a07John ReckRenderProperties& RenderProperties::operator=(const RenderProperties& other) { 89d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (this != &other) { 90d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck mPrimitiveFields = other.mPrimitiveFields; 91d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck setStaticMatrix(other.getStaticMatrix()); 92d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck setAnimationMatrix(other.getAnimationMatrix()); 93d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck setCameraDistance(other.getCameraDistance()); 9425fbb3fa1138675379102a44405852555cefccbdJohn Reck mLayerProperties = other.layerProperties(); 95d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 9649e6c73913e9bee58ea5e3984be151ee8e033163Chris Craik // Force recalculation of the matrix, since other's dirty bit may be clear 97f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mPrimitiveFields.mMatrixOrPivotDirty = true; 9849e6c73913e9bee58ea5e3984be151ee8e033163Chris Craik updateMatrix(); 99d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 100d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck return *this; 101acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck} 102acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck 103d0a0b2a3140bfb1819a116413ce9d81886697a07John Reckvoid RenderProperties::debugOutputProperties(const int level) const { 104d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (mPrimitiveFields.mLeft != 0 || mPrimitiveFields.mTop != 0) { 10591eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s(Translate (left, top) %d, %d)", level * 2, "", 10691eff22b5d7f8fe551bae01331948858ce932a96Chris Craik mPrimitiveFields.mLeft, mPrimitiveFields.mTop); 107d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 108d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (mStaticMatrix) { 10991eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s(ConcatMatrix (static) %p: " SK_MATRIX_STRING ")", 110d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck level * 2, "", mStaticMatrix, SK_MATRIX_ARGS(mStaticMatrix)); 111d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 112d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (mAnimationMatrix) { 11391eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s(ConcatMatrix (animation) %p: " SK_MATRIX_STRING ")", 114d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck level * 2, "", mAnimationMatrix, SK_MATRIX_ARGS(mAnimationMatrix)); 115d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 116f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck if (hasTransformMatrix()) { 117f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck if (isTransformTranslateOnly()) { 11891eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s(Translate %.2f, %.2f, %.2f)", 119cc39e16cb98855f35079941b5e7e6eac2b7bc388Chris Craik level * 2, "", getTranslationX(), getTranslationY(), getZ()); 120d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } else { 12191eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s(ConcatMatrix %p: " SK_MATRIX_STRING ")", 12249e6c73913e9bee58ea5e3984be151ee8e033163Chris Craik level * 2, "", mComputedFields.mTransformMatrix, SK_MATRIX_ARGS(mComputedFields.mTransformMatrix)); 123d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 124d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 125d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 126856f0cc3e382206e67c1a62fe878627d7dd9ada5Chris Craik const bool isLayer = effectiveLayerType() != LayerType::None; 127a753f4c6cb8558795e673df1896532cd148781e2Chris Craik int clipFlags = getClippingFlags(); 12843a1d31a2837406a437937b340db85c1a05ed1edChris Craik if (mPrimitiveFields.mAlpha < 1 12943a1d31a2837406a437937b340db85c1a05ed1edChris Craik && !MathUtils::isZero(mPrimitiveFields.mAlpha)) { 130a753f4c6cb8558795e673df1896532cd148781e2Chris Craik if (isLayer) { 131a753f4c6cb8558795e673df1896532cd148781e2Chris Craik clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer 132d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 1338df5ffa9ae0667d9e0241adf4675753156fcef84Chris Craik 1344e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik if (CC_LIKELY(isLayer || !getHasOverlappingRendering())) { 1354e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik // simply scale rendering content's alpha 13691eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s(ScaleAlpha %.2f)", level * 2, "", mPrimitiveFields.mAlpha); 1374e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik } else { 1384e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik // savelayeralpha to create an offscreen buffer to apply alpha 1394e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik Rect layerBounds(0, 0, getWidth(), getHeight()); 1404e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik if (clipFlags) { 1414e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik getClippingRectForFlags(clipFlags, &layerBounds); 1424e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik clipFlags = 0; // all clipping done by savelayer 1434e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik } 14491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s(SaveLayerAlpha %d, %d, %d, %d, %d, 0x%x)", level * 2, "", 1454e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik (int)layerBounds.left, (int)layerBounds.top, 1464e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik (int)layerBounds.right, (int)layerBounds.bottom, 1474e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik (int)(mPrimitiveFields.mAlpha * 255), 148eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer); 1494e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik } 150d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 15191eff22b5d7f8fe551bae01331948858ce932a96Chris Craik 152a753f4c6cb8558795e673df1896532cd148781e2Chris Craik if (clipFlags) { 153a753f4c6cb8558795e673df1896532cd148781e2Chris Craik Rect clipRect; 154a753f4c6cb8558795e673df1896532cd148781e2Chris Craik getClippingRectForFlags(clipFlags, &clipRect); 15591eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s(ClipRect %d, %d, %d, %d)", level * 2, "", 156a753f4c6cb8558795e673df1896532cd148781e2Chris Craik (int)clipRect.left, (int)clipRect.top, (int)clipRect.right, (int)clipRect.bottom); 157d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } 158acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck} 159acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck 160acb6f07623b7df3d4179f70ae03ade574616ffa6John Reckvoid RenderProperties::updateMatrix() { 161f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck if (mPrimitiveFields.mMatrixOrPivotDirty) { 162f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck if (!mComputedFields.mTransformMatrix) { 163f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck // only allocate a mPrimitiveFields.matrix if we have a complex transform 164f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mComputedFields.mTransformMatrix = new SkMatrix(); 165f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck } 166f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck if (!mPrimitiveFields.mPivotExplicitlySet) { 167f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mPrimitiveFields.mPivotX = mPrimitiveFields.mWidth / 2.0f; 168f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mPrimitiveFields.mPivotY = mPrimitiveFields.mHeight / 2.0f; 169f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck } 170f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck SkMatrix* transform = mComputedFields.mTransformMatrix; 171f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck transform->reset(); 172e0bb87d4bdbd3b08ab6a8569c8e564ed59b8a5a7Chris Craik if (MathUtils::isZero(getRotationX()) && MathUtils::isZero(getRotationY())) { 173f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck transform->setTranslate(getTranslationX(), getTranslationY()); 174f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck transform->preRotate(getRotation(), getPivotX(), getPivotY()); 175f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck transform->preScale(getScaleX(), getScaleY(), getPivotX(), getPivotY()); 176f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck } else { 177f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck SkMatrix transform3D; 178f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mComputedFields.mTransformCamera.save(); 179f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck transform->preScale(getScaleX(), getScaleY(), getPivotX(), getPivotY()); 180f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mComputedFields.mTransformCamera.rotateX(mPrimitiveFields.mRotationX); 181f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mComputedFields.mTransformCamera.rotateY(mPrimitiveFields.mRotationY); 182f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mComputedFields.mTransformCamera.rotateZ(-mPrimitiveFields.mRotation); 183f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mComputedFields.mTransformCamera.getMatrix(&transform3D); 184f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck transform3D.preTranslate(-getPivotX(), -getPivotY()); 185f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck transform3D.postTranslate(getPivotX() + getTranslationX(), 186f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck getPivotY() + getTranslationY()); 187f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck transform->postConcat(transform3D); 188f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mComputedFields.mTransformCamera.restore(); 189acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck } 190f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck mPrimitiveFields.mMatrixOrPivotDirty = false; 191acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck } 192acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck} 193acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck 194acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck} /* namespace uirenderer */ 195acb6f07623b7df3d4179f70ae03ade574616ffa6John Reck} /* namespace android */ 196