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:
Nader Jawad
2021-04-07 16:05:13 -07:00
parent 41a5cb8946
commit 8f5d66b748
3 changed files with 20 additions and 26 deletions

View File

@@ -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() {

View File

@@ -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

View File

@@ -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;