/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "GrPathRendererChain.h" #include "GrCaps.h" #include "GrContext.h" #include "GrGpu.h" #include "batches/GrAAConvexPathRenderer.h" #include "batches/GrAADistanceFieldPathRenderer.h" #include "batches/GrAAHairLinePathRenderer.h" #include "batches/GrAALinearizingConvexPathRenderer.h" #include "batches/GrDashLinePathRenderer.h" #include "batches/GrDefaultPathRenderer.h" #include "batches/GrStencilAndCoverPathRenderer.h" #include "batches/GrTessellatingPathRenderer.h" GrPathRendererChain::GrPathRendererChain(GrContext* context) : fInit(false) , fOwner(context) { } GrPathRendererChain::~GrPathRendererChain() { for (int i = 0; i < fChain.count(); ++i) { fChain[i]->unref(); } } GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) { fChain.push_back() = pr; pr->ref(); return pr; } GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrDrawTarget* target, const GrPipelineBuilder* pipelineBuilder, const SkMatrix& viewMatrix, const SkPath& path, const GrStrokeInfo& stroke, DrawType drawType, StencilSupport* stencilSupport) { if (!fInit) { this->init(); } bool antiAlias = (kColorAntiAlias_DrawType == drawType || kStencilAndColorAntiAlias_DrawType == drawType); GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport < GrPathRenderer::kStencilOnly_StencilSupport); GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport < GrPathRenderer::kNoRestriction_StencilSupport); GrPathRenderer::StencilSupport minStencilSupport; if (kStencilOnly_DrawType == drawType) { minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport; } else if (kStencilAndColor_DrawType == drawType || kStencilAndColorAntiAlias_DrawType == drawType) { minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; } else { minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport; } for (int i = 0; i < fChain.count(); ++i) { GrPathRenderer::CanDrawPathArgs args; args.fShaderCaps = target->caps()->shaderCaps(); args.fPipelineBuilder = pipelineBuilder; args.fViewMatrix = &viewMatrix; args.fPath = &path; args.fStroke = &stroke; args.fAntiAlias = antiAlias; if (fChain[i]->canDrawPath(args)) { if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) { GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(path, stroke); if (support < minStencilSupport) { continue; } else if (stencilSupport) { *stencilSupport = support; } } return fChain[i]; } } return nullptr; } void GrPathRendererChain::init() { SkASSERT(!fInit); const GrCaps& caps = *fOwner->caps(); this->addPathRenderer(new GrDashLinePathRenderer)->unref(); if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(fOwner->resourceProvider(), caps)) { this->addPathRenderer(pr)->unref(); } this->addPathRenderer(new GrTessellatingPathRenderer)->unref(); this->addPathRenderer(new GrAAHairLinePathRenderer)->unref(); this->addPathRenderer(new GrAAConvexPathRenderer)->unref(); this->addPathRenderer(new GrAALinearizingConvexPathRenderer)->unref(); this->addPathRenderer(new GrAADistanceFieldPathRenderer)->unref(); this->addPathRenderer(new GrDefaultPathRenderer(caps.twoSidedStencilSupport(), caps.stencilWrapOpsSupport()))->unref(); fInit = true; }