aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/texdata.cpp3
-rw-r--r--gm/texturedomaineffect.cpp30
-rw-r--r--gm/windowrectangles.cpp10
-rw-r--r--gm/yuvtorgbeffect.cpp6
-rw-r--r--gn/gpu.gni1
-rw-r--r--include/gpu/GrContext.h8
-rw-r--r--src/core/SkGpuBlurUtils.cpp4
-rw-r--r--src/gpu/GrBlurUtils.cpp17
-rw-r--r--src/gpu/GrSurfaceProxyPriv.h3
-rw-r--r--src/gpu/effects/Gr1DKernelEffect.h20
-rw-r--r--src/gpu/effects/GrBicubicEffect.cpp34
-rw-r--r--src/gpu/effects/GrBicubicEffect.h29
-rw-r--r--src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp61
-rw-r--r--src/gpu/effects/GrGaussianConvolutionFragmentProcessor.h19
-rw-r--r--src/gpu/effects/GrMatrixConvolutionEffect.cpp113
-rw-r--r--src/gpu/effects/GrMatrixConvolutionEffect.h38
-rw-r--r--src/gpu/effects/GrProxyMove.h34
-rw-r--r--src/gpu/effects/GrSimpleTextureEffect.cpp40
-rw-r--r--src/gpu/effects/GrSimpleTextureEffect.h83
-rw-r--r--src/gpu/effects/GrTextureDomain.cpp151
-rw-r--r--src/gpu/effects/GrTextureDomain.h29
21 files changed, 546 insertions, 187 deletions
diff --git a/gm/texdata.cpp b/gm/texdata.cpp
index 70afd22ec5..6b229a3db3 100644
--- a/gm/texdata.cpp
+++ b/gm/texdata.cpp
@@ -16,6 +16,7 @@
#include "GrTextureContext.h"
#include "GrFixedClip.h"
#include "SkColorPriv.h"
+#include "SkGr.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "effects/GrSimpleTextureEffect.h"
@@ -86,9 +87,9 @@ DEF_SIMPLE_GM_BG(texdata, canvas, 2 * S, 2 * S, SK_ColorBLACK) {
GrSurfaceDesc desc;
desc.fOrigin = i ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
- desc.fConfig = kBGRA_8888_GrPixelConfig;
desc.fWidth = 2 * S;
desc.fHeight = 2 * S;
+ desc.fConfig = SkImageInfo2GrPixelConfig(ii, *context->caps());
sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(*context->caps(),
context->textureProvider(),
diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp
index 0bebd8c97d..d5d98d556a 100644
--- a/gm/texturedomaineffect.cpp
+++ b/gm/texturedomaineffect.cpp
@@ -43,7 +43,10 @@ protected:
}
void onOnceBeforeDraw() override {
- fBmp.allocN32Pixels(kTargetWidth, kTargetHeight);
+ // TODO: do this with surfaces & images and gpu backend
+ SkImageInfo ii = SkImageInfo::Make(kTargetWidth, kTargetHeight, kN32_SkColorType,
+ kPremul_SkAlphaType);
+ fBmp.allocPixels(ii);
SkCanvas canvas(fBmp);
canvas.clear(0x00000000);
SkPaint paint;
@@ -82,9 +85,17 @@ protected:
return;
}
- sk_sp<GrTexture> texture(
- GrRefCachedBitmapTexture(context, fBmp, GrSamplerParams::ClampNoFilter(), nullptr));
- if (!texture) {
+ GrSurfaceDesc desc;
+ desc.fWidth = fBmp.width();
+ desc.fHeight = fBmp.height();
+ desc.fConfig = SkImageInfo2GrPixelConfig(fBmp.info(), *context->caps());
+
+ sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeDeferred(*context->caps(),
+ context->textureProvider(),
+ desc, SkBudgeted::kYes,
+ fBmp.getPixels(),
+ fBmp.rowBytes()));
+ if (!proxy || !proxy->asTextureProxy()) {
return;
}
@@ -92,14 +103,12 @@ protected:
textureMatrices.push_back() = SkMatrix::I();
textureMatrices.push_back() = SkMatrix::MakeScale(1.5f, 0.85f);
textureMatrices.push_back();
- textureMatrices.back().setRotate(45.f, texture->width() / 2.f, texture->height() / 2.f);
+ textureMatrices.back().setRotate(45.f, proxy->width() / 2.f, proxy->height() / 2.f);
const SkIRect texelDomains[] = {
fBmp.bounds(),
- SkIRect::MakeXYWH(fBmp.width() / 4,
- fBmp.height() / 4,
- fBmp.width() / 2,
- fBmp.height() / 2),
+ SkIRect::MakeXYWH(fBmp.width() / 4, fBmp.height() / 4,
+ fBmp.width() / 2, fBmp.height() / 2),
};
SkRect renderRect = SkRect::Make(fBmp.bounds());
@@ -115,7 +124,8 @@ protected:
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
sk_sp<GrFragmentProcessor> fp(
GrTextureDomainEffect::Make(
- texture.get(), nullptr, textureMatrices[tm],
+ context, sk_ref_sp(proxy->asTextureProxy()),
+ nullptr, textureMatrices[tm],
GrTextureDomain::MakeTexelDomainForMode(texelDomains[d], mode),
mode, GrSamplerParams::kNone_FilterMode));
diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp
index 29356fc72a..c335c985ad 100644
--- a/gm/windowrectangles.cpp
+++ b/gm/windowrectangles.cpp
@@ -153,9 +153,10 @@ private:
*/
class AlphaOnlyClip final : public MaskOnlyClipBase {
public:
- AlphaOnlyClip(GrTexture* mask, int x, int y) {
+ AlphaOnlyClip(GrContext* context, sk_sp<GrTextureProxy> mask, int x, int y) {
int w = mask->width(), h = mask->height();
- fFP = GrDeviceSpaceTextureDecalFragmentProcessor::Make(mask, SkIRect::MakeWH(w, h), {x, y});
+ fFP = GrDeviceSpaceTextureDecalFragmentProcessor::Make(context, std::move(mask),
+ SkIRect::MakeWH(w, h), {x, y});
}
private:
bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out) const override {
@@ -216,7 +217,6 @@ void WindowRectanglesMaskGM::visualizeAlphaMask(GrContext* ctx, GrRenderTargetCo
SkRegion::kDifference_Op, false, GrAA::kNo, SkMatrix::I(),
SkRect::MakeIWH(maskRTC->width(), maskRTC->height()));
reducedClip.drawAlphaClipMask(maskRTC.get());
- sk_sp<GrTexture> mask(maskRTC->asTexture());
int x = kCoverRect.x() - kLayerRect.x(),
y = kCoverRect.y() - kLayerRect.y();
@@ -224,9 +224,9 @@ void WindowRectanglesMaskGM::visualizeAlphaMask(GrContext* ctx, GrRenderTargetCo
// Now visualize the alpha mask by drawing a rect over the area where it is defined. The regions
// inside window rectangles or outside the scissor should still have the initial checkerboard
// intact. (This verifies we didn't spend any time modifying those pixels in the mask.)
- AlphaOnlyClip clip(mask.get(), x, y);
+ AlphaOnlyClip clip(ctx, sk_ref_sp(maskRTC->asDeferredTexture()), x, y);
rtc->drawRect(clip, std::move(paint), GrAA::kYes, SkMatrix::I(),
- SkRect::Make(SkIRect::MakeXYWH(x, y, mask->width(), mask->height())));
+ SkRect::Make(SkIRect::MakeXYWH(x, y, maskRTC->width(), maskRTC->height())));
}
void WindowRectanglesMaskGM::visualizeStencilMask(GrContext* ctx, GrRenderTargetContext* rtc,
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index fa82f9090b..1835fe3446 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -86,11 +86,11 @@ protected:
{
GrSurfaceDesc desc;
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
- desc.fConfig = kAlpha_8_GrPixelConfig;
for (int i = 0; i < 3; ++i) {
desc.fWidth = fBmp[i].width();
desc.fHeight = fBmp[i].height();
+ desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[i].info(), *context->caps());
proxy[i] = GrSurfaceProxy::MakeDeferred(*context->caps(),
context->textureProvider(),
@@ -221,11 +221,9 @@ protected:
for (int i = 0; i < 3; ++i) {
int index = (0 == i) ? 0 : 1;
- desc.fConfig = kAlpha_8_SkColorType == fBmp[index].colorType()
- ? kAlpha_8_GrPixelConfig
- : kBGRA_8888_GrPixelConfig;
desc.fWidth = fBmp[index].width();
desc.fHeight = fBmp[index].height();
+ desc.fConfig = SkImageInfo2GrPixelConfig(fBmp[index].info(), *context->caps());
proxy[i] = GrSurfaceProxy::MakeDeferred(*context->caps(),
context->textureProvider(),
diff --git a/gn/gpu.gni b/gn/gpu.gni
index a53daeb705..b3ed69481e 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -324,6 +324,7 @@ skia_gpu_sources = [
"$_src/gpu/effects/GrOvalEffect.cpp",
"$_src/gpu/effects/GrOvalEffect.h",
"$_src/gpu/effects/GrPorterDuffXferProcessor.cpp",
+ "$_src/gpu/effects/GrProxyMove.h",
"$_src/gpu/effects/GrRRectEffect.cpp",
"$_src/gpu/effects/GrRRectEffect.h",
"$_src/gpu/effects/GrShadowGeoProc.cpp",
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 4fe3e72b5f..f7bfd9a2e5 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -189,7 +189,7 @@ public:
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt = 0,
- GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin,
+ GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted = SkBudgeted::kYes);
@@ -201,7 +201,7 @@ public:
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt = 0,
- GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin,
+ GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted = SkBudgeted::kYes);
/*
@@ -216,7 +216,7 @@ public:
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt = 0,
- GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin,
+ GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted budgeted = SkBudgeted::kYes);
@@ -228,7 +228,7 @@ public:
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt = 0,
- GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin,
+ GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted budgeted = SkBudgeted::kYes);
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index ec9376501a..d7522ca726 100644
--- a/src/core/SkGpuBlurUtils.cpp
+++ b/src/core/SkGpuBlurUtils.cpp
@@ -231,7 +231,7 @@ sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context,
const GrPixelConfig config = srcTexture->config();
sk_sp<GrRenderTargetContext> dstRenderTargetContext(context->makeDeferredRenderTargetContext(
- fit, width, height, config, colorSpace, 0, kDefault_GrSurfaceOrigin));
+ fit, width, height, config, colorSpace, 0, kBottomLeft_GrSurfaceOrigin));
if (!dstRenderTargetContext) {
return nullptr;
}
@@ -250,7 +250,7 @@ sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context,
}
sk_sp<GrRenderTargetContext> tmpRenderTargetContext(context->makeDeferredRenderTargetContext(
- fit, width, height, config, colorSpace, 0, kDefault_GrSurfaceOrigin));
+ fit, width, height, config, colorSpace, 0, kBottomLeft_GrSurfaceOrigin));
if (!tmpRenderTargetContext) {
return nullptr;
}
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index 7a8a252cff..cec9cdc7ad 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -30,18 +30,13 @@ static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& r
// Draw a mask using the supplied paint. Since the coverage/geometry
// is already burnt into the mask this boils down to a rect draw.
// Return true if the mask was successfully drawn.
-static bool draw_mask(GrRenderTargetContext* renderTargetContext,
- GrTextureProvider* textureProvider,
+static bool draw_mask(GrContext* context,
+ GrRenderTargetContext* renderTargetContext,
const GrClip& clip,
const SkMatrix& viewMatrix,
const SkIRect& maskRect,
GrPaint&& paint,
sk_sp<GrTextureProxy> mask) {
- // TODO: defer this instantiation
- GrTexture* maskTex = mask->instantiate(textureProvider);
- if (!maskTex) {
- return false;
- }
SkMatrix inverse;
if (!viewMatrix.invert(&inverse)) {
return false;
@@ -50,7 +45,8 @@ static bool draw_mask(GrRenderTargetContext* renderTargetContext,
SkMatrix matrix = SkMatrix::MakeTrans(-SkIntToScalar(maskRect.fLeft),
-SkIntToScalar(maskRect.fTop));
matrix.preConcat(viewMatrix);
- paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(maskTex, nullptr, matrix));
+ paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(context, std::move(mask),
+ nullptr, matrix));
renderTargetContext->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
SkRect::Make(maskRect), inverse);
@@ -86,6 +82,7 @@ static bool sw_draw_with_mask_filter(GrContext* context,
// we now have a device-aligned 8bit mask in dstM, ready to be drawn using
// the current clip (and identity matrix) and GrPaint settings
GrSurfaceDesc desc;
+ desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fWidth = dstM.fBounds.width();
desc.fHeight = dstM.fBounds.height();
desc.fConfig = kAlpha_8_GrPixelConfig;
@@ -103,7 +100,7 @@ static bool sw_draw_with_mask_filter(GrContext* context,
return false;
}
- return draw_mask(renderTargetContext, context->textureProvider(), clipData, viewMatrix,
+ return draw_mask(context, renderTargetContext, clipData, viewMatrix,
dstM.fBounds, std::move(paint), sk_ref_sp(sContext->asDeferredTexture()));
}
@@ -234,7 +231,7 @@ static void draw_path_with_mask_filter(GrContext* context,
viewMatrix,
finalIRect);
if (filtered) {
- if (draw_mask(renderTargetContext, context->textureProvider(), clip, viewMatrix,
+ if (draw_mask(context, renderTargetContext, clip, viewMatrix,
finalIRect, std::move(paint), std::move(filtered))) {
// This path is completely drawn
return;
diff --git a/src/gpu/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h
index 19b81712e1..4e43daea9d 100644
--- a/src/gpu/GrSurfaceProxyPriv.h
+++ b/src/gpu/GrSurfaceProxyPriv.h
@@ -20,6 +20,9 @@ public:
// future when the proxy is actually used/instantiated.
bool hasPendingIO() const { return fProxy->hasPendingIO(); }
+ // Don't abuse this!!!!!!!
+ bool isExact() const { return SkBackingFit::kExact == fProxy->fFit; }
+
private:
explicit GrSurfaceProxyPriv(GrSurfaceProxy* proxy) : fProxy(proxy) {}
GrSurfaceProxyPriv(const GrSurfaceProxyPriv&) {} // unimpl
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h
index 67cc771c61..24c94fcce2 100644
--- a/src/gpu/effects/Gr1DKernelEffect.h
+++ b/src/gpu/effects/Gr1DKernelEffect.h
@@ -28,13 +28,23 @@ public:
kY_Direction,
};
- Gr1DKernelEffect(GrTexture* texture, Direction direction, int radius,
+ Gr1DKernelEffect(GrTexture* texture,
+ Direction direction,
+ int radius,
OptimizationFlags optFlags)
- : INHERITED(texture, nullptr, SkMatrix::I(), optFlags)
- , fDirection(direction)
- , fRadius(radius) {}
+ : INHERITED(texture, nullptr, SkMatrix::I(), optFlags)
+ , fDirection(direction)
+ , fRadius(radius) {
+ }
+
+ Gr1DKernelEffect(GrContext* ctx, OptimizationFlags optFlags, sk_sp<GrTextureProxy> proxy,
+ Direction direction, int radius)
+ : INHERITED(ctx, optFlags, std::move(proxy), nullptr, SkMatrix::I())
+ , fDirection(direction)
+ , fRadius(radius) {
+ }
- virtual ~Gr1DKernelEffect() {}
+ ~Gr1DKernelEffect() override {}
static int WidthFromRadius(int radius) { return 2 * radius + 1; }
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index cf3d2b5e79..cb589959a2 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -7,6 +7,7 @@
#include "GrBicubicEffect.h"
#include "GrInvariantOutput.h"
+#include "GrProxyMove.h"
#include "glsl/GrGLSLColorSpaceXformHelper.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
@@ -152,6 +153,31 @@ GrBicubicEffect::GrBicubicEffect(GrTexture* texture,
this->initClassID<GrBicubicEffect>();
}
+GrBicubicEffect::GrBicubicEffect(GrContext* context, sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix &matrix,
+ const SkShader::TileMode tileModes[2])
+ : INHERITED{context,
+ ModulationFlags(proxy->config()),
+ GR_PROXY_MOVE(proxy),
+ std::move(colorSpaceXform),
+ matrix,
+ GrSamplerParams(tileModes, GrSamplerParams::kNone_FilterMode)}
+ , fDomain(GrTextureDomain::IgnoredDomain()) {
+ this->initClassID<GrBicubicEffect>();
+}
+
+GrBicubicEffect::GrBicubicEffect(GrContext* context, sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix &matrix,
+ const SkRect& domain)
+ : INHERITED(context, ModulationFlags(proxy->config()), proxy,
+ std::move(colorSpaceXform), matrix,
+ GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode))
+ , fDomain(proxy.get(), domain, GrTextureDomain::kClamp_Mode) {
+ this->initClassID<GrBicubicEffect>();
+}
+
GrBicubicEffect::~GrBicubicEffect() {
}
@@ -177,12 +203,12 @@ void GrBicubicEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrBicubicEffect);
sk_sp<GrFragmentProcessor> GrBicubicEffect::TestCreate(GrProcessorTestData* d) {
- int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
- GrProcessorUnitTest::kAlphaTextureIdx;
- auto colorSpaceXform = GrTest::TestColorXform(d->fRandom);
+ int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
+ : GrProcessorUnitTest::kAlphaTextureIdx;
+ sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(d->fRandom);
static const SkShader::TileMode kClampClamp[] =
{ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode };
- return GrBicubicEffect::Make(d->fTextures[texIdx], colorSpaceXform,
+ return GrBicubicEffect::Make(d->context(), d->textureProxy(texIdx), std::move(colorSpaceXform),
SkMatrix::I(), kClampClamp);
}
diff --git a/src/gpu/effects/GrBicubicEffect.h b/src/gpu/effects/GrBicubicEffect.h
index d0f5f41a90..a51aad8cab 100644
--- a/src/gpu/effects/GrBicubicEffect.h
+++ b/src/gpu/effects/GrBicubicEffect.h
@@ -49,6 +49,30 @@ public:
}
/**
+ * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
+ */
+ static sk_sp<GrFragmentProcessor> Make(GrContext* context, sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix& matrix,
+ const SkShader::TileMode tileModes[2]) {
+ return sk_sp<GrFragmentProcessor>(new GrBicubicEffect(context, std::move(proxy),
+ std::move(colorSpaceXform),
+ matrix, tileModes));
+ }
+
+ /**
+ * Create a Mitchell filter effect with a texture matrix and a domain.
+ */
+ static sk_sp<GrFragmentProcessor> Make(GrContext* context, sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix& matrix,
+ const SkRect& domain) {
+ return sk_sp<GrFragmentProcessor>(new GrBicubicEffect(context, std::move(proxy),
+ std::move(colorSpaceXform),
+ matrix, domain));
+ }
+
+ /**
* Determines whether the bicubic effect should be used based on the transformation from the
* local coords to the device. Returns true if the bicubic effect should be used. filterMode
* is set to appropriate filtering mode to use regardless of the return result (e.g. when this
@@ -64,6 +88,11 @@ private:
GrBicubicEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix &matrix,
const SkRect& domain);
+ GrBicubicEffect(GrContext*, sk_sp<GrTextureProxy>, sk_sp<GrColorSpaceXform>,
+ const SkMatrix &matrix, const SkShader::TileMode tileModes[2]);
+ GrBicubicEffect(GrContext*, sk_sp<GrTextureProxy>, sk_sp<GrColorSpaceXform>,
+ const SkMatrix &matrix, const SkRect& domain);
+
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
index be6d4d8302..c5f554fc69 100644
--- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
+++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
@@ -6,6 +6,7 @@
*/
#include "GrGaussianConvolutionFragmentProcessor.h"
+#include "GrProxyMove.h"
#include "../private/GrGLSL.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
@@ -144,6 +145,25 @@ void GrGLConvolutionEffect::GenKey(const GrProcessor& processor, const GrShaderC
///////////////////////////////////////////////////////////////////////////////
+
+static void fill_in_1D_guassian_kernel(float* kernel, int width, float gaussianSigma, int radius) {
+ const float denom = 1.0f / (2.0f * gaussianSigma * gaussianSigma);
+
+ float sum = 0.0f;
+ for (int i = 0; i < width; ++i) {
+ float x = static_cast<float>(i - radius);
+ // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
+ // is dropped here, since we renormalize the kernel below.
+ kernel[i] = sk_float_exp(-x * x * denom);
+ sum += kernel[i];
+ }
+ // Normalize the kernel
+ float scale = 1.0f / sum;
+ for (int i = 0; i < width; ++i) {
+ kernel[i] *= scale;
+ }
+}
+
GrGaussianConvolutionFragmentProcessor::GrGaussianConvolutionFragmentProcessor(GrTexture* texture,
Direction direction,
int radius,
@@ -154,22 +174,31 @@ GrGaussianConvolutionFragmentProcessor::GrGaussianConvolutionFragmentProcessor(G
, fUseBounds(useBounds) {
this->initClassID<GrGaussianConvolutionFragmentProcessor>();
SkASSERT(radius <= kMaxKernelRadius);
- int width = this->width();
- float sum = 0.0f;
- float denom = 1.0f / (2.0f * gaussianSigma * gaussianSigma);
- for (int i = 0; i < width; ++i) {
- float x = static_cast<float>(i - this->radius());
- // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
- // is dropped here, since we renormalize the kernel below.
- fKernel[i] = sk_float_exp(-x * x * denom);
- sum += fKernel[i];
- }
- // Normalize the kernel
- float scale = 1.0f / sum;
- for (int i = 0; i < width; ++i) {
- fKernel[i] *= scale;
- }
+ fill_in_1D_guassian_kernel(fKernel, this->width(), gaussianSigma, this->radius());
+
+ memcpy(fBounds, bounds, sizeof(fBounds));
+}
+
+GrGaussianConvolutionFragmentProcessor::GrGaussianConvolutionFragmentProcessor(
+ GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ Direction direction,
+ int radius,
+ float gaussianSigma,
+ bool useBounds,
+ float bounds[2])
+ : INHERITED{context,
+ ModulationFlags(proxy->config()),
+ GR_PROXY_MOVE(proxy),
+ direction,
+ radius}
+ , fUseBounds(useBounds) {
+ this->initClassID<GrGaussianConvolutionFragmentProcessor>();
+ SkASSERT(radius <= kMaxKernelRadius);
+
+ fill_in_1D_guassian_kernel(fKernel, this->width(), gaussianSigma, this->radius());
+
memcpy(fBounds, bounds, sizeof(fBounds));
}
@@ -212,5 +241,5 @@ sk_sp<GrFragmentProcessor> GrGaussianConvolutionFragmentProcessor::TestCreate(
float sigma = radius / 3.f;
return GrGaussianConvolutionFragmentProcessor::Make(
- d->fTextures[texIdx], dir, radius, sigma, useBounds, bounds);
+ d->context(), d->textureProxy(texIdx), dir, radius, sigma, useBounds, bounds);
}
diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.h b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.h
index da40ec2b93..b4f5cb7921 100644
--- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.h
+++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.h
@@ -29,7 +29,18 @@ public:
tex, dir, halfWidth, gaussianSigma, useBounds, bounds));
}
- virtual ~GrGaussianConvolutionFragmentProcessor();
+ static sk_sp<GrFragmentProcessor> Make(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ Direction dir,
+ int halfWidth,
+ float gaussianSigma,
+ bool useBounds,
+ float* bounds) {
+ return sk_sp<GrFragmentProcessor>(new GrGaussianConvolutionFragmentProcessor(
+ context, std::move(proxy), dir, halfWidth, gaussianSigma, useBounds, bounds));
+ }
+
+ ~GrGaussianConvolutionFragmentProcessor() override;
const float* kernel() const { return fKernel; }
@@ -52,6 +63,10 @@ private:
GrGaussianConvolutionFragmentProcessor(GrTexture*, Direction, int halfWidth,
float gaussianSigma, bool useBounds, float bounds[2]);
+ GrGaussianConvolutionFragmentProcessor(GrContext*, sk_sp<GrTextureProxy>, Direction,
+ int halfWidth, float gaussianSigma, bool useBounds,
+ float bounds[2]);
+
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
@@ -69,7 +84,7 @@ private:
// TODO: Inline the kernel constants into the generated shader code. This may involve pulling
// some of the logic from SkGpuBlurUtils into this class related to radius/sigma calculations.
float fKernel[kMaxKernelWidth];
- bool fUseBounds;
+ bool fUseBounds;
float fBounds[2];
typedef Gr1DKernelEffect INHERITED;
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index 9b670e120f..86fd565877 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -172,6 +172,32 @@ GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
fKernelOffset[1] = static_cast<float>(kernelOffset.y());
}
+GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ const SkScalar* kernel,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha)
+ // To advertise either the modulation or opaqueness optimizations we'd have to examine the
+ // parameters.
+ : INHERITED(context, kNone_OptimizationFlags, proxy, nullptr, SkMatrix::I())
+ , fKernelSize(kernelSize)
+ , fGain(SkScalarToFloat(gain))
+ , fBias(SkScalarToFloat(bias) / 255.0f)
+ , fConvolveAlpha(convolveAlpha)
+ , fDomain(proxy.get(), GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode) {
+ this->initClassID<GrMatrixConvolutionEffect>();
+ for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
+ fKernel[i] = SkScalarToFloat(kernel[i]);
+ }
+ fKernelOffset[0] = static_cast<float>(kernelOffset.x());
+ fKernelOffset[1] = static_cast<float>(kernelOffset.y());
+}
+
void GrMatrixConvolutionEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {
GrGLMatrixConvolutionEffect::GenKey(*this, caps, b);
@@ -193,49 +219,75 @@ bool GrMatrixConvolutionEffect::onIsEqual(const GrFragmentProcessor& sBase) cons
fDomain == s.domain();
}
-// Static function to create a 2D convolution
-sk_sp<GrFragmentProcessor>
-GrMatrixConvolutionEffect::MakeGaussian(GrTexture* texture,
- const SkIRect& bounds,
- const SkISize& kernelSize,
- SkScalar gain,
- SkScalar bias,
- const SkIPoint& kernelOffset,
- GrTextureDomain::Mode tileMode,
- bool convolveAlpha,
- SkScalar sigmaX,
- SkScalar sigmaY) {
- float kernel[MAX_KERNEL_SIZE];
- int width = kernelSize.width();
- int height = kernelSize.height();
+static void fill_in_2D_gaussian_kernel(float* kernel, int width, int height,
+ SkScalar sigmaX, SkScalar sigmaY) {
SkASSERT(width * height <= MAX_KERNEL_SIZE);
+ const float sigmaXDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaX)));
+ const float sigmaYDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaY)));
+ const int xRadius = width / 2;
+ const int yRadius = height / 2;
+
float sum = 0.0f;
- float sigmaXDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaX)));
- float sigmaYDenom = 1.0f / (2.0f * SkScalarToFloat(SkScalarSquare(sigmaY)));
- int xRadius = width / 2;
- int yRadius = height / 2;
for (int x = 0; x < width; x++) {
- float xTerm = static_cast<float>(x - xRadius);
- xTerm = xTerm * xTerm * sigmaXDenom;
- for (int y = 0; y < height; y++) {
- float yTerm = static_cast<float>(y - yRadius);
- float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom));
- // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
- // is dropped here, since we renormalize the kernel below.
- kernel[y * width + x] = xyTerm;
- sum += xyTerm;
- }
+ float xTerm = static_cast<float>(x - xRadius);
+ xTerm = xTerm * xTerm * sigmaXDenom;
+ for (int y = 0; y < height; y++) {
+ float yTerm = static_cast<float>(y - yRadius);
+ float xyTerm = sk_float_exp(-(xTerm + yTerm * yTerm * sigmaYDenom));
+ // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian
+ // is dropped here, since we renormalize the kernel below.
+ kernel[y * width + x] = xyTerm;
+ sum += xyTerm;
+ }
}
// Normalize the kernel
float scale = 1.0f / sum;
for (int i = 0; i < width * height; ++i) {
kernel[i] *= scale;
}
+}
+
+
+// Static function to create a 2D convolution
+sk_sp<GrFragmentProcessor> GrMatrixConvolutionEffect::MakeGaussian(GrTexture* texture,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha,
+ SkScalar sigmaX,
+ SkScalar sigmaY) {
+ float kernel[MAX_KERNEL_SIZE];
+
+ fill_in_2D_gaussian_kernel(kernel, kernelSize.width(), kernelSize.height(), sigmaX, sigmaY);
+
return sk_sp<GrFragmentProcessor>(
new GrMatrixConvolutionEffect(texture, bounds, kernelSize, kernel, gain, bias,
kernelOffset, tileMode, convolveAlpha));
}
+sk_sp<GrFragmentProcessor> GrMatrixConvolutionEffect::MakeGaussian(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha,
+ SkScalar sigmaX,
+ SkScalar sigmaY) {
+ float kernel[MAX_KERNEL_SIZE];
+
+ fill_in_2D_gaussian_kernel(kernel, kernelSize.width(), kernelSize.height(), sigmaX, sigmaY);
+
+ return sk_sp<GrFragmentProcessor>(
+ new GrMatrixConvolutionEffect(context, std::move(proxy), bounds, kernelSize, kernel,
+ gain, bias, kernelOffset, tileMode, convolveAlpha));
+}
+
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMatrixConvolutionEffect);
sk_sp<GrFragmentProcessor> GrMatrixConvolutionEffect::TestCreate(GrProcessorTestData* d) {
@@ -259,7 +311,8 @@ sk_sp<GrFragmentProcessor> GrMatrixConvolutionEffect::TestCreate(GrProcessorTest
GrTextureDomain::Mode tileMode =
static_cast<GrTextureDomain::Mode>(d->fRandom->nextRangeU(0, 2));
bool convolveAlpha = d->fRandom->nextBool();
- return GrMatrixConvolutionEffect::Make(d->fTextures[texIdx],
+ return GrMatrixConvolutionEffect::Make(d->context(),
+ d->textureProxy(texIdx),
bounds,
kernelSize,
kernel.get(),
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h
index 7cc88b651b..0bb7c5043a 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.h
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.h
@@ -43,6 +43,33 @@ public:
SkScalar sigmaX,
SkScalar sigmaY);
+ static sk_sp<GrFragmentProcessor> Make(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ const SkScalar* kernel,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha) {
+ return sk_sp<GrFragmentProcessor>(
+ new GrMatrixConvolutionEffect(context, std::move(proxy), bounds, kernelSize, kernel,
+ gain, bias, kernelOffset, tileMode, convolveAlpha));
+ }
+
+ static sk_sp<GrFragmentProcessor> MakeGaussian(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha,
+ SkScalar sigmaX,
+ SkScalar sigmaY);
+
const SkIRect& bounds() const { return fBounds; }
const SkISize& kernelSize() const { return fKernelSize; }
const float* kernelOffset() const { return fKernelOffset; }
@@ -65,6 +92,17 @@ private:
GrTextureDomain::Mode tileMode,
bool convolveAlpha);
+ GrMatrixConvolutionEffect(GrContext*,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& bounds,
+ const SkISize& kernelSize,
+ const SkScalar* kernel,
+ SkScalar gain,
+ SkScalar bias,
+ const SkIPoint& kernelOffset,
+ GrTextureDomain::Mode tileMode,
+ bool convolveAlpha);
+
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
diff --git a/src/gpu/effects/GrProxyMove.h b/src/gpu/effects/GrProxyMove.h
new file mode 100644
index 0000000000..643e01bc81
--- /dev/null
+++ b/src/gpu/effects/GrProxyMove.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProxyMove_DEFINED
+#define GrProxyMove_DEFINED
+
+// In a few places below we rely on braced initialization order being defined by the C++ spec (left
+// to right). We use operator-> on a sk_sp and then in a later argument std::move() the sk_sp. GCC
+// 4.9.0 and earlier has a bug where the left to right order evaluation isn't implemented correctly.
+#if defined(__GNUC__) && !defined(__clang__)
+# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+# if (GCC_VERSION > 40900)
+# define GCC_EVAL_ORDER_BUG 0
+# else
+# define GCC_EVAL_ORDER_BUG 1
+# endif
+# undef GCC_VERSION
+#else
+# define GCC_EVAL_ORDER_BUG 0
+#endif
+
+#if GCC_EVAL_ORDER_BUG
+# define GR_PROXY_MOVE(X) (X)
+#else
+# define GR_PROXY_MOVE(X) (std::move(X))
+#endif
+
+#undef GCC_EVAL_ORDER_BUG
+
+#endif
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index 682539ff3b..3dc6ea3a2c 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -7,11 +7,38 @@
#include "GrSimpleTextureEffect.h"
#include "GrInvariantOutput.h"
+#include "GrProxyMove.h"
#include "GrTexture.h"
#include "glsl/GrGLSLColorSpaceXformHelper.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
+GrSimpleTextureEffect::GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix& matrix,
+ GrSamplerParams::FilterMode filterMode)
+ : INHERITED{ctx,
+ ModulationFlags(proxy->config()),
+ GR_PROXY_MOVE(proxy),
+ std::move(colorSpaceXform),
+ matrix,
+ filterMode} {
+ this->initClassID<GrSimpleTextureEffect>();
+}
+
+GrSimpleTextureEffect::GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix& matrix,
+ const GrSamplerParams& params)
+ : INHERITED{ctx,
+ ModulationFlags(proxy->config()),
+ GR_PROXY_MOVE(proxy),
+ std::move(colorSpaceXform),
+ matrix,
+ params} {
+ this->initClassID<GrSimpleTextureEffect>();
+}
+
class GrGLSimpleTextureEffect : public GrGLSLFragmentProcessor {
public:
void emitCode(EmitArgs& args) override {
@@ -70,8 +97,8 @@ GrGLSLFragmentProcessor* GrSimpleTextureEffect::onCreateGLSLInstance() const {
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSimpleTextureEffect);
sk_sp<GrFragmentProcessor> GrSimpleTextureEffect::TestCreate(GrProcessorTestData* d) {
- int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
- GrProcessorUnitTest::kAlphaTextureIdx;
+ int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
+ : GrProcessorUnitTest::kAlphaTextureIdx;
static const SkShader::TileMode kTileModes[] = {
SkShader::kClamp_TileMode,
SkShader::kRepeat_TileMode,
@@ -81,10 +108,11 @@ sk_sp<GrFragmentProcessor> GrSimpleTextureEffect::TestCreate(GrProcessorTestData
kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
};
- GrSamplerParams params(tileModes, d->fRandom->nextBool() ? GrSamplerParams::kBilerp_FilterMode :
- GrSamplerParams::kNone_FilterMode);
+ GrSamplerParams params(tileModes, d->fRandom->nextBool() ? GrSamplerParams::kBilerp_FilterMode
+ : GrSamplerParams::kNone_FilterMode);
const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom);
- auto colorSpaceXform = GrTest::TestColorXform(d->fRandom);
- return GrSimpleTextureEffect::Make(d->fTextures[texIdx], colorSpaceXform, matrix);
+ sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(d->fRandom);
+ return GrSimpleTextureEffect::Make(d->context(), d->textureProxy(texIdx),
+ std::move(colorSpaceXform), matrix);
}
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
index c44ce44121..64ca3cb8f5 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.h
+++ b/src/gpu/effects/GrSimpleTextureEffect.h
@@ -13,29 +13,6 @@
class GrInvariantOutput;
-// In a few places below we rely on braced initialization order being defined by the C++ spec (left
-// to right). We use operator-> on a sk_sp and then in a later argument std::move() the sk_sp. GCC
-// 4.9.0 and earlier has a bug where the left to right order evaluation isn't implemented correctly.
-#if defined(__GNUC__) && !defined(__clang__)
-# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-# if (GCC_VERSION > 40900)
-# define GCC_EVAL_ORDER_BUG 0
-# else
-# define GCC_EVAL_ORDER_BUG 1
-# endif
-# undef GCC_VERSION
-#else
-# define GCC_EVAL_ORDER_BUG 0
-#endif
-
-#if GCC_EVAL_ORDER_BUG
-# define PROXY_MOVE(X) (X)
-#else
-# define PROXY_MOVE(X) (std::move(X))
-#endif
-
-#undef GCC_EVAL_ORDER_BUG
-
/**
* The output color of this effect is a modulation of the input color and a sample from a texture.
* It allows explicit specification of the filtering and wrap modes (GrSamplerParams) and accepts
@@ -52,23 +29,33 @@ public:
GrSamplerParams::kNone_FilterMode));
}
- static sk_sp<GrFragmentProcessor> Make(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
+ /* clamp mode */
+ static sk_sp<GrFragmentProcessor> Make(GrTexture* tex,
sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix& matrix) {
+ const SkMatrix& matrix,
+ GrSamplerParams::FilterMode filterMode) {
return sk_sp<GrFragmentProcessor>(
- new GrSimpleTextureEffect(ctx, std::move(proxy), std::move(colorSpaceXform), matrix,
- GrSamplerParams::kNone_FilterMode));
+ new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, filterMode));
}
- /* clamp mode */
static sk_sp<GrFragmentProcessor> Make(GrTexture* tex,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& matrix,
- GrSamplerParams::FilterMode filterMode) {
+ const GrSamplerParams& p) {
+ return sk_sp<GrFragmentProcessor>(new GrSimpleTextureEffect(tex, std::move(colorSpaceXform),
+ matrix, p));
+ }
+
+ /* unfiltered, clamp mode */
+ static sk_sp<GrFragmentProcessor> Make(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix& matrix) {
return sk_sp<GrFragmentProcessor>(
- new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, filterMode));
+ new GrSimpleTextureEffect(ctx, std::move(proxy), std::move(colorSpaceXform), matrix,
+ GrSamplerParams::kNone_FilterMode));
}
+ /* clamp mode */
static sk_sp<GrFragmentProcessor> Make(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& matrix,
@@ -78,14 +65,6 @@ public:
matrix, filterMode));
}
- static sk_sp<GrFragmentProcessor> Make(GrTexture* tex,
- sk_sp<GrColorSpaceXform> colorSpaceXform,
- const SkMatrix& matrix,
- const GrSamplerParams& p) {
- return sk_sp<GrFragmentProcessor>(new GrSimpleTextureEffect(tex, std::move(colorSpaceXform),
- matrix, p));
- }
-
static sk_sp<GrFragmentProcessor> Make(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& matrix,
@@ -109,18 +88,6 @@ private:
this->initClassID<GrSimpleTextureEffect>();
}
- GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
- sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix,
- GrSamplerParams::FilterMode filterMode)
- : INHERITED{ctx,
- ModulationFlags(proxy->config()),
- PROXY_MOVE(proxy),
- std::move(colorSpaceXform),
- matrix,
- filterMode} {
- this->initClassID<GrSimpleTextureEffect>();
- }
-
GrSimpleTextureEffect(GrTexture* texture,
sk_sp<GrColorSpaceXform>colorSpaceXform,
const SkMatrix& matrix,
@@ -132,15 +99,11 @@ private:
GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix,
- const GrSamplerParams& params)
- : INHERITED{ctx,
- ModulationFlags(proxy->config()),
- PROXY_MOVE(proxy),
- std::move(colorSpaceXform),
- matrix,
- params} {
- this->initClassID<GrSimpleTextureEffect>();
- }
+ GrSamplerParams::FilterMode filterMode);
+
+ GrSimpleTextureEffect(GrContext* ctx, sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix,
+ const GrSamplerParams& params);
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -155,6 +118,4 @@ private:
typedef GrSingleTextureEffect INHERITED;
};
-#undef PROXY_MOVE
-
#endif
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 7ab598fd1f..f27b776f3c 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -6,9 +6,12 @@
*/
#include "GrTextureDomain.h"
+
+#include "GrContext.h"
#include "GrInvariantOutput.h"
#include "GrShaderCaps.h"
#include "GrSimpleTextureEffect.h"
+#include "GrSurfaceProxyPriv.h"
#include "SkFloatingPoint.h"
#include "glsl/GrGLSLColorSpaceXformHelper.h"
#include "glsl/GrGLSLFragmentProcessor.h"
@@ -17,6 +20,16 @@
#include "glsl/GrGLSLShaderBuilder.h"
#include "glsl/GrGLSLUniformHandler.h"
+static bool can_ignore_rect(GrSurfaceProxy* proxy, const SkRect& domain) {
+ if (proxy->priv().isExact()) {
+ const SkIRect kFullRect = SkIRect::MakeWH(proxy->width(), proxy->height());
+
+ return domain.contains(kFullRect);
+ }
+
+ return false;
+}
+
static bool can_ignore_rect(GrTexture* tex, const SkRect& domain) {
// This logic is relying on the instantiated size of 'tex'. In the deferred world it
// will have to change so this logic only fires for kExact texture proxies. This shouldn't
@@ -28,7 +41,8 @@ static bool can_ignore_rect(GrTexture* tex, const SkRect& domain) {
}
GrTextureDomain::GrTextureDomain(GrTexture* tex, const SkRect& domain, Mode mode, int index)
- : fMode(mode), fIndex(index) {
+ : fMode(mode)
+ , fIndex(index) {
if (kIgnore_Mode == fMode) {
return;
@@ -54,6 +68,34 @@ GrTextureDomain::GrTextureDomain(GrTexture* tex, const SkRect& domain, Mode mode
SkASSERT(fDomain.fTop <= fDomain.fBottom);
}
+GrTextureDomain::GrTextureDomain(GrTextureProxy* proxy, const SkRect& domain, Mode mode, int index)
+ : fMode(mode)
+ , fIndex(index) {
+
+ if (kIgnore_Mode == fMode) {
+ return;
+ }
+
+ if (kClamp_Mode == mode && can_ignore_rect(proxy, domain)) {
+ fMode = kIgnore_Mode;
+ return;
+ }
+
+ const SkRect kFullRect = SkRect::MakeIWH(proxy->width(), proxy->height());
+
+ // We don't currently handle domains that are empty or don't intersect the texture.
+ // It is OK if the domain rect is a line or point, but it should not be inverted. We do not
+ // handle rects that do not intersect the [0..1]x[0..1] rect.
+ SkASSERT(domain.fLeft <= domain.fRight);
+ SkASSERT(domain.fTop <= domain.fBottom);
+ fDomain.fLeft = SkScalarPin(domain.fLeft, 0.0f, kFullRect.fRight);
+ fDomain.fRight = SkScalarPin(domain.fRight, fDomain.fLeft, kFullRect.fRight);
+ fDomain.fTop = SkScalarPin(domain.fTop, 0.0f, kFullRect.fBottom);
+ fDomain.fBottom = SkScalarPin(domain.fBottom, fDomain.fTop, kFullRect.fBottom);
+ SkASSERT(fDomain.fLeft <= fDomain.fRight);
+ SkASSERT(fDomain.fTop <= fDomain.fBottom);
+}
+
//////////////////////////////////////////////////////////////////////////////
void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder,
@@ -191,7 +233,6 @@ void GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman,
}
///////////////////////////////////////////////////////////////////////////////
-
sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& matrix,
@@ -209,8 +250,8 @@ sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture,
}
inline GrFragmentProcessor::OptimizationFlags GrTextureDomainEffect::OptFlags(
- GrTexture* texture, GrTextureDomain::Mode mode) {
- if (mode == GrTextureDomain::kDecal_Mode || !GrPixelConfigIsOpaque(texture->config())) {
+ GrPixelConfig config, GrTextureDomain::Mode mode) {
+ if (mode == GrTextureDomain::kDecal_Mode || !GrPixelConfigIsOpaque(config)) {
return GrFragmentProcessor::kModulatesInput_OptimizationFlag;
} else {
return GrFragmentProcessor::kModulatesInput_OptimizationFlag |
@@ -225,13 +266,46 @@ GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
GrTextureDomain::Mode mode,
GrSamplerParams::FilterMode filterMode)
: GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode,
- OptFlags(texture, mode))
+ OptFlags(texture->config(), mode))
, fTextureDomain(texture, domain, mode) {
SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
filterMode == GrSamplerParams::kNone_FilterMode);
this->initClassID<GrTextureDomainEffect>();
}
+sk_sp<GrFragmentProcessor> GrTextureDomainEffect::Make(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix& matrix,
+ const SkRect& domain,
+ GrTextureDomain::Mode mode,
+ GrSamplerParams::FilterMode filterMode) {
+ if (GrTextureDomain::kIgnore_Mode == mode ||
+ (GrTextureDomain::kClamp_Mode == mode && can_ignore_rect(proxy.get(), domain))) {
+ return GrSimpleTextureEffect::Make(context, std::move(proxy), std::move(colorSpaceXform),
+ matrix, filterMode);
+ } else {
+ return sk_sp<GrFragmentProcessor>(
+ new GrTextureDomainEffect(context, std::move(proxy), std::move(colorSpaceXform),
+ matrix, domain, mode, filterMode));
+ }
+}
+
+GrTextureDomainEffect::GrTextureDomainEffect(GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ const SkMatrix& matrix,
+ const SkRect& domain,
+ GrTextureDomain::Mode mode,
+ GrSamplerParams::FilterMode filterMode)
+ : GrSingleTextureEffect(context, OptFlags(proxy->config(), mode), proxy,
+ std::move(colorSpaceXform), matrix, filterMode)
+ , fTextureDomain(proxy.get(), domain, mode) {
+ SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
+ filterMode == GrSamplerParams::kNone_FilterMode);
+ this->initClassID<GrTextureDomainEffect>();
+}
+
void GrTextureDomainEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
GrProcessorKeyBuilder* b) const {
b->add32(GrTextureDomain::GLDomain::DomainKey(fTextureDomain));
@@ -302,26 +376,27 @@ void GrTextureDomainEffect::onComputeInvariantOutput(GrInvariantOutput* inout) c
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrTextureDomainEffect);
sk_sp<GrFragmentProcessor> GrTextureDomainEffect::TestCreate(GrProcessorTestData* d) {
- int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
- GrProcessorUnitTest::kAlphaTextureIdx;
- GrTexture* tex = d->fTextures[texIdx];
+ int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
+ : GrProcessorUnitTest::kAlphaTextureIdx;
+ sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
SkRect domain;
- domain.fLeft = d->fRandom->nextRangeScalar(0, tex->width());
- domain.fRight = d->fRandom->nextRangeScalar(domain.fLeft, tex->width());
- domain.fTop = d->fRandom->nextRangeScalar(0, tex->height());
- domain.fBottom = d->fRandom->nextRangeScalar(domain.fTop, tex->height());
+ domain.fLeft = d->fRandom->nextRangeScalar(0, proxy->width());
+ domain.fRight = d->fRandom->nextRangeScalar(domain.fLeft, proxy->width());
+ domain.fTop = d->fRandom->nextRangeScalar(0, proxy->height());
+ domain.fBottom = d->fRandom->nextRangeScalar(domain.fTop, proxy->height());
GrTextureDomain::Mode mode =
(GrTextureDomain::Mode) d->fRandom->nextULessThan(GrTextureDomain::kModeCount);
const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom);
bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? d->fRandom->nextBool() : false;
- auto colorSpaceXform = GrTest::TestColorXform(d->fRandom);
- return GrTextureDomainEffect::Make(
- tex,
- colorSpaceXform,
- matrix,
- domain,
- mode,
- bilerp ? GrSamplerParams::kBilerp_FilterMode : GrSamplerParams::kNone_FilterMode);
+ sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(d->fRandom);
+ return GrTextureDomainEffect::Make(d->context(),
+ std::move(proxy),
+ std::move(colorSpaceXform),
+ matrix,
+ domain,
+ mode,
+ bilerp ? GrSamplerParams::kBilerp_FilterMode
+ : GrSamplerParams::kNone_FilterMode);
}
///////////////////////////////////////////////////////////////////////////////
@@ -344,6 +419,30 @@ GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentPro
this->initClassID<GrDeviceSpaceTextureDecalFragmentProcessor>();
}
+sk_sp<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::Make(
+ GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& subset,
+ const SkIPoint& deviceSpaceOffset) {
+ return sk_sp<GrFragmentProcessor>(new GrDeviceSpaceTextureDecalFragmentProcessor(
+ context, std::move(proxy), subset, deviceSpaceOffset));
+}
+
+GrDeviceSpaceTextureDecalFragmentProcessor::GrDeviceSpaceTextureDecalFragmentProcessor(
+ GrContext* context,
+ sk_sp<GrTextureProxy> proxy,
+ const SkIRect& subset,
+ const SkIPoint& deviceSpaceOffset)
+ : INHERITED(kModulatesInput_OptimizationFlag)
+ , fTextureSampler(context->textureProvider(), proxy, GrSamplerParams::ClampNoFilter())
+ , fTextureDomain(proxy.get(), GrTextureDomain::MakeTexelDomain(subset),
+ GrTextureDomain::kDecal_Mode) {
+ this->addTextureSampler(&fTextureSampler);
+ fDeviceSpaceOffset.fX = deviceSpaceOffset.fX - subset.fLeft;
+ fDeviceSpaceOffset.fY = deviceSpaceOffset.fY - subset.fTop;
+ this->initClassID<GrDeviceSpaceTextureDecalFragmentProcessor>();
+}
+
GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLSLInstance() const {
class GLSLProcessor : public GrGLSLFragmentProcessor {
public:
@@ -420,13 +519,15 @@ sk_sp<GrFragmentProcessor> GrDeviceSpaceTextureDecalFragmentProcessor::TestCreat
GrProcessorTestData* d) {
int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
: GrProcessorUnitTest::kAlphaTextureIdx;
+ sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
SkIRect subset;
- subset.fLeft = d->fRandom->nextULessThan(d->fTextures[texIdx]->width() - 1);
- subset.fRight = d->fRandom->nextRangeU(subset.fLeft, d->fTextures[texIdx]->width());
- subset.fTop = d->fRandom->nextULessThan(d->fTextures[texIdx]->height() - 1);
- subset.fBottom = d->fRandom->nextRangeU(subset.fTop, d->fTextures[texIdx]->height());
+ subset.fLeft = d->fRandom->nextULessThan(proxy->width() - 1);
+ subset.fRight = d->fRandom->nextRangeU(subset.fLeft, proxy->width());
+ subset.fTop = d->fRandom->nextULessThan(proxy->height() - 1);
+ subset.fBottom = d->fRandom->nextRangeU(subset.fTop, proxy->height());
SkIPoint pt;
pt.fX = d->fRandom->nextULessThan(2048);
pt.fY = d->fRandom->nextULessThan(2048);
- return GrDeviceSpaceTextureDecalFragmentProcessor::Make(d->fTextures[texIdx], subset, pt);
+ return GrDeviceSpaceTextureDecalFragmentProcessor::Make(d->context(),
+ std::move(proxy), subset, pt);
}
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index 6758d9045e..fbc20f1947 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -44,7 +44,8 @@ public:
static const int kModeCount = kLastMode + 1;
static const GrTextureDomain& IgnoredDomain() {
- static const GrTextureDomain gDomain(nullptr, SkRect::MakeEmpty(), kIgnore_Mode);
+ static const GrTextureDomain gDomain((GrTextureProxy*)nullptr,
+ SkRect::MakeEmpty(), kIgnore_Mode);
return gDomain;
}
@@ -54,6 +55,8 @@ public:
*/
GrTextureDomain(GrTexture*, const SkRect& domain, Mode, int index = -1);
+ GrTextureDomain(GrTextureProxy*, const SkRect& domain, Mode, int index = -1);
+
const SkRect& domain() const { return fDomain; }
Mode mode() const { return fMode; }
@@ -157,6 +160,14 @@ public:
GrTextureDomain::Mode,
GrSamplerParams::FilterMode filterMode);
+ static sk_sp<GrFragmentProcessor> Make(GrContext*,
+ sk_sp<GrTextureProxy>,
+ sk_sp<GrColorSpaceXform>,
+ const SkMatrix&,
+ const SkRect& domain,
+ GrTextureDomain::Mode,
+ GrSamplerParams::FilterMode filterMode);
+
const char* name() const override { return "TextureDomain"; }
SkString dumpInfo() const override {
@@ -178,7 +189,15 @@ private:
GrTextureDomain::Mode,
GrSamplerParams::FilterMode);
- static OptimizationFlags OptFlags(GrTexture* texture, GrTextureDomain::Mode mode);
+ GrTextureDomainEffect(GrContext*,
+ sk_sp<GrTextureProxy>,
+ sk_sp<GrColorSpaceXform>,
+ const SkMatrix&,
+ const SkRect& domain,
+ GrTextureDomain::Mode,
+ GrSamplerParams::FilterMode);
+
+ static OptimizationFlags OptFlags(GrPixelConfig config, GrTextureDomain::Mode mode);
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -198,6 +217,9 @@ public:
static sk_sp<GrFragmentProcessor> Make(GrTexture*, const SkIRect& subset,
const SkIPoint& deviceSpaceOffset);
+ static sk_sp<GrFragmentProcessor> Make(GrContext*, sk_sp<GrTextureProxy>, const SkIRect& subset,
+ const SkIPoint& deviceSpaceOffset);
+
const char* name() const override { return "GrDeviceSpaceTextureDecalFragmentProcessor"; }
SkString dumpInfo() const override {
@@ -217,6 +239,9 @@ private:
GrDeviceSpaceTextureDecalFragmentProcessor(GrTexture*, const SkIRect&, const SkIPoint&);
+ GrDeviceSpaceTextureDecalFragmentProcessor(GrContext*, sk_sp<GrTextureProxy>,
+ const SkIRect&, const SkIPoint&);
+
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
// Since we always use decal mode, there is no need for key data.