Do not use SkImageFilter for Stretch
Refactor stretch implementation to manually draw the shader as a rect instead of using SkImageFilter Bug: 184184033 Test: Re-ran stretch tests Change-Id: I6263f5474b185b3f81ef9fd1bec3e43e86da49f2
This commit is contained in:
@@ -171,13 +171,13 @@ static const SkString stretchShader = SkString(R"(
|
||||
static const float ZERO = 0.f;
|
||||
static const float CONTENT_DISTANCE_STRETCHED = 1.f;
|
||||
|
||||
sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapshotImage) const {
|
||||
sk_sp<SkShader> StretchEffect::getShader(const sk_sp<SkImage>& snapshotImage) const {
|
||||
if (isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mStretchFilter != nullptr) {
|
||||
return mStretchFilter;
|
||||
if (mStretchShader != nullptr) {
|
||||
return mStretchShader;
|
||||
}
|
||||
|
||||
float viewportWidth = stretchArea.width();
|
||||
@@ -212,10 +212,9 @@ sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapsho
|
||||
mBuilder->uniform("viewportWidth").set(&viewportWidth, 1);
|
||||
mBuilder->uniform("viewportHeight").set(&viewportHeight, 1);
|
||||
|
||||
mStretchFilter = SkImageFilters::Shader(mBuilder->makeShader(nullptr, false),
|
||||
SkRect{0, 0, viewportWidth, viewportHeight});
|
||||
mStretchShader = mBuilder->makeShader(nullptr, false);
|
||||
|
||||
return mStretchFilter;
|
||||
return mStretchShader;
|
||||
}
|
||||
|
||||
sk_sp<SkRuntimeEffect> StretchEffect::getStretchEffect() {
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
StretchEffect& operator=(const StretchEffect& other) {
|
||||
this->stretchArea = other.stretchArea;
|
||||
this->mStretchDirection = other.mStretchDirection;
|
||||
this->mStretchFilter = nullptr;
|
||||
this->mStretchShader = other.mStretchShader;
|
||||
this->maxStretchAmountX = other.maxStretchAmountX;
|
||||
this->maxStretchAmountY = other.maxStretchAmountY;
|
||||
return *this;
|
||||
@@ -76,14 +76,14 @@ public:
|
||||
maxStretchAmountY = std::max(maxStretchAmountY, other.maxStretchAmountY);
|
||||
}
|
||||
|
||||
sk_sp<SkImageFilter> getImageFilter(const sk_sp<SkImage>& snapshotImage) const;
|
||||
sk_sp<SkShader> getShader(const sk_sp<SkImage>& snapshotImage) const;
|
||||
|
||||
SkRect stretchArea {0, 0, 0, 0};
|
||||
float maxStretchAmountX = 0;
|
||||
float maxStretchAmountY = 0;
|
||||
|
||||
void setStretchDirection(const SkVector& direction) {
|
||||
mStretchFilter = nullptr;
|
||||
mStretchShader = nullptr;
|
||||
mStretchDirection = direction;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ private:
|
||||
static sk_sp<SkRuntimeEffect> getStretchEffect();
|
||||
mutable SkVector mStretchDirection{0, 0};
|
||||
mutable std::unique_ptr<SkRuntimeShaderBuilder> mBuilder;
|
||||
mutable sk_sp<SkImageFilter> mStretchFilter;
|
||||
mutable sk_sp<SkShader> mStretchShader;
|
||||
};
|
||||
|
||||
} // namespace android::uirenderer
|
||||
|
||||
@@ -180,20 +180,7 @@ static bool layerNeedsPaint(const sk_sp<SkImage>& snapshotImage, const LayerProp
|
||||
paint->setColorFilter(sk_ref_sp(properties.getColorFilter()));
|
||||
|
||||
sk_sp<SkImageFilter> imageFilter = sk_ref_sp(properties.getImageFilter());
|
||||
sk_sp<SkImageFilter> stretchFilter =
|
||||
properties.getStretchEffect().getImageFilter(snapshotImage);
|
||||
sk_sp<SkImageFilter> filter;
|
||||
if (imageFilter && stretchFilter) {
|
||||
filter = SkImageFilters::Compose(
|
||||
std::move(stretchFilter),
|
||||
std::move(imageFilter)
|
||||
);
|
||||
} else if (stretchFilter) {
|
||||
filter = std::move(stretchFilter);
|
||||
} else {
|
||||
filter = std::move(imageFilter);
|
||||
}
|
||||
paint->setImageFilter(std::move(filter));
|
||||
paint->setImageFilter(std::move(imageFilter));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -262,8 +249,16 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const {
|
||||
TransformCanvas transformCanvas(canvas);
|
||||
displayList->draw(&transformCanvas);
|
||||
}
|
||||
canvas->drawImageRect(snapshotImage, bounds, bounds, sampling, &paint,
|
||||
SkCanvas::kStrict_SrcRectConstraint);
|
||||
|
||||
const StretchEffect& stretch = properties.layerProperties().getStretchEffect();
|
||||
if (stretch.isEmpty()) {
|
||||
canvas->drawImageRect(snapshotImage, bounds, bounds, sampling, &paint,
|
||||
SkCanvas::kStrict_SrcRectConstraint);
|
||||
} else {
|
||||
sk_sp<SkShader> stretchShader = stretch.getShader(snapshotImage);
|
||||
paint.setShader(stretchShader);
|
||||
canvas->drawRect(bounds, paint);
|
||||
}
|
||||
|
||||
if (!renderNode->getSkiaLayer()->hasRenderedSinceRepaint) {
|
||||
renderNode->getSkiaLayer()->hasRenderedSinceRepaint = true;
|
||||
|
||||
Reference in New Issue
Block a user