diff options
26 files changed, 599 insertions, 448 deletions
diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp index e60cfdf7b8..92c3a24252 100644 --- a/gm/bigrrectaaeffect.cpp +++ b/gm/bigrrectaaeffect.cpp @@ -13,7 +13,7 @@ #include "SkRRect.h" #include "effects/GrRRectEffect.h" #include "ops/GrDrawOp.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" namespace skiagm { @@ -89,8 +89,8 @@ protected: bounds.offset(SkIntToScalar(x), SkIntToScalar(y)); renderTargetContext->priv().testingOnly_addDrawOp( - GrRectOpFactory::MakeNonAAFill(std::move(grPaint), SkMatrix::I(), - bounds, GrAAType::kNone)); + GrNonAAFillRectOp::Make(std::move(grPaint), SkMatrix::I(), bounds, + nullptr, nullptr, GrAAType::kNone)); } canvas->restore(); x = x + fTestOffsetX; diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp index 39926a98eb..bbfca008bd 100644 --- a/gm/constcolorprocessor.cpp +++ b/gm/constcolorprocessor.cpp @@ -18,7 +18,7 @@ #include "SkGradientShader.h" #include "effects/GrConstColorProcessor.h" #include "ops/GrDrawOp.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" namespace skiagm { /** @@ -110,8 +110,8 @@ protected: grPaint.addColorFragmentProcessor(std::move(fp)); renderTargetContext->priv().testingOnly_addDrawOp( - GrRectOpFactory::MakeNonAAFill(std::move(grPaint), viewMatrix, - renderRect, GrAAType::kNone)); + GrNonAAFillRectOp::Make(std::move(grPaint), viewMatrix, renderRect, + nullptr, nullptr, GrAAType::kNone)); // Draw labels for the input to the processor and the processor to the right of // the test rect. The input label appears above the processor label. diff --git a/gm/rrects.cpp b/gm/rrects.cpp index 3124895a49..23f576b5e9 100644 --- a/gm/rrects.cpp +++ b/gm/rrects.cpp @@ -12,7 +12,7 @@ #include "GrRenderTargetContextPriv.h" #include "effects/GrRRectEffect.h" #include "ops/GrDrawOp.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" #endif #include "SkRRect.h" @@ -117,9 +117,12 @@ protected: bounds.outset(2.f, 2.f); renderTargetContext->priv().testingOnly_addDrawOp( - GrRectOpFactory::MakeNonAAFill(std::move(grPaint), - SkMatrix::I(), bounds, - GrAAType::kNone)); + GrNonAAFillRectOp::Make(std::move(grPaint), + SkMatrix::I(), + bounds, + nullptr, + nullptr, + GrAAType::kNone)); } else { drew = false; } diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp index e54404ef64..d49e059c56 100644 --- a/gm/texturedomaineffect.cpp +++ b/gm/texturedomaineffect.cpp @@ -18,7 +18,7 @@ #include "SkGradientShader.h" #include "effects/GrTextureDomain.h" #include "ops/GrDrawOp.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" namespace skiagm { /** @@ -134,8 +134,8 @@ protected: const SkMatrix viewMatrix = SkMatrix::MakeTrans(x, y); grPaint.addColorFragmentProcessor(std::move(fp)); renderTargetContext->priv().testingOnly_addDrawOp( - GrRectOpFactory::MakeNonAAFill(std::move(grPaint), viewMatrix, - renderRect, GrAAType::kNone)); + GrNonAAFillRectOp::Make(std::move(grPaint), viewMatrix, renderRect, + nullptr, nullptr, GrAAType::kNone)); x += renderRect.width() + kTestPad; } y += renderRect.height() + kTestPad; diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp index c6effed793..eb2e422286 100644 --- a/gm/yuvtorgbeffect.cpp +++ b/gm/yuvtorgbeffect.cpp @@ -19,7 +19,7 @@ #include "SkGradientShader.h" #include "effects/GrYUVEffect.h" #include "ops/GrDrawOp.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" #define YSIZE 8 #define USIZE 4 @@ -133,8 +133,8 @@ protected: SkMatrix viewMatrix; viewMatrix.setTranslate(x, y); renderTargetContext->priv().testingOnly_addDrawOp( - GrRectOpFactory::MakeNonAAFill(std::move(grPaint), viewMatrix, - renderRect, GrAAType::kNone)); + GrNonAAFillRectOp::Make(std::move(grPaint), viewMatrix, renderRect, + nullptr, nullptr, GrAAType::kNone)); } x += renderRect.width() + kTestPad; } @@ -256,8 +256,9 @@ protected: SkMatrix viewMatrix; viewMatrix.setTranslate(x, y); grPaint.addColorFragmentProcessor(fp); - renderTargetContext->priv().testingOnly_addDrawOp(GrRectOpFactory::MakeNonAAFill( - std::move(grPaint), viewMatrix, renderRect, GrAAType::kNone)); + renderTargetContext->priv().testingOnly_addDrawOp( + GrNonAAFillRectOp::Make(std::move(grPaint), viewMatrix, renderRect, nullptr, + nullptr, GrAAType::kNone)); } } } diff --git a/gn/gpu.gni b/gn/gpu.gni index 2a1ed00c75..01d0628a99 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -230,11 +230,13 @@ skia_gpu_sources = [ "$_src/gpu/ops/GrAAConvexPathRenderer.cpp", "$_src/gpu/ops/GrAAConvexPathRenderer.h", "$_src/gpu/ops/GrAAFillRectOp.cpp", + "$_src/gpu/ops/GrAAFillRectOp.h", "$_src/gpu/ops/GrAAHairLinePathRenderer.cpp", "$_src/gpu/ops/GrAAHairLinePathRenderer.h", "$_src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp", "$_src/gpu/ops/GrAALinearizingConvexPathRenderer.h", "$_src/gpu/ops/GrAAStrokeRectOp.cpp", + "$_src/gpu/ops/GrAAStrokeRectOp.h", "$_src/gpu/ops/GrAnalyticRectOp.cpp", "$_src/gpu/ops/GrAnalyticRectOp.h", "$_src/gpu/ops/GrAtlasTextOp.cpp", @@ -262,8 +264,10 @@ skia_gpu_sources = [ "$_src/gpu/ops/GrMeshDrawOp.h", "$_src/gpu/ops/GrMSAAPathRenderer.cpp", "$_src/gpu/ops/GrMSAAPathRenderer.h", + "$_src/gpu/ops/GrNonAAFillRectOp.h", "$_src/gpu/ops/GrNonAAFillRectOp.cpp", "$_src/gpu/ops/GrNonAAStrokeRectOp.cpp", + "$_src/gpu/ops/GrNonAAStrokeRectOp.h", "$_src/gpu/ops/GrLatticeOp.cpp", "$_src/gpu/ops/GrLatticeOp.h", "$_src/gpu/ops/GrOp.cpp", @@ -271,6 +275,7 @@ skia_gpu_sources = [ "$_src/gpu/ops/GrOvalOpFactory.cpp", "$_src/gpu/ops/GrOvalOpFactory.h", "$_src/gpu/ops/GrRectOpFactory.h", + "$_src/gpu/ops/GrRectOpFactory.cpp", "$_src/gpu/ops/GrRegionOp.cpp", "$_src/gpu/ops/GrRegionOp.h", "$_src/gpu/ops/GrSemaphoreOp.cpp", diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 7d752b43c7..0f436f0300 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -34,6 +34,7 @@ #include "ops/GrDrawOp.h" #include "ops/GrDrawVerticesOp.h" #include "ops/GrLatticeOp.h" +#include "ops/GrNonAAFillRectOp.h" #include "ops/GrOp.h" #include "ops/GrOvalOpFactory.h" #include "ops/GrRectOpFactory.h" @@ -284,9 +285,10 @@ void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const GrColor // We don't call drawRect() here to avoid the cropping to the, possibly smaller, // RenderTargetProxy bounds - std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFill( - std::move(paint), SkMatrix::I(), SkRect::Make(rtRect), GrAAType::kNone); - fRenderTargetContext->addDrawOp(GrNoClip(), std::move(op)); + fRenderTargetContext->drawNonAAFilledRect(GrNoClip(), std::move(paint), SkMatrix::I(), + SkRect::Make(rtRect), nullptr, nullptr, nullptr, + GrAAType::kNone); + } else { // This path doesn't handle coalescing of full screen clears b.c. it // has to clear the entire render target - not just the content area. @@ -396,9 +398,8 @@ void GrRenderTargetContext::drawPaint(const GrClip& clip, AutoCheckFlush acf(this->drawingManager()); - std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFillWithLocalMatrix( - std::move(paint), SkMatrix::I(), localMatrix, r, GrAAType::kNone); - this->addDrawOp(clip, std::move(op)); + this->drawNonAAFilledRect(clip, std::move(paint), SkMatrix::I(), r, nullptr, &localMatrix, + nullptr, GrAAType::kNone); } } @@ -407,6 +408,10 @@ static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po point.fY >= rect.fTop && point.fY <= rect.fBottom; } +static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { + return viewMatrix.preservesRightAngles(); +} + // Attempts to crop a rect and optional local rect to the clip boundaries. // Returns false if the draw can be skipped entirely. static bool crop_filled_rect(int width, int height, const GrClip& clip, @@ -474,17 +479,29 @@ bool GrRenderTargetContext::drawFilledRect(const GrClip& clip, } } GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo); - std::unique_ptr<GrDrawOp> op; if (GrAAType::kCoverage == aaType) { - op = GrRectOpFactory::MakeAAFill(std::move(paint), viewMatrix, rect, ss); + // The fill path can handle rotation but not skew. + if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { + SkRect devBoundRect; + viewMatrix.mapRect(&devBoundRect, croppedRect); + std::unique_ptr<GrLegacyMeshDrawOp> op = + GrRectOpFactory::MakeAAFill(paint, viewMatrix, rect, croppedRect, devBoundRect); + if (op) { + GrPipelineBuilder pipelineBuilder(std::move(paint), aaType); + if (ss) { + pipelineBuilder.setUserStencil(ss); + } + this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); + return true; + } + } } else { - op = GrRectOpFactory::MakeNonAAFill(std::move(paint), viewMatrix, croppedRect, aaType, ss); - } - if (!op) { - return false; + this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect, nullptr, nullptr, + ss, aaType); + return true; } - this->addDrawOp(clip, std::move(op)); - return true; + + return false; } void GrRenderTargetContext::drawRect(const GrClip& clip, @@ -574,21 +591,30 @@ void GrRenderTargetContext::drawRect(const GrClip& clip, } } - std::unique_ptr<GrDrawOp> op; + bool snapToPixelCenters = false; + std::unique_ptr<GrLegacyMeshDrawOp> op; + GrColor color = paint.getColor(); GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo); if (GrAAType::kCoverage == aaType) { // The stroke path needs the rect to remain axis aligned (no rotation or skew). if (viewMatrix.rectStaysRect()) { - op = GrRectOpFactory::MakeAAStroke(std::move(paint), viewMatrix, rect, stroke); + op = GrRectOpFactory::MakeAAStroke(color, viewMatrix, rect, stroke); } } else { - op = GrRectOpFactory::MakeNonAAStroke(std::move(paint), viewMatrix, rect, stroke, - aaType); + // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of + // hairline rects. We jam all the vertices to pixel centers to avoid this, but not + // when MSAA is enabled because it can cause ugly artifacts. + snapToPixelCenters = stroke.getStyle() == SkStrokeRec::kHairline_Style && + GrFSAAType::kUnifiedMSAA != fRenderTargetProxy->fsaaType(); + op = GrRectOpFactory::MakeNonAAStroke(color, viewMatrix, rect, stroke, + snapToPixelCenters); } if (op) { - this->addDrawOp(clip, std::move(op)); + GrPipelineBuilder pipelineBuilder(std::move(paint), aaType); + pipelineBuilder.setSnapVerticesToPixelCenters(snapToPixelCenters); + this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); return; } } @@ -694,9 +720,9 @@ void GrRenderTargetContextPriv::stencilRect(const GrClip& clip, GrPaint paint; paint.setXPFactory(GrDisableColorXPFactory::Get()); - std::unique_ptr<GrDrawOp> op = - GrRectOpFactory::MakeNonAAFill(std::move(paint), viewMatrix, rect, aaType, ss); - fRenderTargetContext->addDrawOp(clip, std::move(op)); + + fRenderTargetContext->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, rect, nullptr, + nullptr, ss, aaType); } bool GrRenderTargetContextPriv::drawAndStencilRect(const GrClip& clip, @@ -758,16 +784,16 @@ void GrRenderTargetContext::fillRectToRect(const GrClip& clip, GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo); if (GrAAType::kCoverage != aaType) { - std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFillWithLocalRect( - std::move(paint), viewMatrix, croppedRect, croppedLocalRect, aaType); - this->addDrawOp(clip, std::move(op)); + this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect, + &croppedLocalRect, nullptr, nullptr, aaType); return; } - std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeAAFillWithLocalRect( - std::move(paint), viewMatrix, croppedRect, croppedLocalRect); - if (op) { - this->addDrawOp(clip, std::move(op)); + if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { + std::unique_ptr<GrLegacyMeshDrawOp> op = GrAAFillRectOp::MakeWithLocalRect( + paint.getColor(), viewMatrix, croppedRect, croppedLocalRect); + GrPipelineBuilder pipelineBuilder(std::move(paint), aaType); + this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); return; } @@ -814,16 +840,16 @@ void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip, GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo); if (GrAAType::kCoverage != aaType) { - std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFillWithLocalMatrix( - std::move(paint), viewMatrix, localMatrix, croppedRect, aaType); - this->addDrawOp(clip, std::move(op)); + this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect, nullptr, + &localMatrix, nullptr, aaType); return; } - std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeAAFillWithLocalMatrix( - std::move(paint), viewMatrix, localMatrix, croppedRect); - if (op) { - this->addDrawOp(clip, std::move(op)); + if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { + std::unique_ptr<GrLegacyMeshDrawOp> op = + GrAAFillRectOp::Make(paint.getColor(), viewMatrix, localMatrix, croppedRect); + GrPipelineBuilder pipelineBuilder(std::move(paint), aaType); + this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); return; } @@ -1438,6 +1464,21 @@ void GrRenderTargetContext::prepareForExternalIO() { this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get()); } +void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip, + GrPaint&& paint, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect* localRect, + const SkMatrix* localMatrix, + const GrUserStencilSettings* ss, + GrAAType hwOrNoneAAType) { + SkASSERT(GrAAType::kCoverage != hwOrNoneAAType); + SkASSERT(GrAAType::kNone == hwOrNoneAAType || GrFSAAType::kNone != this->fsaaType()); + std::unique_ptr<GrDrawOp> op = GrNonAAFillRectOp::Make( + std::move(paint), viewMatrix, rect, localRect, localMatrix, hwOrNoneAAType, ss); + this->addDrawOp(clip, std::move(op)); +} + // Can 'path' be drawn as a pair of filled nested rectangles? static bool fills_as_nested_rects(const SkMatrix& viewMatrix, const SkPath& path, SkRect rects[2]) { @@ -1511,13 +1552,13 @@ void GrRenderTargetContext::drawPath(const GrClip& clip, SkRect rects[2]; if (fills_as_nested_rects(viewMatrix, path, rects)) { - std::unique_ptr<GrDrawOp> op = - GrRectOpFactory::MakeAAFillNestedRects(std::move(paint), viewMatrix, rects); - if (!op) { - // A null return indicates that there is nothing to draw in this case. - return; + std::unique_ptr<GrLegacyMeshDrawOp> op = + GrRectOpFactory::MakeAAFillNestedRects(paint.getColor(), viewMatrix, rects); + if (op) { + GrPipelineBuilder pipelineBuilder(std::move(paint), aaType); + this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); } - this->addDrawOp(clip, std::move(op)); + return; } } SkRect ovalRect; diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index c471eacdde..c7940504c9 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -400,6 +400,15 @@ private: const SkRect& rect, const GrUserStencilSettings* ss); + void drawNonAAFilledRect(const GrClip&, + GrPaint&&, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect* localRect, + const SkMatrix* localMatrix, + const GrUserStencilSettings* ss, + GrAAType hwOrNoneAAType); + void internalDrawPath( const GrClip&, GrPaint&&, GrAA, const SkMatrix&, const SkPath&, const GrStyle&); diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index fb66886098..141f35710e 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -6,6 +6,7 @@ */ #include "GrSWMaskHelper.h" + #include "GrCaps.h" #include "GrContext.h" #include "GrContextPriv.h" @@ -14,9 +15,11 @@ #include "GrShape.h" #include "GrSurfaceContext.h" #include "GrTextureProxy.h" -#include "SkDistanceFieldGen.h" #include "ops/GrDrawOp.h" -#include "ops/GrRectOpFactory.h" + +#include "SkDistanceFieldGen.h" + +#include "ops/GrNonAAFillRectOp.h" /* * Convert a boolean operation into a transfer mode code @@ -173,8 +176,7 @@ void GrSWMaskHelper::DrawToTargetWithShapeMask(sk_sp<GrTextureProxy> proxy, paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make( resourceProvider, std::move(proxy), nullptr, maskMatrix, GrSamplerParams::kNone_FilterMode)); - renderTargetContext->addDrawOp(clip, - GrRectOpFactory::MakeNonAAFillWithLocalMatrix( - std::move(paint), SkMatrix::I(), invert, dstRect, - GrAAType::kNone, &userStencilSettings)); + renderTargetContext->addDrawOp( + clip, GrNonAAFillRectOp::Make(std::move(paint), SkMatrix::I(), dstRect, nullptr, + &invert, GrAAType::kNone, &userStencilSettings)); } diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 161b62bdf0..f823e13704 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -12,7 +12,7 @@ #include "GrPipelineBuilder.h" #include "GrResourceProvider.h" #include "GrSWMaskHelper.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" //////////////////////////////////////////////////////////////////////////////// bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { @@ -76,10 +76,9 @@ void GrSoftwarePathRenderer::DrawNonAARect(GrRenderTargetContext* renderTargetCo const SkMatrix& viewMatrix, const SkRect& rect, const SkMatrix& localMatrix) { - renderTargetContext->addDrawOp(clip, - GrRectOpFactory::MakeNonAAFillWithLocalMatrix( - std::move(paint), viewMatrix, localMatrix, rect, - GrAAType::kNone, &userStencilSettings)); + renderTargetContext->addDrawOp( + clip, GrNonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, &localMatrix, + GrAAType::kNone, &userStencilSettings)); } void GrSoftwarePathRenderer::DrawAroundInvPath(GrRenderTargetContext* renderTargetContext, diff --git a/src/gpu/ops/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp index 478c10982a..af5885c34f 100644 --- a/src/gpu/ops/GrAAFillRectOp.cpp +++ b/src/gpu/ops/GrAAFillRectOp.cpp @@ -5,26 +5,21 @@ * found in the LICENSE file. */ +#include "GrAAFillRectOp.h" + #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" #include "GrMeshDrawOp.h" #include "GrOpFlushState.h" -#include "GrRectOpFactory.h" #include "GrResourceKey.h" #include "GrResourceProvider.h" #include "GrTypes.h" #include "SkMatrix.h" #include "SkRect.h" -#include "ops/GrSimpleMeshDrawOpHelper.h" GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); -static inline bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { - return viewMatrix.preservesRightAngles(); -} - -static inline void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx, - SkScalar dy) { +static void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx, SkScalar dy) { pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride); } @@ -158,34 +153,16 @@ static void generate_aa_fill_rect_geometry(intptr_t verts, } } -namespace { - -class AAFillRectOp final : public GrMeshDrawOp { -private: - using Helper = GrSimpleMeshDrawOpHelperWithStencil; - +class AAFillRectOp final : public GrLegacyMeshDrawOp { public: DEFINE_OP_CLASS_ID - static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& devRect, - const SkMatrix* localMatrix, - const GrUserStencilSettings* stencil) { - SkASSERT(view_matrix_ok_for_aa_fill_rect(viewMatrix)); - return Helper::FactoryHelper<AAFillRectOp>(std::move(paint), viewMatrix, rect, devRect, - localMatrix, stencil); - } - - AAFillRectOp(const Helper::MakeArgs& helperArgs, - GrColor color, + AAFillRectOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, const SkRect& devRect, - const SkMatrix* localMatrix, - const GrUserStencilSettings* stencil) - : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage, stencil) { + const SkMatrix* localMatrix) + : INHERITED(ClassID()) { if (localMatrix) { void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo)); new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix); @@ -212,29 +189,38 @@ public: info->color(), rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); info = this->next(info); } + str.append(DumpPipelineInfo(*this->pipeline())); return str; } - FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); } - - bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override { - GrColor color = this->first()->color(); - bool result = fHelper.xpRequiresDstTexture( - caps, clip, GrProcessorAnalysisCoverage::kSingleChannel, &color); - this->first()->setColor(color); - return result; + void applyPipelineOptimizations(const PipelineOptimizations& optimizations) override { + GrColor color; + if (optimizations.getOverrideColorIfSet(&color)) { + this->first()->setColor(color); + } + fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage(); + fNeedsLocalCoords = optimizations.readsLocalCoords(); } private: + void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color, + GrProcessorAnalysisCoverage* coverage) const override { + color->setToConstant(this->first()->color()); + *coverage = GrProcessorAnalysisCoverage::kSingleChannel; + } + void onPrepareDraws(Target* target) const override { using namespace GrDefaultGeoProcFactory; Color color(Color::kPremulGrColorAttribute_Type); - Coverage::Type coverageType = fHelper.compatibleWithAlphaAsCoverage() - ? Coverage::kSolid_Type - : Coverage::kAttribute_Type; - LocalCoords lc = fHelper.usesLocalCoords() ? LocalCoords::kHasExplicit_Type - : LocalCoords::kUnused_Type; + Coverage::Type coverageType; + if (fCanTweakAlphaForCoverage) { + coverageType = Coverage::kSolid_Type; + } else { + coverageType = Coverage::kAttribute_Type; + } + LocalCoords lc = + fNeedsLocalCoords ? LocalCoords::kHasExplicit_Type : LocalCoords::kUnused_Type; sk_sp<GrGeometryProcessor> gp = GrDefaultGeoProcFactory::Make(color, coverageType, lc, SkMatrix::I()); if (!gp) { @@ -259,7 +245,7 @@ private: for (int i = 0; i < fRectCnt; i++) { intptr_t verts = reinterpret_cast<intptr_t>(vertices) + i * kVertsPerAAFillRect * vertexStride; - if (fHelper.usesLocalCoords()) { + if (fNeedsLocalCoords) { if (info->hasLocalMatrix()) { localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(info)->localMatrix(); } else { @@ -267,19 +253,28 @@ private: } } generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), info->viewMatrix(), - info->rect(), info->devRect(), - fHelper.compatibleWithAlphaAsCoverage(), localMatrix); + info->rect(), info->devRect(), fCanTweakAlphaForCoverage, + localMatrix); info = this->next(info); } - helper.recordDraw(target, gp.get(), fHelper.makePipeline(target)); + helper.recordDraw(target, gp.get(), this->pipeline()); } bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { AAFillRectOp* that = t->cast<AAFillRectOp>(); - if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { + if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), + that->bounds(), caps)) { return false; } + SkASSERT(fNeedsLocalCoords == that->fNeedsLocalCoords); + + // In the event of two ops, one who can tweak, one who cannot, we just fall back to not + // tweaking. + if (fCanTweakAlphaForCoverage && !that->fCanTweakAlphaForCoverage) { + fCanTweakAlphaForCoverage = false; + } + fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin()); fRectCnt += that->fRectCnt; this->joinBounds(*that); @@ -338,63 +333,55 @@ private: return reinterpret_cast<const RectInfo*>(next); } + bool fNeedsLocalCoords; + bool fCanTweakAlphaForCoverage; SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData; - Helper fHelper; int fRectCnt; - typedef GrMeshDrawOp INHERITED; + typedef GrLegacyMeshDrawOp INHERITED; }; -} // anonymous namespace +namespace GrAAFillRectOp { -namespace GrRectOpFactory { - -std::unique_ptr<GrDrawOp> MakeAAFill(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkRect& rect, const GrUserStencilSettings* stencil) { - if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) { - return nullptr; - } - SkRect devRect; - if (!viewMatrix.mapRect(&devRect, rect)) { - return nullptr; - } - return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, nullptr, stencil); +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect& devRect) { + return std::unique_ptr<GrLegacyMeshDrawOp>( + new AAFillRectOp(color, viewMatrix, rect, devRect, nullptr)); } -std::unique_ptr<GrDrawOp> MakeAAFillWithDevRect(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkRect& rect, const SkRect& devRect) { - if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) { - return nullptr; - } - return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, nullptr, nullptr); +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkMatrix& localMatrix, + const SkRect& rect, + const SkRect& devRect) { + return std::unique_ptr<GrLegacyMeshDrawOp>( + new AAFillRectOp(color, viewMatrix, rect, devRect, &localMatrix)); } -std::unique_ptr<GrDrawOp> MakeAAFillWithLocalMatrix(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, - const SkRect& rect) { - if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) { - return nullptr; - } +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkMatrix& localMatrix, + const SkRect& rect) { SkRect devRect; viewMatrix.mapRect(&devRect, rect); - return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, &localMatrix, nullptr); + return Make(color, viewMatrix, localMatrix, rect, devRect); } -std::unique_ptr<GrDrawOp> MakeAAFillWithLocalRect(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkRect& rect, const SkRect& localRect) { - if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) { - return nullptr; - } +std::unique_ptr<GrLegacyMeshDrawOp> MakeWithLocalRect(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect& localRect) { SkRect devRect; viewMatrix.mapRect(&devRect, rect); SkMatrix localMatrix; if (!localMatrix.setRectToRect(rect, localRect, SkMatrix::kFill_ScaleToFit)) { return nullptr; } - return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, &localMatrix, nullptr); + return Make(color, viewMatrix, localMatrix, rect, devRect); } - -} // namespace GrRectOpFactory +}; /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -402,22 +389,21 @@ std::unique_ptr<GrDrawOp> MakeAAFillWithLocalRect(GrPaint&& paint, const SkMatri #include "GrDrawOpTest.h" -GR_DRAW_OP_TEST_DEFINE(AAFillRectOp) { - SkMatrix viewMatrix; - do { - viewMatrix = GrTest::TestMatrixInvertible(random); - } while (!view_matrix_ok_for_aa_fill_rect(viewMatrix)); +GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAFillRectOp) { + GrColor color = GrRandomColor(random); + SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); SkRect rect = GrTest::TestRect(random); - SkRect devRect; - viewMatrix.mapRect(&devRect, rect); - const SkMatrix* localMatrix = nullptr; - SkMatrix m; - if (random->nextBool()) { - m = GrTest::TestMatrix(random); - } - const GrUserStencilSettings* stencil = - random->nextBool() ? nullptr : GrGetRandomStencil(random, context); - return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, localMatrix, stencil); + SkRect devRect = GrTest::TestRect(random); + return GrAAFillRectOp::Make(color, viewMatrix, rect, devRect); +} + +GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAFillRectOpLocalMatrix) { + GrColor color = GrRandomColor(random); + SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); + SkMatrix localMatrix = GrTest::TestMatrix(random); + SkRect rect = GrTest::TestRect(random); + SkRect devRect = GrTest::TestRect(random); + return GrAAFillRectOp::Make(color, viewMatrix, localMatrix, rect, devRect); } #endif diff --git a/src/gpu/ops/GrAAFillRectOp.h b/src/gpu/ops/GrAAFillRectOp.h new file mode 100644 index 0000000000..7d977164fc --- /dev/null +++ b/src/gpu/ops/GrAAFillRectOp.h @@ -0,0 +1,41 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrAAFillRectOp_DEFINED +#define GrAAFillRectOp_DEFINED + +#include "GrColor.h" +#include "SkRefCnt.h" + +class GrLegacyMeshDrawOp; +class SkMatrix; +struct SkRect; + +namespace GrAAFillRectOp { +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect& devRect); + +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkMatrix& localMatrix, + const SkRect& rect); + +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkMatrix& localMatrix, + const SkRect& rect, + const SkRect& devRect); + +std::unique_ptr<GrLegacyMeshDrawOp> MakeWithLocalRect(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect& localRect); +}; + +#endif diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp index 82b4ec13fa..7af6c3e58e 100644 --- a/src/gpu/ops/GrAAStrokeRectOp.cpp +++ b/src/gpu/ops/GrAAStrokeRectOp.cpp @@ -5,12 +5,12 @@ * found in the LICENSE file. */ +#include "GrAAStrokeRectOp.h" + #include "GrDefaultGeoProcFactory.h" #include "GrOpFlushState.h" -#include "GrRectOpFactory.h" #include "GrResourceKey.h" #include "GrResourceProvider.h" -#include "GrSimpleMeshDrawOpHelper.h" #include "SkStrokeRec.h" GR_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey); @@ -110,26 +110,13 @@ static sk_sp<GrGeometryProcessor> create_stroke_rect_gp(bool tweakAlphaForCovera viewMatrix); } -namespace { - -class AAStrokeRectOp final : public GrMeshDrawOp { -private: - using Helper = GrSimpleMeshDrawOpHelper; - +class AAStrokeRectOp final : public GrLegacyMeshDrawOp { public: DEFINE_OP_CLASS_ID - static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkRect& devOutside, const SkRect& devInside) { - return Helper::FactoryHelper<AAStrokeRectOp>(std::move(paint), viewMatrix, devOutside, - devInside); - } - - AAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix, - const SkRect& devOutside, const SkRect& devInside) - : INHERITED(ClassID()) - , fHelper(helperArgs, GrAAType::kCoverage) - , fViewMatrix(viewMatrix) { + AAStrokeRectOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& devOutside, + const SkRect& devInside) + : INHERITED(ClassID()), fViewMatrix(viewMatrix) { SkASSERT(!devOutside.isEmpty()); SkASSERT(!devInside.isEmpty()); @@ -138,35 +125,30 @@ public: fMiterStroke = true; } - static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkRect& rect, const SkStrokeRec& stroke) { + static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, + const SkRect& rect, const SkStrokeRec& stroke) { bool isMiter; if (!allowed_stroke(stroke, &isMiter)) { return nullptr; } - return Helper::FactoryHelper<AAStrokeRectOp>(std::move(paint), viewMatrix, rect, stroke, - isMiter); - } - AAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix, - const SkRect& rect, const SkStrokeRec& stroke, bool isMiter) - : INHERITED(ClassID()) - , fHelper(helperArgs, GrAAType::kCoverage) - , fViewMatrix(viewMatrix) { - fMiterStroke = isMiter; - RectInfo& info = fRects.push_back(); + AAStrokeRectOp* op = new AAStrokeRectOp(); + op->fMiterStroke = isMiter; + RectInfo& info = op->fRects.push_back(); compute_rects(&info.fDevOutside, &info.fDevOutsideAssist, &info.fDevInside, &info.fDegenerate, viewMatrix, rect, stroke.getWidth(), isMiter); info.fColor = color; if (isMiter) { - this->setBounds(info.fDevOutside, HasAABloat::kYes, IsZeroArea::kNo); + op->setBounds(info.fDevOutside, HasAABloat::kYes, IsZeroArea::kNo); } else { // The outer polygon of the bevel stroke is an octagon specified by the points of a // pair of overlapping rectangles where one is wide and the other is narrow. SkRect bounds = info.fDevOutside; bounds.joinPossiblyEmptyRect(info.fDevOutsideAssist); - this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo); + op->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo); } + op->fViewMatrix = viewMatrix; + return std::unique_ptr<GrLegacyMeshDrawOp>(op); } const char* name() const override { return "AAStrokeRect"; } @@ -184,18 +166,20 @@ public: info.fDevOutsideAssist.fBottom, info.fDevInside.fLeft, info.fDevInside.fTop, info.fDevInside.fRight, info.fDevInside.fBottom, info.fDegenerate); } + string.append(DumpPipelineInfo(*this->pipeline())); string.append(INHERITED::dumpInfo()); return string; } - FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); } +private: + AAStrokeRectOp() : INHERITED(ClassID()) {} - bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override { - return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kSingleChannel, - &fRects.back().fColor); + void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color, + GrProcessorAnalysisCoverage* coverage) const override { + color->setToConstant(fRects[0].fColor); + *coverage = GrProcessorAnalysisCoverage::kSingleChannel; } - -private: + void applyPipelineOptimizations(const PipelineOptimizations&) override; void onPrepareDraws(Target*) const override; static const int kMiterIndexCnt = 3 * 24; @@ -208,6 +192,8 @@ private: static const GrBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider, bool miterStroke); + bool usesLocalCoords() const { return fUsesLocalCoords; } + bool canTweakAlphaForCoverage() const { return fCanTweakAlphaForCoverage; } const SkMatrix& viewMatrix() const { return fViewMatrix; } bool miterStroke() const { return fMiterStroke; } @@ -235,20 +221,29 @@ private: bool fDegenerate; }; - Helper fHelper; SkSTArray<1, RectInfo, true> fRects; + bool fUsesLocalCoords; + bool fCanTweakAlphaForCoverage; SkMatrix fViewMatrix; bool fMiterStroke; - typedef GrMeshDrawOp INHERITED; + typedef GrLegacyMeshDrawOp INHERITED; }; -} // anonymous namespace +void AAStrokeRectOp::applyPipelineOptimizations(const PipelineOptimizations& optimizations) { + optimizations.getOverrideColorIfSet(&fRects[0].fColor); + + fUsesLocalCoords = optimizations.readsLocalCoords(); + fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage(); + fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage(); +} void AAStrokeRectOp::onPrepareDraws(Target* target) const { - sk_sp<GrGeometryProcessor> gp(create_stroke_rect_gp(fHelper.compatibleWithAlphaAsCoverage(), + bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); + + sk_sp<GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlphaForCoverage, this->viewMatrix(), - fHelper.usesLocalCoords())); + this->usesLocalCoords())); if (!gp) { SkDebugf("Couldn't create GrGeometryProcessor\n"); return; @@ -256,7 +251,7 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) const { size_t vertexStride = gp->getVertexStride(); - SkASSERT(fHelper.compatibleWithAlphaAsCoverage() + SkASSERT(canTweakAlphaForCoverage ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); int innerVertexNum = 4; @@ -289,9 +284,9 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) const { info.fDevInside, fMiterStroke, info.fDegenerate, - fHelper.compatibleWithAlphaAsCoverage()); + canTweakAlphaForCoverage); } - helper.recordDraw(target, gp.get(), fHelper.makePipeline(target)); + helper.recordDraw(target, gp.get(), this->pipeline()); } const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvider, @@ -391,7 +386,8 @@ const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvi bool AAStrokeRectOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { AAStrokeRectOp* that = t->cast<AAStrokeRectOp>(); - if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { + if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), + that->bounds(), caps)) { return false; } @@ -401,11 +397,18 @@ bool AAStrokeRectOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { } // We apply the viewmatrix to the rect points on the cpu. However, if the pipeline uses - // local coords then we won't be able to combine. TODO: Upload local coords as an attribute. - if (fHelper.usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { + // local coords then we won't be able to combine. We could actually upload the viewmatrix + // using vertex attributes in these cases, but haven't investigated that + if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { return false; } + // In the event of two ops, one who can tweak, one who cannot, we just fall back to not + // tweaking. + if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) { + fCanTweakAlphaForCoverage = false; + } + fRects.push_back_n(that->fRects.count(), that->fRects.begin()); this->joinBounds(*that); return true; @@ -566,35 +569,23 @@ void AAStrokeRectOp::generateAAStrokeRectGeometry(void* vertices, } } -namespace GrRectOpFactory { +namespace GrAAStrokeRectOp { -std::unique_ptr<GrDrawOp> MakeAAFillNestedRects(GrPaint&& paint, - const SkMatrix& viewMatrix, - const SkRect rects[2]) { - SkASSERT(viewMatrix.rectStaysRect()); - SkASSERT(!rects[0].isEmpty() && !rects[1].isEmpty()); - - SkRect devOutside, devInside; - viewMatrix.mapRect(&devOutside, rects[0]); - viewMatrix.mapRect(&devInside, rects[1]); - if (devInside.isEmpty()) { - if (devOutside.isEmpty()) { - return nullptr; - } - return MakeAAFillWithDevRect(std::move(paint), viewMatrix, rects[0], devOutside); - } - - return AAStrokeRectOp::Make(std::move(paint), viewMatrix, devOutside, devInside); +std::unique_ptr<GrLegacyMeshDrawOp> MakeFillBetweenRects(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& devOutside, + const SkRect& devInside) { + return std::unique_ptr<GrLegacyMeshDrawOp>( + new AAStrokeRectOp(color, viewMatrix, devOutside, devInside)); } -std::unique_ptr<GrDrawOp> MakeAAStroke(GrPaint&& paint, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkStrokeRec& stroke) { - return AAStrokeRectOp::Make(std::move(paint), viewMatrix, rect, stroke); +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke) { + return AAStrokeRectOp::Make(color, viewMatrix, rect, stroke); +} } - -} // namespace GrRectOpFactory /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -602,7 +593,7 @@ std::unique_ptr<GrDrawOp> MakeAAStroke(GrPaint&& paint, #include "GrDrawOpTest.h" -GR_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) { +GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) { bool miterStroke = random->nextBool(); // Create either a empty rect or a non-empty rect. @@ -611,12 +602,14 @@ GR_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) { SkScalar minDim = SkMinScalar(rect.width(), rect.height()); SkScalar strokeWidth = random->nextUScalar1() * minDim; + GrColor color = GrRandomColor(random); + SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); rec.setStrokeStyle(strokeWidth); rec.setStrokeParams(SkPaint::kButt_Cap, miterStroke ? SkPaint::kMiter_Join : SkPaint::kBevel_Join, 1.f); SkMatrix matrix = GrTest::TestMatrixRectStaysRect(random); - return GrRectOpFactory::MakeAAStroke(std::move(paint), matrix, rect, rec); + return GrAAStrokeRectOp::Make(color, matrix, rect, rec); } #endif diff --git a/src/gpu/ops/GrAAStrokeRectOp.h b/src/gpu/ops/GrAAStrokeRectOp.h new file mode 100644 index 0000000000..074f8e00e9 --- /dev/null +++ b/src/gpu/ops/GrAAStrokeRectOp.h @@ -0,0 +1,32 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrAAStrokeRectOp_DEFINED +#define GrAAStrokeRectOp_DEFINED + +#include "GrColor.h" +#include "SkRefCnt.h" + +class GrLegacyMeshDrawOp; +class SkMatrix; +struct SkRect; +class SkStrokeRec; + +namespace GrAAStrokeRectOp { + +std::unique_ptr<GrLegacyMeshDrawOp> MakeFillBetweenRects(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& devOutside, + const SkRect& devInside); + +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke); +} + +#endif diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index c712a9c6bc..bc5702b393 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -6,6 +6,7 @@ */ #include "GrDefaultPathRenderer.h" + #include "GrContext.h" #include "GrDefaultGeoProcFactory.h" #include "GrDrawOpTest.h" @@ -19,8 +20,9 @@ #include "SkStrokeRec.h" #include "SkTLazy.h" #include "SkTraceEvent.h" + #include "ops/GrMeshDrawOp.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" GrDefaultPathRenderer::GrDefaultPathRenderer() { } @@ -520,8 +522,8 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget viewMatrix; renderTargetContext->addDrawOp( clip, - GrRectOpFactory::MakeNonAAFillWithLocalMatrix( - std::move(paint), viewM, localMatrix, bounds, aaType, passes[p])); + GrNonAAFillRectOp::Make(std::move(paint), viewM, bounds, nullptr, &localMatrix, + aaType, passes[p])); } else { std::unique_ptr<GrLegacyMeshDrawOp> op = DefaultPathOp::Make(paint.getColor(), path, srcSpaceTol, newCoverage, diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp index f49c8cd586..ef64ecfe7d 100644 --- a/src/gpu/ops/GrMSAAPathRenderer.cpp +++ b/src/gpu/ops/GrMSAAPathRenderer.cpp @@ -6,6 +6,7 @@ */ #include "GrMSAAPathRenderer.h" + #include "GrAuditTrail.h" #include "GrClip.h" #include "GrDefaultGeoProcFactory.h" @@ -25,7 +26,7 @@ #include "glsl/GrGLSLUtil.h" #include "glsl/GrGLSLVertexShaderBuilder.h" #include "ops/GrMeshDrawOp.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" static const float kTolerance = 0.5f; @@ -666,8 +667,8 @@ bool GrMSAAPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetCon (reverse && viewMatrix.hasPerspective()) ? SkMatrix::I() : viewMatrix; renderTargetContext->addDrawOp( clip, - GrRectOpFactory::MakeNonAAFillWithLocalMatrix(std::move(paint), viewM, localMatrix, - bounds, aaType, passes[1])); + GrNonAAFillRectOp::Make(std::move(paint), viewM, bounds, nullptr, &localMatrix, + aaType, passes[1])); } return true; } diff --git a/src/gpu/ops/GrNonAAFillRectOp.cpp b/src/gpu/ops/GrNonAAFillRectOp.cpp index c30f4a198c..defc7907b9 100644 --- a/src/gpu/ops/GrNonAAFillRectOp.cpp +++ b/src/gpu/ops/GrNonAAFillRectOp.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "GrNonAAFillRectOp.h" #include "GrAppliedClip.h" #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" @@ -13,7 +14,6 @@ #include "GrOpFlushState.h" #include "GrPrimitiveProcessor.h" #include "GrQuad.h" -#include "GrRectOpFactory.h" #include "GrResourceProvider.h" #include "GrSimpleMeshDrawOpHelper.h" #include "SkMatrixPriv.h" @@ -358,45 +358,25 @@ private: } // anonymous namespace -namespace GrRectOpFactory { - -std::unique_ptr<GrDrawOp> MakeNonAAFill(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkRect& rect, GrAAType aaType, - const GrUserStencilSettings* stencilSettings) { - if (viewMatrix.hasPerspective()) { - return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, nullptr, - nullptr, aaType, stencilSettings); - } else { - return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, nullptr, aaType, - stencilSettings); - } -} - -std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix( - GrPaint&& paint, const SkMatrix& viewMatrix, const SkMatrix& localMatrix, - const SkRect& rect, GrAAType aaType, const GrUserStencilSettings* stencilSettings) { - if (viewMatrix.hasPerspective() || localMatrix.hasPerspective()) { - return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, nullptr, - &localMatrix, aaType, stencilSettings); - } else { - return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, nullptr, &localMatrix, +namespace GrNonAAFillRectOp { + +std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect* localRect, + const SkMatrix* localMatrix, + GrAAType aaType, + const GrUserStencilSettings* stencilSettings) { + if (!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective())) { + return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, localRect, localMatrix, aaType, stencilSettings); - } -} - -std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkRect& rect, const SkRect& localRect, - GrAAType aaType) { - if (viewMatrix.hasPerspective()) { - return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, &localRect, - nullptr, aaType, nullptr); } else { - return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, &localRect, nullptr, - aaType, nullptr); + return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, localRect, + localMatrix, aaType, stencilSettings); } } -} // namespace GrRectOpFactory +}; // namespace GrNonAAFillRectOp /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -405,17 +385,14 @@ GR_DRAW_OP_TEST_DEFINE(NonAAFillRectOp) { SkRect localRect = GrTest::TestRect(random); SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); SkMatrix localMatrix = GrTest::TestMatrix(random); + bool hasLocalRect = random->nextBool(); + bool hasLocalMatrix = random->nextBool(); const GrUserStencilSettings* stencil = GrGetRandomStencil(random, context); GrAAType aaType = GrAAType::kNone; if (fsaaType == GrFSAAType::kUnifiedMSAA) { aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone; } - const SkRect* lr = random->nextBool() ? &localRect : nullptr; - const SkMatrix* lm = random->nextBool() ? &localMatrix : nullptr; - if (viewMatrix.hasPerspective() || (lm && lm->hasPerspective())) { - return NonAAFillRectPerspectiveOp::Make(std::move(paint), viewMatrix, rect, lr, lm, aaType, - stencil); - } else { - return NonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, lr, lm, aaType, stencil); - } + return GrNonAAFillRectOp::Make(std::move(paint), viewMatrix, rect, + hasLocalRect ? &localRect : nullptr, + hasLocalMatrix ? &localMatrix : nullptr, aaType, stencil); } diff --git a/src/gpu/ops/GrNonAAFillRectOp.h b/src/gpu/ops/GrNonAAFillRectOp.h new file mode 100644 index 0000000000..70dd8fdcb5 --- /dev/null +++ b/src/gpu/ops/GrNonAAFillRectOp.h @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrNonAAFillRectOp_DEFINED +#define GrNonAAFillRectOp_DEFINED + +#include <memory> +#include "GrColor.h" +#include "GrDrawOp.h" + +class GrPaint; +class SkMatrix; +struct SkRect; +struct GrUserStencilSettings; +enum class GrAAType : unsigned; + +namespace GrNonAAFillRectOp { +std::unique_ptr<GrDrawOp> Make(GrPaint&&, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect* localRect, + const SkMatrix* localMatrix, + GrAAType, + const GrUserStencilSettings* = nullptr); +}; + +#endif diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.cpp b/src/gpu/ops/GrNonAAStrokeRectOp.cpp index 4177b6526e..94dc373fc6 100644 --- a/src/gpu/ops/GrNonAAStrokeRectOp.cpp +++ b/src/gpu/ops/GrNonAAStrokeRectOp.cpp @@ -5,15 +5,15 @@ * found in the LICENSE file. */ +#include "GrNonAAStrokeRectOp.h" + #include "GrColor.h" #include "GrDefaultGeoProcFactory.h" #include "GrDrawOpTest.h" #include "GrMeshDrawOp.h" #include "GrOpFlushState.h" -#include "GrRectOpFactory.h" -#include "GrSimpleMeshDrawOpHelper.h" -#include "SkRandom.h" #include "SkStrokeRec.h" +#include "SkRandom.h" /* create a triangle strip that strokes the specified rect. There are 8 unique vertices, but we repeat the last 2 to close up. Alternatively we @@ -46,12 +46,7 @@ inline static bool allowed_stroke(const SkStrokeRec& stroke) { (stroke.getJoin() == SkPaint::kMiter_Join && stroke.getMiter() > SK_ScalarSqrt2); } -namespace { - -class NonAAStrokeRectOp final : public GrMeshDrawOp { -private: - using Helper = GrSimpleMeshDrawOpHelper; - +class NonAAStrokeRectOp final : public GrLegacyMeshDrawOp { public: DEFINE_OP_CLASS_ID @@ -63,44 +58,31 @@ public: "Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], " "StrokeWidth: %.2f\n", fColor, fRect.fLeft, fRect.fTop, fRect.fRight, fRect.fBottom, fStrokeWidth); + string.append(DumpPipelineInfo(*this->pipeline())); string.append(INHERITED::dumpInfo()); return string; } - static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix, - const SkRect& rect, const SkStrokeRec& stroke, - GrAAType aaType) { + static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, + const SkRect& rect, const SkStrokeRec& stroke, + bool snapToPixelCenters) { if (!allowed_stroke(stroke)) { return nullptr; } - Helper::Flags flags = Helper::Flags::kNone; - // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of - // hairline rects. We jam all the vertices to pixel centers to avoid this, but not - // when MSAA is enabled because it can cause ugly artifacts. - if (stroke.getStyle() == SkStrokeRec::kHairline_Style && aaType != GrAAType::kMSAA) { - flags |= Helper::Flags::kSnapVerticesToPixelCenters; - } - return Helper::FactoryHelper<NonAAStrokeRectOp>(std::move(paint), flags, viewMatrix, rect, - stroke, aaType); - } - - NonAAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, Helper::Flags flags, - const SkMatrix& viewMatrix, const SkRect& rect, const SkStrokeRec& stroke, - GrAAType aaType) - : INHERITED(ClassID()), fHelper(helperArgs, aaType, flags) { - fColor = color; - fViewMatrix = viewMatrix; - fRect = rect; + NonAAStrokeRectOp* op = new NonAAStrokeRectOp(); + op->fColor = color; + op->fViewMatrix = viewMatrix; + op->fRect = rect; // Sort the rect for hairlines - fRect.sort(); - fStrokeWidth = stroke.getWidth(); + op->fRect.sort(); + op->fStrokeWidth = stroke.getWidth(); - SkScalar rad = SkScalarHalf(fStrokeWidth); + SkScalar rad = SkScalarHalf(op->fStrokeWidth); SkRect bounds = rect; bounds.outset(rad, rad); // If our caller snaps to pixel centers then we have to round out the bounds - if (flags & Helper::Flags::kSnapVerticesToPixelCenters) { + if (snapToPixelCenters) { viewMatrix.mapRect(&bounds); // We want to be consistent with how we snap non-aa lines. To match what we do in // GrGLSLVertexShaderBuilder, we first floor all the vertex values and then add half a @@ -110,27 +92,28 @@ public: SkScalarFloorToScalar(bounds.fRight), SkScalarFloorToScalar(bounds.fBottom)); bounds.offset(0.5f, 0.5f); - this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); + op->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo); } else { - this->setTransformedBounds(bounds, fViewMatrix, HasAABloat::kNo, IsZeroArea::kNo); + op->setTransformedBounds(bounds, op->fViewMatrix, HasAABloat::kNo, IsZeroArea::kNo); } + return std::unique_ptr<GrLegacyMeshDrawOp>(op); } - FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); } +private: + NonAAStrokeRectOp() : INHERITED(ClassID()) {} - bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override { - bool result = fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, - &fColor); - return result; + void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color, + GrProcessorAnalysisCoverage* coverage) const override { + color->setToConstant(fColor); + *coverage = GrProcessorAnalysisCoverage::kNone; } -private: void onPrepareDraws(Target* target) const override { sk_sp<GrGeometryProcessor> gp; { using namespace GrDefaultGeoProcFactory; Color color(fColor); - LocalCoords::Type localCoordsType = fHelper.usesLocalCoords() + LocalCoords::Type localCoordsType = fNeedsLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type; gp = GrDefaultGeoProcFactory::Make(color, Coverage::kSolid_Type, localCoordsType, @@ -176,7 +159,12 @@ private: GrMesh mesh(primType); mesh.setNonIndexedNonInstanced(vertexCount); mesh.setVertexData(vertexBuffer, firstVertex); - target->draw(gp.get(), fHelper.makePipeline(target), mesh); + target->draw(gp.get(), this->pipeline(), mesh); + } + + void applyPipelineOptimizations(const PipelineOptimizations& optimizations) override { + optimizations.getOverrideColorIfSet(&fColor); + fNeedsLocalCoords = optimizations.readsLocalCoords(); } bool onCombineIfPossible(GrOp* t, const GrCaps&) override { @@ -185,46 +173,42 @@ private: return false; } - Helper fHelper; GrColor fColor; SkMatrix fViewMatrix; SkRect fRect; SkScalar fStrokeWidth; + bool fNeedsLocalCoords; const static int kVertsPerHairlineRect = 5; const static int kVertsPerStrokeRect = 10; - typedef GrMeshDrawOp INHERITED; + typedef GrLegacyMeshDrawOp INHERITED; }; -} // anonymous namespace +namespace GrNonAAStrokeRectOp { -namespace GrRectOpFactory { -std::unique_ptr<GrDrawOp> MakeNonAAStroke(GrPaint&& paint, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkStrokeRec& stroke, - GrAAType aaType) { - return NonAAStrokeRectOp::Make(std::move(paint), viewMatrix, rect, stroke, aaType); +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke, + bool snapToPixelCenters) { + return NonAAStrokeRectOp::Make(color, viewMatrix, rect, stroke, snapToPixelCenters); +} } -} // namespace GrRectOpFactory #if GR_TEST_UTILS -GR_DRAW_OP_TEST_DEFINE(NonAAStrokeRectOp) { +GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(NonAAStrokeRectOp) { SkMatrix viewMatrix = GrTest::TestMatrix(random); + GrColor color = GrRandomColor(random); SkRect rect = GrTest::TestRect(random); SkScalar strokeWidth = random->nextBool() ? 0.0f : 2.0f; - SkPaint strokePaint; - strokePaint.setStrokeWidth(strokeWidth); - strokePaint.setStyle(SkPaint::kStroke_Style); - strokePaint.setStrokeJoin(SkPaint::kMiter_Join); - SkStrokeRec strokeRec(strokePaint); - GrAAType aaType = GrAAType::kNone; - if (fsaaType == GrFSAAType::kUnifiedMSAA) { - aaType = random->nextBool() ? GrAAType::kMSAA : GrAAType::kNone; - } - return NonAAStrokeRectOp::Make(std::move(paint), viewMatrix, rect, strokeRec, aaType); + SkPaint paint; + paint.setStrokeWidth(strokeWidth); + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeJoin(SkPaint::kMiter_Join); + SkStrokeRec strokeRec(paint); + return GrNonAAStrokeRectOp::Make(color, viewMatrix, rect, strokeRec, random->nextBool()); } #endif diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.h b/src/gpu/ops/GrNonAAStrokeRectOp.h new file mode 100644 index 0000000000..4071cfd2a9 --- /dev/null +++ b/src/gpu/ops/GrNonAAStrokeRectOp.h @@ -0,0 +1,28 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrNonAAStrokeRectOp_DEFINED +#define GrNonAAStrokeRectOp_DEFINED + +#include "GrColor.h" +#include "SkRefCnt.h" + +class GrLegacyMeshDrawOp; +struct SkRect; +class SkStrokeRec; +class SkMatrix; + +namespace GrNonAAStrokeRectOp { + +std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec&, + bool snapToPixelCenters); +} + +#endif diff --git a/src/gpu/ops/GrRectOpFactory.cpp b/src/gpu/ops/GrRectOpFactory.cpp new file mode 100644 index 0000000000..45e2053f8d --- /dev/null +++ b/src/gpu/ops/GrRectOpFactory.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrRectOpFactory.h" + +#include "GrAAStrokeRectOp.h" +#include "GrMeshDrawOp.h" +#include "SkStrokeRec.h" + +namespace GrRectOpFactory { + +std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFillNestedRects(GrColor color, + const SkMatrix& viewMatrix, + const SkRect rects[2]) { + SkASSERT(viewMatrix.rectStaysRect()); + SkASSERT(!rects[0].isEmpty() && !rects[1].isEmpty()); + + SkRect devOutside, devInside; + viewMatrix.mapRect(&devOutside, rects[0]); + viewMatrix.mapRect(&devInside, rects[1]); + if (devInside.isEmpty()) { + if (devOutside.isEmpty()) { + return nullptr; + } + return GrAAFillRectOp::Make(color, viewMatrix, devOutside, devOutside); + } + + return GrAAStrokeRectOp::MakeFillBetweenRects(color, viewMatrix, devOutside, devInside); +} +}; diff --git a/src/gpu/ops/GrRectOpFactory.h b/src/gpu/ops/GrRectOpFactory.h index cf3da2f8bd..58927ef91b 100644 --- a/src/gpu/ops/GrRectOpFactory.h +++ b/src/gpu/ops/GrRectOpFactory.h @@ -1,5 +1,5 @@ /* - * Copyright 2017 Google Inc. + * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. @@ -8,66 +8,58 @@ #ifndef GrRectOpFactory_DEFINED #define GrRectOpFactory_DEFINED -#include <memory> -#include "GrTypes.h" +#include "GrAAFillRectOp.h" +#include "GrAAStrokeRectOp.h" +#include "GrAnalyticRectOp.h" +#include "GrColor.h" +#include "GrMeshDrawOp.h" +#include "GrNonAAStrokeRectOp.h" +#include "GrPaint.h" +#include "SkMatrix.h" +#include "SkRefCnt.h" -enum class GrAAType : unsigned; -class GrDrawOp; -class GrPaint; -struct GrUserStencilSettings; -class SkMatrix; struct SkRect; class SkStrokeRec; /** - * A set of factory functions for drawing rectangles including fills, strokes, coverage-antialiased, - * and non-antialiased. The non-antialiased ops can be used with MSAA. As with other GrDrawOp - * factories, the GrPaint is only consumed by these methods if a valid op is returned. If null is - * returned then the paint is unmodified and may still be used. + * A factory for returning GrDrawOps which can draw rectangles. */ namespace GrRectOpFactory { -/** AA Fill */ -std::unique_ptr<GrDrawOp> MakeAAFill(GrPaint&&, const SkMatrix&, const SkRect&, - const GrUserStencilSettings* = nullptr); - -// Using this method to supply a device rect simply saves recalculation if the device rect is known. -std::unique_ptr<GrDrawOp> MakeAAFillWithDevRect(GrPaint&&, const SkMatrix& viewMatrix, - const SkRect& rect, const SkRect& devRect); - -std::unique_ptr<GrDrawOp> MakeAAFillWithLocalMatrix(GrPaint&&, const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, const SkRect&); - -std::unique_ptr<GrDrawOp> MakeAAFillWithLocalRect(GrPaint&&, const SkMatrix&, const SkRect& rect, - const SkRect& localRect); - -/** Non-AA Fill - GrAAType must be either kNone or kMSAA. */ - -std::unique_ptr<GrDrawOp> MakeNonAAFill(GrPaint&&, const SkMatrix& viewMatrix, const SkRect& rect, - GrAAType, const GrUserStencilSettings* = nullptr); - -std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalMatrix(GrPaint&&, const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, const SkRect&, - GrAAType, - const GrUserStencilSettings* = nullptr); - -std::unique_ptr<GrDrawOp> MakeNonAAFillWithLocalRect(GrPaint&&, const SkMatrix&, const SkRect& rect, - const SkRect& localRect, GrAAType); - -/** AA Stroke */ - -std::unique_ptr<GrDrawOp> MakeAAStroke(GrPaint&&, const SkMatrix&, const SkRect&, - const SkStrokeRec&); - -// rects[0] == outer rectangle, rects[1] == inner rectangle. Null return means there is nothing to -// draw rather than failure. -std::unique_ptr<GrDrawOp> MakeAAFillNestedRects(GrPaint&&, const SkMatrix&, const SkRect rects[2]); - -/** Non-AA Stroke - GrAAType must be either kNone or kMSAA. */ - -std::unique_ptr<GrDrawOp> MakeNonAAStroke(GrPaint&&, const SkMatrix&, const SkRect&, - const SkStrokeRec&, GrAAType); - -} // namespace GrRectOpFactory +inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFill(const GrPaint& paint, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect& croppedRect, + const SkRect& devRect) { + return GrAAFillRectOp::Make(paint.getColor(), viewMatrix, croppedRect, devRect); +} + +inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFill(GrColor color, + const SkMatrix& viewMatrix, + const SkMatrix& localMatrix, + const SkRect& rect, + const SkRect& devRect) { + return GrAAFillRectOp::Make(color, viewMatrix, localMatrix, rect, devRect); +} + +inline std::unique_ptr<GrLegacyMeshDrawOp> MakeNonAAStroke(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& strokeRec, + bool snapToPixelCenters) { + return GrNonAAStrokeRectOp::Make(color, viewMatrix, rect, strokeRec, snapToPixelCenters); +} + +inline std::unique_ptr<GrLegacyMeshDrawOp> MakeAAStroke(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkStrokeRec& stroke) { + return GrAAStrokeRectOp::Make(color, viewMatrix, rect, stroke); +} + +// First rect is outer; second rect is inner +std::unique_ptr<GrLegacyMeshDrawOp> MakeAAFillNestedRects(GrColor, const SkMatrix& viewMatrix, + const SkRect rects[2]); +}; #endif diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h index 903859c309..dcd8dd887e 100644 --- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h +++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h @@ -35,26 +35,19 @@ public: template <typename Op, typename... OpArgs> static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs); - enum class Flags : uint32_t { - kNone = 0x0, - kSnapVerticesToPixelCenters = 0x1, - }; - GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags); - - GrSimpleMeshDrawOpHelper(const MakeArgs& args, GrAAType aaType, Flags flags = Flags::kNone) + GrSimpleMeshDrawOpHelper(const MakeArgs& args, GrAAType aaType, + GrUserStencilSettings* stencilSettings = nullptr) : fProcessors(args.fProcessorSet) , fPipelineFlags(args.fSRGBFlags) , fAAType((int)aaType) , fRequiresDstTexture(false) , fUsesLocalCoords(false) , fCompatibleWithAlphaAsCoveage(false) { + SkASSERT(!stencilSettings); SkDEBUGCODE(fDidAnalysis = false); if (GrAATypeIsHW(aaType)) { fPipelineFlags |= GrPipeline::kHWAntialias_Flag; } - if (flags & Flags::kSnapVerticesToPixelCenters) { - fPipelineFlags |= GrPipeline::kSnapVerticesToPixelCenters_Flag; - } } ~GrSimpleMeshDrawOpHelper() { @@ -174,7 +167,6 @@ private: class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper { public: using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs; - using Flags = GrSimpleMeshDrawOpHelper::Flags; // using declarations can't be templated, so this is a pass through function instead. template <typename Op, typename... OpArgs> @@ -184,9 +176,8 @@ public: } GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs& args, GrAAType aaType, - const GrUserStencilSettings* stencilSettings, - Flags flags = Flags::kNone) - : INHERITED(args, aaType, flags) + const GrUserStencilSettings* stencilSettings) + : INHERITED(args, aaType) , fStencilSettings(stencilSettings ? stencilSettings : &GrUserStencilSettings::kUnused) {} @@ -200,7 +191,6 @@ public: using GrSimpleMeshDrawOpHelper::xpRequiresDstTexture; using GrSimpleMeshDrawOpHelper::usesLocalCoords; - using GrSimpleMeshDrawOpHelper::compatibleWithAlphaAsCoverage; bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps& caps, const SkRect& aBounds, const SkRect& bBounds) const { @@ -237,6 +227,4 @@ std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrPaint&& pain } } -GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::Flags) - #endif diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp index a613841d9a..46e9fa7aae 100644 --- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp @@ -17,7 +17,7 @@ #include "GrResourceProvider.h" #include "GrStencilPathOp.h" #include "GrStyle.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrResourceProvider* resourceProvider, const GrCaps& caps) { @@ -134,10 +134,10 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { if (GrAAType::kMixedSamples == coverAAType) { coverAAType = GrAAType::kNone; } - args.fRenderTargetContext->addDrawOp(*args.fClip, - GrRectOpFactory::MakeNonAAFillWithLocalMatrix( - std::move(args.fPaint), viewM, invert, - bounds, coverAAType, &kInvertedCoverPass)); + args.fRenderTargetContext->addDrawOp( + *args.fClip, + GrNonAAFillRectOp::Make(std::move(args.fPaint), viewM, bounds, nullptr, &invert, + coverAAType, &kInvertedCoverPass)); } } else { std::unique_ptr<GrDrawOp> op = diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp index 7f9dff738b..528dd61562 100644 --- a/tests/ProcessorTest.cpp +++ b/tests/ProcessorTest.cpp @@ -19,7 +19,7 @@ #include "GrResourceProvider.h" #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" -#include "ops/GrRectOpFactory.h" +#include "ops/GrNonAAFillRectOp.h" #include "ops/GrTestMeshDrawOp.h" namespace { @@ -270,9 +270,9 @@ void test_draw_op(GrRenderTargetContext* rtc, sk_sp<GrFragmentProcessor> fp, paint.addColorFragmentProcessor(std::move(fp)); paint.setPorterDuffXPFactory(SkBlendMode::kSrc); - auto op = GrRectOpFactory::MakeNonAAFill(std::move(paint), SkMatrix::I(), - SkRect::MakeWH(rtc->width(), rtc->height()), - GrAAType::kNone); + auto op = GrNonAAFillRectOp::Make(std::move(paint), SkMatrix::I(), + SkRect::MakeWH(rtc->width(), rtc->height()), nullptr, nullptr, + GrAAType::kNone); rtc->addDrawOp(GrNoClip(), std::move(op)); } diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp index 1eb9860066..0486787790 100644 --- a/tools/gpu/GrTest.cpp +++ b/tools/gpu/GrTest.cpp @@ -472,24 +472,25 @@ void GrDrawingManager::testingOnly_removeOnFlushCallbackObject(GrOnFlushCallback #define DRAW_OP_TEST_ENTRY(Op) Op##__Test LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAConvexPathOp); +LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAFillRectOp); +LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAFillRectOpLocalMatrix); LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAFlatteningConvexPathOp) LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAHairlineOp); +LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAStrokeRectOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(AnalyticRectOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(DashOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(DefaultPathOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(GrDrawAtlasOp); +LEGACY_MESH_DRAW_OP_TEST_EXTERN(NonAAStrokeRectOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(SmallPathOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(TesselatingPathOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(TextBlobOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(VerticesOp); -DRAW_OP_TEST_EXTERN(AAFillRectOp) -DRAW_OP_TEST_EXTERN(AAStrokeRectOp); DRAW_OP_TEST_EXTERN(CircleOp) DRAW_OP_TEST_EXTERN(DIEllipseOp); DRAW_OP_TEST_EXTERN(EllipseOp); DRAW_OP_TEST_EXTERN(NonAAFillRectOp) -DRAW_OP_TEST_EXTERN(NonAAStrokeRectOp); DRAW_OP_TEST_EXTERN(RRectOp); void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext, GrPaint&& paint) { @@ -497,12 +498,16 @@ void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext using MakeTestLegacyMeshDrawOpFn = std::unique_ptr<GrLegacyMeshDrawOp>(SkRandom*, GrContext*); static constexpr MakeTestLegacyMeshDrawOpFn* gLegacyFactories[] = { DRAW_OP_TEST_ENTRY(AAConvexPathOp), + DRAW_OP_TEST_ENTRY(AAFillRectOp), + DRAW_OP_TEST_ENTRY(AAFillRectOpLocalMatrix), DRAW_OP_TEST_ENTRY(AAFlatteningConvexPathOp), DRAW_OP_TEST_ENTRY(AAHairlineOp), + DRAW_OP_TEST_ENTRY(AAStrokeRectOp), DRAW_OP_TEST_ENTRY(AnalyticRectOp), DRAW_OP_TEST_ENTRY(DashOp), DRAW_OP_TEST_ENTRY(DefaultPathOp), DRAW_OP_TEST_ENTRY(GrDrawAtlasOp), + DRAW_OP_TEST_ENTRY(NonAAStrokeRectOp), DRAW_OP_TEST_ENTRY(SmallPathOp), DRAW_OP_TEST_ENTRY(TesselatingPathOp), DRAW_OP_TEST_ENTRY(TextBlobOp), @@ -511,13 +516,10 @@ void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext using MakeDrawOpFn = std::unique_ptr<GrDrawOp>(GrPaint&&, SkRandom*, GrContext*, GrFSAAType); static constexpr MakeDrawOpFn* gFactories[] = { - DRAW_OP_TEST_ENTRY(AAFillRectOp), - DRAW_OP_TEST_ENTRY(AAStrokeRectOp), DRAW_OP_TEST_ENTRY(CircleOp), DRAW_OP_TEST_ENTRY(DIEllipseOp), DRAW_OP_TEST_ENTRY(EllipseOp), DRAW_OP_TEST_ENTRY(NonAAFillRectOp), - DRAW_OP_TEST_ENTRY(NonAAStrokeRectOp), DRAW_OP_TEST_ENTRY(RRectOp), }; |