aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/clockwise.cpp4
-rw-r--r--src/gpu/GrRenderTargetContext.cpp6
-rw-r--r--src/gpu/GrRenderTargetContext.h2
-rw-r--r--src/gpu/SkGpuDevice_drawTexture.cpp18
-rw-r--r--src/gpu/ops/GrTextureOp.cpp110
-rw-r--r--src/gpu/ops/GrTextureOp.h3
6 files changed, 95 insertions, 48 deletions
diff --git a/gm/clockwise.cpp b/gm/clockwise.cpp
index 0ca6e0a567..00bc47ecda 100644
--- a/gm/clockwise.cpp
+++ b/gm/clockwise.cpp
@@ -168,7 +168,7 @@ void ClockwiseGM::onDraw(SkCanvas* canvas) {
GrSamplerState::Filter::kNearest, 0xffffffff, {0,0,100,200},
{100,0,200,200}, GrAA::kNo,
SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint, SkMatrix::I(),
- nullptr);
+ nullptr, nullptr);
}
// Draw the test to an off-screen, bottom-up render target.
@@ -183,7 +183,7 @@ void ClockwiseGM::onDraw(SkCanvas* canvas) {
GrSamplerState::Filter::kNearest, 0xffffffff, {0,0,100,200},
{200,0,300,200}, GrAA::kNo,
SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint, SkMatrix::I(),
- nullptr);
+ nullptr, nullptr);
}
}
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 7d88bc4936..a67e19a9d9 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -764,7 +764,8 @@ void GrRenderTargetContext::drawTexture(const GrClip& clip, sk_sp<GrTextureProxy
const SkRect& srcRect, const SkRect& dstRect, GrAA aa,
SkCanvas::SrcRectConstraint constraint,
const SkMatrix& viewMatrix,
- sk_sp<GrColorSpaceXform> colorSpaceXform) {
+ sk_sp<GrColorSpaceXform> textureColorSpaceXform,
+ sk_sp<GrColorSpaceXform> paintColorSpaceXform) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
@@ -790,7 +791,8 @@ void GrRenderTargetContext::drawTexture(const GrClip& clip, sk_sp<GrTextureProxy
}
this->addDrawOp(clip, GrTextureOp::Make(fContext, std::move(proxy), filter, color,
clippedSrcRect, clippedDstRect, aaType, constraint,
- viewMatrix, std::move(colorSpaceXform)));
+ viewMatrix, std::move(textureColorSpaceXform),
+ std::move(paintColorSpaceXform)));
}
void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 565a2b8c08..4e31a1a45d 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -148,7 +148,7 @@ public:
void drawTexture(const GrClip& clip, sk_sp<GrTextureProxy>, GrSamplerState::Filter, GrColor,
const SkRect& srcRect, const SkRect& dstRect, GrAA aa,
SkCanvas::SrcRectConstraint, const SkMatrix& viewMatrix,
- sk_sp<GrColorSpaceXform>);
+ sk_sp<GrColorSpaceXform> texXform, sk_sp<GrColorSpaceXform> colorXform);
/**
* Draw a roundrect using a paint.
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index af397cd431..9b2641ea83 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -99,7 +99,6 @@ static bool can_use_draw_texture(const SkPaint& paint) {
static void draw_texture(const SkPaint& paint, const SkMatrix& ctm, const SkRect* src,
const SkRect* dst, GrAA aa, SkCanvas::SrcRectConstraint constraint,
sk_sp<GrTextureProxy> proxy,
-
SkColorSpace* colorSpace, const GrClip& clip, GrRenderTargetContext* rtc) {
SkASSERT(!(SkToBool(src) && !SkToBool(dst)));
SkRect srcRect = src ? *src : SkRect::MakeWH(proxy->width(), proxy->height());
@@ -111,7 +110,7 @@ static void draw_texture(const SkPaint& paint, const SkMatrix& ctm, const SkRect
SkAssertResult(srcRect.intersect(SkRect::MakeIWH(proxy->width(), proxy->height())));
srcToDst.mapRect(&dstRect, srcRect);
}
- auto csxf = GrColorSpaceXform::Make(colorSpace, rtc->colorSpaceInfo().colorSpace());
+ auto textureXform = GrColorSpaceXform::Make(colorSpace, rtc->colorSpaceInfo().colorSpace());
GrSamplerState::Filter filter;
switch (paint.getFilterQuality()) {
case kNone_SkFilterQuality:
@@ -124,11 +123,18 @@ static void draw_texture(const SkPaint& paint, const SkMatrix& ctm, const SkRect
case kHigh_SkFilterQuality:
SK_ABORT("Quality level not allowed.");
}
- GrColor color = GrPixelConfigIsAlphaOnly(proxy->config())
- ? SkColorToPremulGrColor(paint.getColor())
- : SkColorAlphaToGrColor(paint.getColor());
+ GrColor color;
+ sk_sp<GrColorSpaceXform> paintColorXform = nullptr;
+ if (GrPixelConfigIsAlphaOnly(proxy->config())) {
+ // Leave the color unpremul if we're going to transform it in the vertex shader
+ paintColorXform = rtc->colorSpaceInfo().refColorSpaceXformFromSRGB();
+ color = paintColorXform ? SkColorToUnpremulGrColor(paint.getColor())
+ : SkColorToPremulGrColor(paint.getColor());
+ } else {
+ color = SkColorAlphaToGrColor(paint.getColor());
+ }
rtc->drawTexture(clip, std::move(proxy), filter, color, srcRect, dstRect, aa, constraint, ctm,
- std::move(csxf));
+ std::move(textureXform), std::move(paintColorXform));
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 99ecdf8101..516cee628f 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -105,7 +105,9 @@ public:
}
static sk_sp<GrGeometryProcessor> Make(sk_sp<GrTextureProxy> proxies[], int proxyCnt,
- sk_sp<GrColorSpaceXform> csxf, bool coverageAA,
+ sk_sp<GrColorSpaceXform> textureColorSpaceXform,
+ sk_sp<GrColorSpaceXform> paintColorSpaceXform,
+ bool coverageAA,
bool perspective, Domain domain,
const GrSamplerState::Filter filters[],
const GrShaderCaps& caps) {
@@ -115,7 +117,9 @@ public:
size_t size = sizeof(TextureGeometryProcessor) + sizeof(TextureSampler) * (samplerCnt - 1);
void* mem = GrGeometryProcessor::operator new(size);
return sk_sp<TextureGeometryProcessor>(
- new (mem) TextureGeometryProcessor(proxies, proxyCnt, samplerCnt, std::move(csxf),
+ new (mem) TextureGeometryProcessor(proxies, proxyCnt, samplerCnt,
+ std::move(textureColorSpaceXform),
+ std::move(paintColorSpaceXform),
coverageAA, perspective, domain, filters, caps));
}
@@ -129,7 +133,8 @@ public:
const char* name() const override { return "TextureGeometryProcessor"; }
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
- b->add32(GrColorSpaceXform::XformKey(fColorSpaceXform.get()));
+ b->add32(GrColorSpaceXform::XformKey(fTextureColorSpaceXform.get()));
+ b->add32(GrColorSpaceXform::XformKey(fPaintColorSpaceXform.get()));
uint32_t x = this->usesCoverageEdgeAA() ? 0 : 1;
x |= kFloat3_GrVertexAttribType == fPositions.type() ? 0 : 2;
x |= fDomain.isInitialized() ? 4 : 0;
@@ -143,15 +148,20 @@ public:
FPCoordTransformIter&& transformIter) override {
const auto& textureGP = proc.cast<TextureGeometryProcessor>();
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
- fColorSpaceXformHelper.setData(pdman, textureGP.fColorSpaceXform.get());
+ fTextureColorSpaceXformHelper.setData(
+ pdman, textureGP.fTextureColorSpaceXform.get());
+ fPaintColorSpaceXformHelper.setData(pdman, textureGP.fPaintColorSpaceXform.get());
}
private:
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
using Interpolation = GrGLSLVaryingHandler::Interpolation;
const auto& textureGP = args.fGP.cast<TextureGeometryProcessor>();
- fColorSpaceXformHelper.emitCode(
- args.fUniformHandler, textureGP.fColorSpaceXform.get());
+ fTextureColorSpaceXformHelper.emitCode(
+ args.fUniformHandler, textureGP.fTextureColorSpaceXform.get());
+ fPaintColorSpaceXformHelper.emitCode(
+ args.fUniformHandler, textureGP.fPaintColorSpaceXform.get(),
+ kVertex_GrShaderFlag);
if (kFloat2_GrVertexAttribType == textureGP.fPositions.type()) {
args.fVaryingHandler->setNoPerspective();
}
@@ -163,8 +173,20 @@ public:
args.fUniformHandler,
textureGP.fTextureCoords.asShaderVar(),
args.fFPCoordTransformHandler);
- args.fVaryingHandler->addPassThroughAttribute(
- textureGP.fColors, args.fOutputColor, Interpolation::kCanBeFlat);
+ if (fPaintColorSpaceXformHelper.isNoop()) {
+ args.fVaryingHandler->addPassThroughAttribute(
+ textureGP.fColors, args.fOutputColor, Interpolation::kCanBeFlat);
+ } else {
+ GrGLSLVarying varying(kHalf4_GrSLType);
+ args.fVaryingHandler->addVarying("color", &varying);
+ args.fVertBuilder->codeAppend("half4 color = ");
+ args.fVertBuilder->appendColorGamutXform(textureGP.fColors.name(),
+ &fPaintColorSpaceXformHelper);
+ args.fVertBuilder->codeAppend(";");
+ args.fVertBuilder->codeAppendf("%s = half4(color.rgb * color.a, color.a);",
+ varying.vsOut());
+ args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
+ }
args.fFragBuilder->codeAppend("float2 texCoord;");
args.fVaryingHandler->addPassThroughAttribute(textureGP.fTextureCoords, "texCoord");
if (textureGP.fDomain.isInitialized()) {
@@ -185,21 +207,17 @@ public:
args.fFragBuilder->codeAppend("switch (texIdx) {");
for (int i = 0; i < textureGP.numTextureSamplers(); ++i) {
args.fFragBuilder->codeAppendf("case %d: %s = ", i, args.fOutputColor);
- args.fFragBuilder->appendTextureLookupAndModulate(args.fOutputColor,
- args.fTexSamplers[i],
- "texCoord",
- kFloat2_GrSLType,
- &fColorSpaceXformHelper);
+ args.fFragBuilder->appendTextureLookupAndModulate(
+ args.fOutputColor, args.fTexSamplers[i], "texCoord",
+ kFloat2_GrSLType, &fTextureColorSpaceXformHelper);
args.fFragBuilder->codeAppend("; break;");
}
args.fFragBuilder->codeAppend("}");
} else {
args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor);
- args.fFragBuilder->appendTextureLookupAndModulate(args.fOutputColor,
- args.fTexSamplers[0],
- "texCoord",
- kFloat2_GrSLType,
- &fColorSpaceXformHelper);
+ args.fFragBuilder->appendTextureLookupAndModulate(
+ args.fOutputColor, args.fTexSamplers[0], "texCoord",
+ kFloat2_GrSLType, &fTextureColorSpaceXformHelper);
}
args.fFragBuilder->codeAppend(";");
if (textureGP.usesCoverageEdgeAA()) {
@@ -244,7 +262,8 @@ public:
args.fFragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage);
}
}
- GrGLSLColorSpaceXformHelper fColorSpaceXformHelper;
+ GrGLSLColorSpaceXformHelper fTextureColorSpaceXformHelper;
+ GrGLSLColorSpaceXformHelper fPaintColorSpaceXformHelper;
};
return new GLSLProcessor;
}
@@ -268,10 +287,13 @@ private:
}
TextureGeometryProcessor(sk_sp<GrTextureProxy> proxies[], int proxyCnt, int samplerCnt,
- sk_sp<GrColorSpaceXform> csxf, bool coverageAA, bool perspective,
- Domain domain, const GrSamplerState::Filter filters[],
- const GrShaderCaps& caps)
- : INHERITED(kTextureGeometryProcessor_ClassID), fColorSpaceXform(std::move(csxf)) {
+ sk_sp<GrColorSpaceXform> textureColorSpaceXform,
+ sk_sp<GrColorSpaceXform> paintColorSpaceXform,
+ bool coverageAA, bool perspective, Domain domain,
+ const GrSamplerState::Filter filters[], const GrShaderCaps& caps)
+ : INHERITED(kTextureGeometryProcessor_ClassID)
+ , fTextureColorSpaceXform(std::move(textureColorSpaceXform))
+ , fPaintColorSpaceXform(std::move(paintColorSpaceXform)) {
SkASSERT(proxyCnt > 0 && samplerCnt >= proxyCnt);
fSamplers[0].reset(std::move(proxies[0]), filters[0]);
this->addTextureSampler(&fSamplers[0]);
@@ -328,7 +350,8 @@ private:
Attribute fTextureIdx;
Attribute fDomain;
Attribute fAAEdges[4];
- sk_sp<GrColorSpaceXform> fColorSpaceXform;
+ sk_sp<GrColorSpaceXform> fTextureColorSpaceXform;
+ sk_sp<GrColorSpaceXform> fPaintColorSpaceXform;
TextureSampler fSamplers[1];
typedef GrGeometryProcessor INHERITED;
@@ -597,12 +620,14 @@ public:
GrAAType aaType,
SkCanvas::SrcRectConstraint constraint,
const SkMatrix& viewMatrix,
- sk_sp<GrColorSpaceXform> csxf) {
+ sk_sp<GrColorSpaceXform> textureColorSpaceXform,
+ sk_sp<GrColorSpaceXform> paintColorSpaceXform) {
GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
return pool->allocate<TextureOp>(std::move(proxy), filter, color,
srcRect, dstRect, aaType, constraint,
- viewMatrix, std::move(csxf));
+ viewMatrix, std::move(textureColorSpaceXform),
+ std::move(paintColorSpaceXform));
}
~TextureOp() override {
@@ -685,9 +710,11 @@ __attribute__((no_sanitize("float-cast-overflow")))
TextureOp(sk_sp<GrTextureProxy> proxy, GrSamplerState::Filter filter, GrColor color,
const SkRect& srcRect, const SkRect& dstRect, GrAAType aaType,
SkCanvas::SrcRectConstraint constraint, const SkMatrix& viewMatrix,
- sk_sp<GrColorSpaceXform> csxf)
+ sk_sp<GrColorSpaceXform> textureColorSpaceXform,
+ sk_sp<GrColorSpaceXform> paintColorSpaceXform)
: INHERITED(ClassID())
- , fColorSpaceXform(std::move(csxf))
+ , fTextureColorSpaceXform(std::move(textureColorSpaceXform))
+ , fPaintColorSpaceXform(std::move(paintColorSpaceXform))
, fProxy0(proxy.release())
, fFilter0(filter)
, fProxyCnt(1)
@@ -750,7 +777,8 @@ __attribute__((no_sanitize("float-cast-overflow")))
Domain domain = fDomain ? Domain::kYes : Domain::kNo;
bool coverageAA = GrAAType::kCoverage == this->aaType();
sk_sp<GrGeometryProcessor> gp = TextureGeometryProcessor::Make(
- proxiesSPs, fProxyCnt, std::move(fColorSpaceXform), coverageAA, fPerspective,
+ proxiesSPs, fProxyCnt, std::move(fTextureColorSpaceXform),
+ std::move(fPaintColorSpaceXform), coverageAA, fPerspective,
domain, filters, *target->caps().shaderCaps());
GrPipeline::InitArgs args;
args.fProxy = target->proxy();
@@ -842,7 +870,12 @@ __attribute__((no_sanitize("float-cast-overflow")))
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
const auto* that = t->cast<TextureOp>();
const auto& shaderCaps = *caps.shaderCaps();
- if (!GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get())) {
+ if (!GrColorSpaceXform::Equals(fTextureColorSpaceXform.get(),
+ that->fTextureColorSpaceXform.get())) {
+ return false;
+ }
+ if (!GrColorSpaceXform::Equals(fPaintColorSpaceXform.get(),
+ that->fPaintColorSpaceXform.get())) {
return false;
}
if (this->aaType() != that->aaType()) {
@@ -850,7 +883,8 @@ __attribute__((no_sanitize("float-cast-overflow")))
}
// Because of an issue where GrColorSpaceXform adds the same function every time it is used
// in a texture lookup, we only allow multiple textures when there is no transform.
- if (TextureGeometryProcessor::SupportsMultitexture(shaderCaps) && !fColorSpaceXform &&
+ if (TextureGeometryProcessor::SupportsMultitexture(shaderCaps) &&
+ !fTextureColorSpaceXform &&
fMaxApproxDstPixelArea <= shaderCaps.disableImageMultitexturingDstRectAreaThreshold() &&
that->fMaxApproxDstPixelArea <=
shaderCaps.disableImageMultitexturingDstRectAreaThreshold()) {
@@ -999,7 +1033,8 @@ __attribute__((no_sanitize("float-cast-overflow")))
GrColor fColor;
};
SkSTArray<1, Draw, true> fDraws;
- sk_sp<GrColorSpaceXform> fColorSpaceXform;
+ sk_sp<GrColorSpaceXform> fTextureColorSpaceXform;
+ sk_sp<GrColorSpaceXform> fPaintColorSpaceXform;
// Initially we store a single proxy ptr and a single filter. If we grow to have more than
// one proxy we instead store pointers to dynamically allocated arrays of size kMaxTextures
// followed by kMaxTextures filters.
@@ -1035,9 +1070,11 @@ std::unique_ptr<GrDrawOp> Make(GrContext* context,
GrAAType aaType,
SkCanvas::SrcRectConstraint constraint,
const SkMatrix& viewMatrix,
- sk_sp<GrColorSpaceXform> csxf) {
+ sk_sp<GrColorSpaceXform> textureColorSpaceXform,
+ sk_sp<GrColorSpaceXform> paintColorSpaceXform) {
return TextureOp::Make(context, std::move(proxy), filter, color, srcRect, dstRect, aaType,
- constraint, viewMatrix, std::move(csxf));
+ constraint, viewMatrix, std::move(textureColorSpaceXform),
+ std::move(paintColorSpaceXform));
}
} // namespace GrTextureOp
@@ -1078,7 +1115,8 @@ GR_DRAW_OP_TEST_DEFINE(TextureOp) {
filter = (GrSamplerState::Filter)random->nextULessThan(
static_cast<uint32_t>(GrSamplerState::Filter::kMipMap) + 1);
}
- auto csxf = GrTest::TestColorXform(random);
+ auto texXform = GrTest::TestColorXform(random);
+ auto paintXform = GrTest::TestColorXform(random);
GrAAType aaType = GrAAType::kNone;
if (random->nextBool()) {
aaType = (fsaaType == GrFSAAType::kUnifiedMSAA) ? GrAAType::kMSAA : GrAAType::kCoverage;
@@ -1086,7 +1124,7 @@ GR_DRAW_OP_TEST_DEFINE(TextureOp) {
auto constraint = random->nextBool() ? SkCanvas::kStrict_SrcRectConstraint
: SkCanvas::kFast_SrcRectConstraint;
return GrTextureOp::Make(context, std::move(proxy), filter, color, srcRect, rect, aaType,
- constraint, viewMatrix, std::move(csxf));
+ constraint, viewMatrix, std::move(texXform), std::move(paintXform));
}
#endif
diff --git a/src/gpu/ops/GrTextureOp.h b/src/gpu/ops/GrTextureOp.h
index 7211b5edc2..96cbc70cb8 100644
--- a/src/gpu/ops/GrTextureOp.h
+++ b/src/gpu/ops/GrTextureOp.h
@@ -34,5 +34,6 @@ std::unique_ptr<GrDrawOp> Make(GrContext*,
GrAAType,
SkCanvas::SrcRectConstraint,
const SkMatrix& viewMatrix,
- sk_sp<GrColorSpaceXform>);
+ sk_sp<GrColorSpaceXform> textureXform,
+ sk_sp<GrColorSpaceXform> paintXform);
}