/* * This method traverses the clip stack to see if the GrSoftwarePathRenderer * will be used on any element. If so, it returns true to indicate that the * entire clip should be rendered in SW and then uploaded en masse to the gpu. */ bool GrClipMaskManager::UseSWOnlyPath(GrContext* context, const GrPipelineBuilder& pipelineBuilder, const GrDrawContext* drawContext, const SkVector& clipToMaskOffset, const GrReducedClip::ElementList& elements) { // TODO: generalize this function so that when // a clip gets complex enough it can just be done in SW regardless // of whether it would invoke the GrSoftwarePathRenderer. // Set the matrix so that rendered clip elements are transformed to mask space from clip // space. const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMaskOffset.fY); for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { const Element* element = iter.get(); SkRegion::Op op = element->getOp(); bool invert = element->isInverseFilled(); bool needsStencil = invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op; if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings(), drawContext, translate, element, nullptr, needsStencil)) { return true; } } return false; }
// Determines whether it is possible to draw the element to both the stencil buffer and the // alpha mask simultaneously. If so and the element is a path a compatible path renderer is // also returned. GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context, GrTexture* texture, const SkMatrix& viewMatrix, const SkClipStack::Element* element) { GrPathRenderer* pr; static const bool kNeedsStencil = true; static const bool kStencilIsDisabled = true; PathNeedsSWRenderer(context, kStencilIsDisabled, texture->asRenderTarget(), viewMatrix, element, &pr, kNeedsStencil); return pr; }