Revert "Add 2x2 bilinear downscale steps to GrSurfaceContext::rescale."
This reverts commit 9c6f6bf031b4bc0c40358eca2de43911fe13bbfb.
Reason for revert: likely hurt flutter perf
https://github.com/flutter/flutter/issues/58716
Original change's description:
> Add 2x2 bilinear downscale steps to GrSurfaceContext::rescale.
>
> Currently just uses 2x2 configuration but could be adapted easily
> to support other sample position layouts.
>
> Change-Id: If857bac5d1fab1b6ee04694e445d0f19431646f1
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/292079
> Commit-Queue: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Michael Ludwig <michaelludwig@google.com>
TBR=bsalomon@google.com,michaelludwig@google.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Change-Id: I8c322c02e22622ab61b99e4a8c241b30a2a31b12
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/294399
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index efc76cb..b7c667f 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -7,7 +7,6 @@
#include "src/gpu/GrSurfaceContext.h"
-#include "include/effects/SkRuntimeEffect.h"
#include "include/private/GrRecordingContext.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/gpu/GrAuditTrail.h"
@@ -23,7 +22,6 @@
#include "src/gpu/GrSurfacePriv.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/GrBicubicEffect.h"
-#include "src/gpu/effects/GrSkSLFP.h"
#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(this->singleOwner())
#define RETURN_FALSE_IF_ABANDONED if (this->fContext->priv().abandoned()) { return false; }
@@ -501,61 +499,6 @@
this->readSurfaceView(), dstPoint);
}
-template <int N> static std::unique_ptr<GrSkSLFP> make_avg_effect(GrRecordingContext* context) {
- static sk_sp<SkRuntimeEffect> gEffect;
- static SkString gName;
- if (!gEffect) {
- SkString string;
- for (int i = 0; i < N; ++i) {
- string.appendf("in fragmentProcessor child%d;\n", i);
- }
- string.append("void main(float2 p, inout half4 color) {\n");
- for (int i = 0; i < N; ++i) {
- string.appendf(" color %c= sample(child%d, p);\n", i ? '+' : ' ', i);
- }
- string.appendf(" color /= half(%d);\n"
- "}\n", N);
- gEffect = std::get<0>(SkRuntimeEffect::Make(std::move(string)));
- SkASSERT(gEffect);
- gName.printf("Avg%d", N);
- }
- return GrSkSLFP::Make(context, gEffect, gName.c_str(), nullptr);
-}
-
-template <int NX, int NY>
-static std::unique_ptr<GrFragmentProcessor> make_multibilerp_effect(GrRecordingContext* context,
- GrSurfaceProxyView srcView,
- SkAlphaType alphaType,
- const SkIRect& srcRect,
- const SkISize& dstSize) {
- auto effect = make_avg_effect<NX*NY>(context);
-
- // scale factors.
- float sx = static_cast<float>(srcRect.width()) /dstSize.width(),
- sy = static_cast<float>(srcRect.height())/dstSize.height();
- // spacing between bilerp samples.
- float dx = sx/NX,
- dy = sy/NY;
- // offset in src from back projection of dst pixel center to left/upper-most bilerp sample.
- float x0 = (dx - sx)/2,
- y0 = (dy - sy)/2;
-
- const auto& caps = *context->priv().caps();
- for (int j = 0; j < NY; ++j) {
- for (int i = 0; i < NX; ++i) {
- float tx = x0 + i*dx,
- ty = y0 + j*dy;
- SkMatrix m = SkMatrix::Scale(sx, sy);
- m.postTranslate(tx + srcRect.x(), ty + srcRect.y());
- SkRect domain = SkRect::Make(srcRect).makeInset(sx/2, sy/2).makeOffset(tx, ty);
- effect->addChild(GrTextureEffect::MakeSubset(srcView, alphaType, m,
- GrSamplerState::Filter::kBilerp,
- SkRect::Make(srcRect), domain, caps));
- }
- }
- return std::move(effect);
-}
-
std::unique_ptr<GrRenderTargetContext> GrSurfaceContext::rescale(
const GrImageInfo& info,
GrSurfaceOrigin origin,
@@ -619,42 +562,22 @@
srcRect = SkIRect::MakeSize(srcRect.size());
}
- enum StepType {
- kNearest,
- kBilinear,
- kFourTapBilinear,
- kBicubic,
- };
- auto determineNextStep = [rescaleQuality, finalSize = info.dimensions()](SkISize srcSize) {
- if (rescaleQuality == kNone_SkFilterQuality) {
- return std::make_tuple(StepType::kNearest, finalSize);
- }
- SkISize nextSize;
- if (srcSize.width() > finalSize.width()) {
- nextSize.fWidth = std::max((srcSize.width() + 1)/2, finalSize.width());
- } else {
- nextSize.fWidth = std::min(srcSize.width()*2, finalSize.width());
- }
- if (srcSize.height() > finalSize.height()) {
- nextSize.fHeight = std::max((srcSize.height() + 1)/2, finalSize.height());
- } else {
- nextSize.fHeight = std::min(srcSize.height()*2, finalSize.height());
- }
- if (rescaleQuality == kHigh_SkFilterQuality) {
- return std::make_tuple(StepType::kBicubic, nextSize);
- }
- // See if we can do multiple bilinear steps in one.
- if (nextSize.width() > finalSize.width() && nextSize.height() > finalSize.height()) {
- nextSize = {std::max((nextSize.width() + 1)/2, finalSize.width()),
- std::max((nextSize.height() + 1)/2, finalSize.height())};
- return std::make_tuple(StepType::kFourTapBilinear, nextSize);
- }
- return std::make_tuple(StepType::kBilinear, nextSize);
- };
while (srcRect.size() != info.dimensions()) {
- auto [stepType, nextDims] = determineNextStep(srcRect.size());
+ SkISize nextDims = info.dimensions();
+ if (rescaleQuality != kNone_SkFilterQuality) {
+ if (srcRect.width() > info.width()) {
+ nextDims.fWidth = std::max((srcRect.width() + 1)/2, info.width());
+ } else if (srcRect.width() < info.width()) {
+ nextDims.fWidth = std::min(srcRect.width()*2, info.width());
+ }
+ if (srcRect.height() > info.height()) {
+ nextDims.fHeight = std::max((srcRect.height() + 1)/2, info.height());
+ } else if (srcRect.height() < info.height()) {
+ nextDims.fHeight = std::min(srcRect.height()*2, info.height());
+ }
+ }
auto input = tempA ? tempA.get() : this;
- auto colorType = input->colorInfo().colorType();
+ GrColorType colorType = input->colorInfo().colorType();
auto cs = input->colorInfo().refColorSpace();
sk_sp<GrColorSpaceXform> xform;
auto prevAlphaType = input->colorInfo().alphaType();
@@ -671,49 +594,43 @@
if (!tempB) {
return nullptr;
}
- std::unique_ptr<GrFragmentProcessor> srcFP;
- switch (stepType) {
- case StepType::kBicubic: {
- SkMatrix matrix;
- matrix.setScaleTranslate((float)srcRect.width() /nextDims.width(),
- (float)srcRect.height()/nextDims.height(),
- srcRect.x(),
- srcRect.y());
- auto dir = GrBicubicEffect::Direction::kXY;
- if (nextDims.width() == srcRect.width()) {
- dir = GrBicubicEffect::Direction::kY;
- } else if (nextDims.height() == srcRect.height()) {
- dir = GrBicubicEffect::Direction::kX;
- }
- static constexpr GrSamplerState::WrapMode kWM = GrSamplerState::WrapMode::kClamp;
- srcFP = GrBicubicEffect::MakeSubset(std::move(texView), prevAlphaType, matrix, kWM,
- kWM, SkRect::Make(srcRect), dir, *this->caps());
- break;
+ auto dstRect = SkRect::Make(nextDims);
+ if (rescaleQuality == kHigh_SkFilterQuality) {
+ SkMatrix matrix;
+ matrix.setScaleTranslate((float)srcRect.width()/nextDims.width(),
+ (float)srcRect.height()/nextDims.height(),
+ srcRect.x(),
+ srcRect.y());
+ std::unique_ptr<GrFragmentProcessor> fp;
+ auto dir = GrBicubicEffect::Direction::kXY;
+ if (nextDims.width() == srcRect.width()) {
+ dir = GrBicubicEffect::Direction::kY;
+ } else if (nextDims.height() == srcRect.height()) {
+ dir = GrBicubicEffect::Direction::kX;
}
- case StepType::kFourTapBilinear:
- srcFP = make_multibilerp_effect<2, 2>(fContext, texView, srcAlphaType, srcRect,
- nextDims);
- break;
- default: {
- auto filter = stepType == StepType::kNearest ? GrSamplerState::Filter::kNearest
- : GrSamplerState::Filter::kBilerp;
- float sx = static_cast<float>(srcRect.width()) /nextDims.width(),
- sy = static_cast<float>(srcRect.height())/nextDims.height();
- SkMatrix matrix;
- matrix.setScaleTranslate(sx, sy, srcRect.x(), srcRect.y());
- SkRect domain = SkRect::Make(srcRect).makeInset(sx/2, sy/2);
- srcFP = GrTextureEffect::MakeSubset(std::move(texView), srcAlphaType, matrix,
- filter, SkRect::Make(srcRect), domain,
- *this->caps());
- break;
+ static constexpr GrSamplerState::WrapMode kWM = GrSamplerState::WrapMode::kClamp;
+ fp = GrBicubicEffect::MakeSubset(std::move(texView), prevAlphaType, matrix, kWM, kWM,
+ SkRect::Make(srcRect), dir, *this->caps());
+ if (xform) {
+ fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(xform));
}
+ GrPaint paint;
+ paint.addColorFragmentProcessor(std::move(fp));
+ paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+ tempB->fillRectToRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect,
+ dstRect);
+ } else {
+ auto filter = rescaleQuality == kNone_SkFilterQuality ? GrSamplerState::Filter::kNearest
+ : GrSamplerState::Filter::kBilerp;
+ // Minimizing draw with integer coord src and dev rects can always be kFast.
+ auto constraint = SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint;
+ if (nextDims.width() <= srcRect.width() && nextDims.height() <= srcRect.height()) {
+ constraint = SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint;
+ }
+ tempB->drawTexture(nullptr, std::move(texView), srcAlphaType, filter, SkBlendMode::kSrc,
+ SK_PMColor4fWHITE, SkRect::Make(srcRect), dstRect, GrAA::kNo,
+ GrQuadAAFlags::kNone, constraint, SkMatrix::I(), std::move(xform));
}
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- srcFP = GrColorSpaceXformEffect::Make(std::move(srcFP), std::move(xform));
- paint.addColorFragmentProcessor(std::move(srcFP));
- tempB->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- SkRect::Make(nextDims));
texView = tempB->readSurfaceView();
tempA = std::move(tempB);
srcRect = SkIRect::MakeSize(nextDims);
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index 407d61a..a2e9b46 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -164,9 +164,6 @@
std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext_Base* context, sk_sp<SkRuntimeEffect> effect,
const char* name, sk_sp<SkData> inputs) {
- if (!inputs) {
- inputs = SkData::MakeEmpty();
- }
if (inputs->size() != effect->inputSize()) {
return nullptr;
}