summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nader Jawad <njawad@google.com> 2021-05-10 22:12:48 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-05-10 22:12:48 +0000
commit020efbc1a8feda5670f1b7b7cd75e79dcacbaa94 (patch)
tree47343aebfbb96daff0bb9bf62ba458410d49ec12
parentd825a07bc472f206a0066d6a11a32ac6deebe1f7 (diff)
parent8ed00dc56d5af7483ed053eb88c550cc1035b029 (diff)
Merge "Add a linear variant of the stretch effect" into sc-dev
-rw-r--r--libs/hwui/DamageAccumulator.cpp10
-rw-r--r--libs/hwui/Properties.cpp6
-rw-r--r--libs/hwui/Properties.h9
-rw-r--r--libs/hwui/RenderNode.cpp8
-rw-r--r--libs/hwui/effects/StretchEffect.h9
-rw-r--r--libs/hwui/jni/android_graphics_RenderNode.cpp3
-rw-r--r--libs/hwui/pipeline/skia/RenderNodeDrawable.cpp17
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) {