180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrStencilAndCoverPathRenderer.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrContext.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrDrawTargetCaps.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrGpu.h" 14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrPath.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStrokeRec.h" 16910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger 17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) { 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != context); 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != context->getGpu()); 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (context->getGpu()->caps()->pathRenderingSupport()) { 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(GrStencilAndCoverPathRenderer, (context->getGpu())); 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrGpu* gpu) { 28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(gpu->caps()->pathRenderingSupport()); 29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGpu = gpu; 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gpu->ref(); 310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrStencilAndCoverPathRenderer::~GrStencilAndCoverPathRenderer() { 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->unref(); 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path, 38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkStrokeRec& stroke, 39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const GrDrawTarget* target, 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool antiAlias) const { 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return !stroke.isHairlineStyle() && 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !antiAlias && // doesn't do per-path AA, relies on the target having MSAA 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL != target->getDrawState().getRenderTarget()->getStencilBuffer() && 44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger target->getDrawState().getStencil().isDisabled(); 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport( 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPath&, 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkStrokeRec& , 50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const GrDrawTarget*) const { 51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return GrPathRenderer::kStencilOnly_StencilSupport; 52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkStrokeRec& stroke, 56363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrDrawTarget* target) { 57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(!path.isInverseFillType()); 58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(path, stroke)); 59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger target->stencilPath(p, path.getFillType()); 60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 61363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, 63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkStrokeRec& stroke, 64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrDrawTarget* target, 65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool antiAlias) { 66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(!antiAlias); 67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(!stroke.isHairlineStyle()); 68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrDrawState* drawState = target->drawState(); 70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(drawState->getStencil().isDisabled()); 71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 72363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(path, stroke)); 73363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 74363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (path.isInverseFillType()) { 75363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass, 76363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger kZero_StencilOp, 77363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger kZero_StencilOp, 78363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // We know our rect will hit pixels outside the clip and the user bits will be 0 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // outside the clip. So we can't just fill where the user bits are 0. We also need to 80363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // check that the clip bit is set. 81363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger kEqualIfInClip_StencilFunc, 82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0xffff, 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0x0000, 84363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0xffff); 85363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *drawState->stencil() = kInvertedStencilPass; 870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } else { 88363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GR_STATIC_CONST_SAME_STENCIL(kStencilPass, 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kZero_StencilOp, 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kZero_StencilOp, 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kNotEqual_StencilFunc, 92363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0xffff, 93363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0x0000, 94363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0xffff); 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *drawState->stencil() = kStencilPass; 97363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawPath(p, path.getFillType()); 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawState()->stencil()->setDisabled(); 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 104363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger