From c906d250658d6728e1df80428e10414d0d7e2836 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Tue, 4 Dec 2018 11:17:46 -0500 Subject: [PATCH] Half float vertex colors (when necessary) in small path renderer Bug: skia: Change-Id: I34fa12e8d7dbf003d4776df779967dd273228502 Reviewed-on: https://skia-review.googlesource.com/c/174302 Reviewed-by: Jim Van Verth Commit-Queue: Brian Osman --- src/gpu/GrGeometryProcessor.h | 8 ++++++++ src/gpu/effects/GrBitmapTextGeoProc.cpp | 4 +++- src/gpu/effects/GrBitmapTextGeoProc.h | 7 ++++--- src/gpu/effects/GrDistanceFieldGeoProc.cpp | 4 +++- src/gpu/effects/GrDistanceFieldGeoProc.h | 5 ++++- src/gpu/ops/GrAtlasTextOp.cpp | 4 ++-- src/gpu/ops/GrOvalOpFactory.cpp | 14 ++++---------- src/gpu/ops/GrSmallPathRenderer.cpp | 14 ++++++++------ 8 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h index a12ab0058d..f6d3ef5ef5 100644 --- a/src/gpu/GrGeometryProcessor.h +++ b/src/gpu/GrGeometryProcessor.h @@ -39,6 +39,14 @@ protected: fSampleShading = sampleShading; } + // GPs that need to use either half-float or ubyte colors can just call this to get a correctly + // configured Attribute struct + static Attribute MakeColorAttribute(const char* name, bool wideColor) { + return { name, + wideColor ? kHalf4_GrVertexAttribType : kUByte4_norm_GrVertexAttribType, + kHalf4_GrSLType }; + } + private: bool fWillUseGeoShader; float fSampleShading; diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 0b83c7b2b0..cd98f1d69f 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -120,6 +120,7 @@ private: GrBitmapTextGeoProc::GrBitmapTextGeoProc(const GrShaderCaps& caps, const SkPMColor4f& color, + bool wideColor, const sk_sp* proxies, int numActiveProxies, const GrSamplerState& params, GrMaskFormat format, @@ -140,7 +141,7 @@ GrBitmapTextGeoProc::GrBitmapTextGeoProc(const GrShaderCaps& caps, bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat || kA565_GrMaskFormat == fMaskFormat; if (hasVertexColor) { - fInColor = {"inColor", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType}; + fInColor = MakeColorAttribute("inColor", wideColor); } fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType, @@ -224,6 +225,7 @@ sk_sp GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* return GrBitmapTextGeoProc::Make(*d->caps()->shaderCaps(), SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)), + d->fRandom->nextBool(), proxies, 1, samplerState, format, GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool()); } diff --git a/src/gpu/effects/GrBitmapTextGeoProc.h b/src/gpu/effects/GrBitmapTextGeoProc.h index ca9b796e54..30cd38e7a2 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.h +++ b/src/gpu/effects/GrBitmapTextGeoProc.h @@ -23,13 +23,14 @@ class GrBitmapTextGeoProc : public GrGeometryProcessor { public: static constexpr int kMaxTextures = 4; - static sk_sp Make(const GrShaderCaps& caps, const SkPMColor4f& color, + static sk_sp Make(const GrShaderCaps& caps, + const SkPMColor4f& color, bool wideColor, const sk_sp* proxies, int numActiveProxies, const GrSamplerState& p, GrMaskFormat format, const SkMatrix& localMatrix, bool usesW) { return sk_sp( - new GrBitmapTextGeoProc(caps, color, proxies, numActiveProxies, p, format, + new GrBitmapTextGeoProc(caps, color, wideColor, proxies, numActiveProxies, p, format, localMatrix, usesW)); } @@ -54,7 +55,7 @@ public: GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override; private: - GrBitmapTextGeoProc(const GrShaderCaps&, const SkPMColor4f&, + GrBitmapTextGeoProc(const GrShaderCaps&, const SkPMColor4f&, bool wideColor, const sk_sp* proxies, int numProxies, const GrSamplerState& params, GrMaskFormat format, const SkMatrix& localMatrix, bool usesW); diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 29c7c47b5d..314a984364 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -509,6 +509,7 @@ private: GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(const GrShaderCaps& caps, const SkMatrix& matrix, + bool wideColor, const sk_sp* proxies, int numProxies, const GrSamplerState& params, @@ -520,7 +521,7 @@ GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(const GrShaderCaps& caps, SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; - fInColor = {"inColor", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType}; + fInColor = MakeColorAttribute("inColor", wideColor); fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType, caps.integerSupport() ? kUShort2_GrSLType : kFloat2_GrSLType}; this->setVertexAttributes(&fInPosition, 3); @@ -596,6 +597,7 @@ sk_sp GrDistanceFieldPathGeoProc::TestCreate(GrProcessorTes return GrDistanceFieldPathGeoProc::Make(*d->caps()->shaderCaps(), GrTest::TestMatrix(d->fRandom), + d->fRandom->nextBool(), proxies, 1, samplerState, flags); diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.h b/src/gpu/effects/GrDistanceFieldGeoProc.h index 3529fe07df..386b38a112 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.h +++ b/src/gpu/effects/GrDistanceFieldGeoProc.h @@ -137,11 +137,13 @@ public: /** The local matrix should be identity if local coords are not required by the GrPipeline. */ static sk_sp Make(const GrShaderCaps& caps, const SkMatrix& matrix, + bool wideColor, const sk_sp* proxies, int numActiveProxies, const GrSamplerState& params, uint32_t flags) { return sk_sp( - new GrDistanceFieldPathGeoProc(caps, matrix, proxies, numActiveProxies, params, flags)); + new GrDistanceFieldPathGeoProc(caps, matrix, wideColor, proxies, numActiveProxies, + params, flags)); } ~GrDistanceFieldPathGeoProc() override {} @@ -164,6 +166,7 @@ public: private: GrDistanceFieldPathGeoProc(const GrShaderCaps& caps, const SkMatrix& matrix, + bool wideColor, const sk_sp* proxies, int numActiveProxies, const GrSamplerState&, uint32_t flags); diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp index 7263dfb414..368c6257d4 100644 --- a/src/gpu/ops/GrAtlasTextOp.cpp +++ b/src/gpu/ops/GrAtlasTextOp.cpp @@ -321,8 +321,8 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) { GrSamplerState samplerState = fNeedsGlyphTransform ? GrSamplerState::ClampBilerp() : GrSamplerState::ClampNearest(); flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make( - *target->caps().shaderCaps(), this->color(), proxies, numActiveProxies, samplerState, - maskFormat, localMatrix, vmPerspective); + *target->caps().shaderCaps(), this->color(), false, proxies, numActiveProxies, + samplerState, maskFormat, localMatrix, vmPerspective); } flushInfo.fGlyphsToFlush = 0; diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp index 0c2946c825..5752c8105c 100644 --- a/src/gpu/ops/GrOvalOpFactory.cpp +++ b/src/gpu/ops/GrOvalOpFactory.cpp @@ -32,12 +32,6 @@ namespace { static inline bool circle_stays_circle(const SkMatrix& m) { return m.isSimilarity(); } -static inline GrPrimitiveProcessor::Attribute color_attribute(bool wideColor) { - return { "inColor", - wideColor ? kHalf4_GrVertexAttribType : kUByte4_norm_GrVertexAttribType, - kHalf4_GrSLType }; -} - // Produces TriStrip vertex data for an origin-centered rectangle from [-x, -y] to [x, y] static inline GrVertexWriter::TriStrip origin_centered_tri_strip(float x, float y) { return GrVertexWriter::TriStrip{ -x, -y, x, y }; @@ -74,7 +68,7 @@ public: , fLocalMatrix(localMatrix) , fStroke(stroke) { fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; - fInColor = color_attribute(wideColor); + fInColor = MakeColorAttribute("inColor", wideColor); fInCircleEdge = {"inCircleEdge", kFloat4_GrVertexAttribType, kFloat4_GrSLType}; if (clipPlane) { @@ -266,7 +260,7 @@ public: ButtCapDashedCircleGeometryProcessor(bool wideColor, const SkMatrix& localMatrix) : INHERITED(kButtCapStrokedCircleGeometryProcessor_ClassID), fLocalMatrix(localMatrix) { fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; - fInColor = color_attribute(wideColor); + fInColor = MakeColorAttribute("inColor", wideColor); fInCircleEdge = {"inCircleEdge", kFloat4_GrVertexAttribType, kFloat4_GrSLType}; fInDashParams = {"inDashParams", kFloat4_GrVertexAttribType, kFloat4_GrSLType}; this->setVertexAttributes(&fInPosition, 4); @@ -513,7 +507,7 @@ public: : INHERITED(kEllipseGeometryProcessor_ClassID) , fLocalMatrix(localMatrix) { fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; - fInColor = color_attribute(wideColor); + fInColor = MakeColorAttribute("inColor", wideColor); fInEllipseOffset = {"inEllipseOffset", kFloat2_GrVertexAttribType, kHalf2_GrSLType}; fInEllipseRadii = {"inEllipseRadii", kFloat4_GrVertexAttribType, kHalf4_GrSLType}; this->setVertexAttributes(&fInPosition, 4); @@ -665,7 +659,7 @@ public: , fViewMatrix(viewMatrix) { fStyle = style; fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; - fInColor = color_attribute(wideColor); + fInColor = MakeColorAttribute("inColor", wideColor); fInEllipseOffsets0 = {"inEllipseOffsets0", kFloat2_GrVertexAttribType, kHalf2_GrSLType}; fInEllipseOffsets1 = {"inEllipseOffsets1", kFloat2_GrVertexAttribType, kHalf2_GrSLType}; this->setVertexAttributes(&fInPosition, 4); diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp index 4f902e0879..154d845fbc 100644 --- a/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/src/gpu/ops/GrSmallPathRenderer.cpp @@ -267,6 +267,7 @@ public: fShapeCache = shapeCache; fShapeList = shapeList; fGammaCorrect = gammaCorrect; + fWideColor = !SkPMColor4fFitsInBytes(color); } @@ -351,7 +352,7 @@ private: matrix = &SkMatrix::I(); } flushInfo.fGeometryProcessor = GrDistanceFieldPathGeoProc::Make( - *target->caps().shaderCaps(), *matrix, fAtlas->getProxies(), + *target->caps().shaderCaps(), *matrix, fWideColor, fAtlas->getProxies(), fAtlas->numActivePages(), GrSamplerState::ClampBilerp(), flags); } else { SkMatrix invert; @@ -362,7 +363,7 @@ private: } flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make( - *target->caps().shaderCaps(), this->color(), fAtlas->getProxies(), + *target->caps().shaderCaps(), this->color(), fWideColor, fAtlas->getProxies(), fAtlas->numActivePages(), GrSamplerState::ClampNearest(), kA8_GrMaskFormat, invert, false); } @@ -489,9 +490,8 @@ private: auto uploadTarget = target->deferredUploadTarget(); fAtlas->setLastUseToken(shapeData->fID, uploadTarget->tokenTracker()->nextDrawToken()); - // TODO4F: Preserve float colors - this->writePathVertices(fAtlas, vertices, args.fColor.toBytes_RGBA(), args.fViewMatrix, - shapeData); + this->writePathVertices(fAtlas, vertices, GrVertexColor(args.fColor, fWideColor), + args.fViewMatrix, shapeData); flushInfo.fInstancesToFlush++; } @@ -745,7 +745,7 @@ private: void writePathVertices(GrDrawOpAtlas* atlas, GrVertexWriter& vertices, - GrColor color, + const GrVertexColor& color, const SkMatrix& ctm, const ShapeData* shapeData) const { SkRect translatedBounds(shapeData->fBounds); @@ -844,6 +844,7 @@ private: } fShapes.push_back_n(that->fShapes.count(), that->fShapes.begin()); + fWideColor |= that->fWideColor; return CombineResult::kMerged; } @@ -861,6 +862,7 @@ private: ShapeCache* fShapeCache; ShapeDataList* fShapeList; bool fGammaCorrect; + bool fWideColor; typedef GrMeshDrawOp INHERITED; };