aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects/GrTextureDomain.cpp
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-01-30 08:06:27 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-30 13:40:15 +0000
commit40fd7c94c24bb30d888c3d85a79cbb96c7fbf800 (patch)
tree075e886c01de864ba982910f1854f47ba1ae95d8 /src/gpu/effects/GrTextureDomain.cpp
parent55b72530fedeb58154635531751a8730982fbf2a (diff)
Push GrTextureProxy down to more effects
Change-Id: Ie3f32a88f25af082c25bc6daf3fe24e303e80f9e Reviewed-on: https://skia-review.googlesource.com/7616 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/effects/GrTextureDomain.cpp')
-rw-r--r--src/gpu/effects/GrTextureDomain.cpp151
1 files changed, 126 insertions, 25 deletions
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);
}