diff options
author | 2021-05-10 22:12:48 +0000 | |
---|---|---|
committer | 2021-05-10 22:12:48 +0000 | |
commit | 020efbc1a8feda5670f1b7b7cd75e79dcacbaa94 (patch) | |
tree | 47343aebfbb96daff0bb9bf62ba458410d49ec12 /libs | |
parent | d825a07bc472f206a0066d6a11a32ac6deebe1f7 (diff) | |
parent | 8ed00dc56d5af7483ed053eb88c550cc1035b029 (diff) |
Merge "Add a linear variant of the stretch effect" into sc-dev
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DamageAccumulator.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/Properties.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 9 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/effects/StretchEffect.h | 9 | ||||
-rw-r--r-- | libs/hwui/jni/android_graphics_RenderNode.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/RenderNodeDrawable.cpp | 17 |
7 files changed, 59 insertions, 3 deletions
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp index cf3ef40b688a..a1642339190a 100644 --- a/libs/hwui/DamageAccumulator.cpp +++ b/libs/hwui/DamageAccumulator.cpp @@ -150,9 +150,19 @@ static inline void applyMatrix(const SkMatrix* transform, SkRect* rect) { } } +static inline void applyMatrix(const SkMatrix& transform, SkRect* rect) { + return applyMatrix(&transform, rect); +} + static inline void mapRect(const RenderProperties& props, const SkRect& in, SkRect* out) { if (in.isEmpty()) return; SkRect temp(in); + if (Properties::stretchEffectBehavior == StretchEffectBehavior::LinearScale) { + const StretchEffect& stretch = props.layerProperties().getStretchEffect(); + if (!stretch.isEmpty()) { + applyMatrix(stretch.makeLinearStretch(props.getWidth(), props.getHeight()), &temp); + } + } applyMatrix(props.getTransformMatrix(), &temp); if (props.getStaticMatrix()) { applyMatrix(props.getStaticMatrix(), &temp); diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 7af0a221d228..c58c888b8a21 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -84,6 +84,8 @@ float Properties::defaultSdrWhitePoint = 200.f; bool Properties::useHintManager = true; int Properties::targetCpuTimePercentage = 70; +StretchEffectBehavior Properties::stretchEffectBehavior = StretchEffectBehavior::Shader; + bool Properties::load() { bool prevDebugLayersUpdates = debugLayersUpdates; bool prevDebugOverdraw = debugOverdraw; @@ -135,6 +137,10 @@ bool Properties::load() { targetCpuTimePercentage = base::GetIntProperty(PROPERTY_TARGET_CPU_TIME_PERCENTAGE, 70); if (targetCpuTimePercentage <= 0 || targetCpuTimePercentage > 100) targetCpuTimePercentage = 70; + int stretchType = base::GetIntProperty(PROPERTY_STRETCH_EFFECT_TYPE, 0); + stretchType = std::clamp(stretchType, 0, static_cast<int>(StretchEffectBehavior::LinearScale)); + stretchEffectBehavior = static_cast<StretchEffectBehavior>(stretchType); + return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw); } diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 01c157123c50..82ce5c6fb979 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -171,6 +171,8 @@ enum DebugLevel { */ #define PROPERTY_TARGET_CPU_TIME_PERCENTAGE "debug.hwui.target_cpu_time_percent" +#define PROPERTY_STRETCH_EFFECT_TYPE "debug.hwui.stretch_mode" + /** * Property for whether this is running in the emulator. */ @@ -197,6 +199,11 @@ enum class OverdrawColorSet { Default = 0, Deuteranomaly }; enum class RenderPipelineType { SkiaGL, SkiaVulkan, NotInitialized = 128 }; +enum class StretchEffectBehavior { + Shader, + LinearScale, +}; + /** * Renderthread-only singleton which manages several static rendering properties. Most of these * are driven by system properties which are queried once at initialization, and again if init() @@ -270,6 +277,8 @@ public: static bool useHintManager; static int targetCpuTimePercentage; + static StretchEffectBehavior stretchEffectBehavior; + private: static ProfileType sProfileType; static bool sDisableProfileBars; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index fce2e1fa9970..64abd9428528 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -477,6 +477,14 @@ void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) } } } + + if (Properties::stretchEffectBehavior == StretchEffectBehavior::LinearScale) { + const StretchEffect& stretch = properties().layerProperties().getStretchEffect(); + if (!stretch.isEmpty()) { + matrix.multiply( + stretch.makeLinearStretch(properties().getWidth(), properties().getHeight())); + } + } } const SkPath* RenderNode::getClippedOutline(const SkRect& clipRect) const { diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h index 6d517aca9c85..c49d53af94eb 100644 --- a/libs/hwui/effects/StretchEffect.h +++ b/libs/hwui/effects/StretchEffect.h @@ -20,6 +20,7 @@ #include <SkImage.h> #include <SkImageFilter.h> +#include <SkMatrix.h> #include <SkPoint.h> #include <SkRect.h> #include <SkRuntimeEffect.h> @@ -99,6 +100,14 @@ public: const SkVector getStretchDirection() const { return mStretchDirection; } + SkMatrix makeLinearStretch(float width, float height) const { + SkMatrix matrix; + auto [sX, sY] = getStretchDirection(); + matrix.setScale(1 + std::abs(sX), 1 + std::abs(sY), sX > 0 ? 0 : width, + sY > 0 ? 0 : height); + return matrix; + } + private: static sk_sp<SkRuntimeEffect> getStretchEffect(); mutable SkVector mStretchDirection{0, 0}; diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp index f92c32c12c61..6123c05fb22a 100644 --- a/libs/hwui/jni/android_graphics_RenderNode.cpp +++ b/libs/hwui/jni/android_graphics_RenderNode.cpp @@ -573,7 +573,8 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, const RenderProperties& props = node.properties(); uirenderer::Rect bounds(props.getWidth(), props.getHeight()); - if (info.stretchEffectCount) { + if (Properties::stretchEffectBehavior == StretchEffectBehavior::Shader && + info.stretchEffectCount) { handleStretchEffect(info, bounds); } diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp index 1ae06d082744..509884e23c26 100644 --- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp +++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp @@ -171,11 +171,16 @@ void RenderNodeDrawable::forceDraw(SkCanvas* canvas) const { displayList->mProjectedOutline = nullptr; } +static bool stretchNeedsLayer(const LayerProperties& properties) { + return Properties::stretchEffectBehavior == StretchEffectBehavior::Shader && + !properties.getStretchEffect().isEmpty(); +} + static bool layerNeedsPaint(const sk_sp<SkImage>& snapshotImage, const LayerProperties& properties, float alphaMultiplier, SkPaint* paint) { if (alphaMultiplier < 1.0f || properties.alpha() < 255 || properties.xferMode() != SkBlendMode::kSrcOver || properties.getColorFilter() != nullptr || - properties.getImageFilter() != nullptr || !properties.getStretchEffect().isEmpty()) { + properties.getImageFilter() != nullptr || stretchNeedsLayer(properties)) { paint->setAlpha(properties.alpha() * alphaMultiplier); paint->setBlendMode(properties.xferMode()); paint->setColorFilter(sk_ref_sp(properties.getColorFilter())); @@ -247,7 +252,8 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const { } const StretchEffect& stretch = properties.layerProperties().getStretchEffect(); - if (stretch.isEmpty()) { + if (stretch.isEmpty() || + Properties::stretchEffectBehavior != StretchEffectBehavior::Shader) { // If we don't have any stretch effects, issue the filtered // canvas draw calls to make sure we still punch a hole // with the same canvas transformation + clip into the target @@ -326,6 +332,13 @@ void RenderNodeDrawable::setViewProperties(const RenderProperties& properties, S canvas->concat(*properties.getTransformMatrix()); } } + if (Properties::stretchEffectBehavior == StretchEffectBehavior::LinearScale) { + const StretchEffect& stretch = properties.layerProperties().getStretchEffect(); + if (!stretch.isEmpty()) { + canvas->concat( + stretch.makeLinearStretch(properties.getWidth(), properties.getHeight())); + } + } const bool isLayer = properties.effectiveLayerType() != LayerType::None; int clipFlags = properties.getClippingFlags(); if (properties.getAlpha() < 1) { |