Add a linear variant of the stretch effect
Supports SurfaceViews & everything Test: setprop debug.hwui.stretch_mode 1 Bug: 187718492 Change-Id: I9a222fa4c1a40e80a74cdaf75becb9524cbeed9b
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user