1ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 2ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com/* 3ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com * Copyright 2012 Google Inc. 4ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com * 5ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 6ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com * found in the LICENSE file. 7ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com */ 8ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 9ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 10ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrStencilAndCoverPathRenderer.h" 11ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrContext.h" 12c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com#include "GrDrawTargetCaps.h" 13ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrGpu.h" 14ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrPath.h" 155f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkStrokeRec.h" 16ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 17ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.comGrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) { 1849f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(context); 1949f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(context->getGpu()); 20c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org if (context->getGpu()->caps()->pathRenderingSupport()) { 21c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com return SkNEW_ARGS(GrStencilAndCoverPathRenderer, (context->getGpu())); 22ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } else { 23ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com return NULL; 24ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } 25ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com} 26ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 27ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.comGrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrGpu* gpu) { 28c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org SkASSERT(gpu->caps()->pathRenderingSupport()); 29ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com fGpu = gpu; 30ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com gpu->ref(); 31ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com} 32ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 33ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.comGrStencilAndCoverPathRenderer::~GrStencilAndCoverPathRenderer() { 34ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com fGpu->unref(); 35ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com} 36ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 37e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.combool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path, 38e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com const SkStrokeRec& stroke, 39ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com const GrDrawTarget* target, 40ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com bool antiAlias) const { 4132184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.org return !stroke.isHairlineStyle() && 42ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com !antiAlias && // doesn't do per-path AA, relies on the target having MSAA 4349f085dddff10473b6ebf832a974288300224e60bsalomon target->getDrawState().getRenderTarget()->getStencilBuffer() && 44ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com target->getDrawState().getStencil().isDisabled(); 45ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com} 46ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 4745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.comGrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport( 48e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com const SkPath&, 495f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com const SkStrokeRec& , 5045a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com const GrDrawTarget*) const { 5145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com return GrPathRenderer::kStencilOnly_StencilSupport; 52ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com} 53ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 544e205b10799730b887ae5d6ac7207570292c177fcdaltonstatic GrPath* get_gr_path(GrGpu* gpu, const SkPath& skPath, const SkStrokeRec& stroke) { 554e205b10799730b887ae5d6ac7207570292c177fcdalton GrContext* ctx = gpu->getContext(); 564e205b10799730b887ae5d6ac7207570292c177fcdalton GrResourceKey resourceKey = GrPath::ComputeKey(skPath, stroke); 574e205b10799730b887ae5d6ac7207570292c177fcdalton SkAutoTUnref<GrPath> path(static_cast<GrPath*>(ctx->findAndRefCachedResource(resourceKey))); 584e205b10799730b887ae5d6ac7207570292c177fcdalton if (NULL == path || !path->isEqualTo(skPath, stroke)) { 594e205b10799730b887ae5d6ac7207570292c177fcdalton path.reset(gpu->pathRendering()->createPath(skPath, stroke)); 604e205b10799730b887ae5d6ac7207570292c177fcdalton ctx->addResourceToCache(resourceKey, path); 614e205b10799730b887ae5d6ac7207570292c177fcdalton } 624e205b10799730b887ae5d6ac7207570292c177fcdalton return path.detach(); 634e205b10799730b887ae5d6ac7207570292c177fcdalton} 644e205b10799730b887ae5d6ac7207570292c177fcdalton 65e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.comvoid GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, 66e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com const SkStrokeRec& stroke, 6745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com GrDrawTarget* target) { 68e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com SkASSERT(!path.isInverseFillType()); 694e205b10799730b887ae5d6ac7207570292c177fcdalton SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke)); 70e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com target->stencilPath(p, path.getFillType()); 71ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com} 72ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 73e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.combool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, 74e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com const SkStrokeRec& stroke, 75ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com GrDrawTarget* target, 760f11e1ab5b6e53f6176dde2dbb25a8e3ae34858fbsalomon@google.com bool antiAlias) { 77f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!antiAlias); 78f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(!stroke.isHairlineStyle()); 79ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 80ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com GrDrawState* drawState = target->drawState(); 81f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(drawState->getStencil().isDisabled()); 82ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 834e205b10799730b887ae5d6ac7207570292c177fcdalton SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke)); 840f11e1ab5b6e53f6176dde2dbb25a8e3ae34858fbsalomon@google.com 856803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 86ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass, 87ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com kZero_StencilOp, 88ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com kZero_StencilOp, 8905a718c9d2302b08f859adac5854b2df6ff84e43bsalomon@google.com // We know our rect will hit pixels outside the clip and the user bits will be 0 9005a718c9d2302b08f859adac5854b2df6ff84e43bsalomon@google.com // outside the clip. So we can't just fill where the user bits are 0. We also need to 9105a718c9d2302b08f859adac5854b2df6ff84e43bsalomon@google.com // check that the clip bit is set. 9205a718c9d2302b08f859adac5854b2df6ff84e43bsalomon@google.com kEqualIfInClip_StencilFunc, 93ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 0xffff, 94ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 0x0000, 95ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 0xffff); 96c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 97ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com *drawState->stencil() = kInvertedStencilPass; 98c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org } else { 99c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org GR_STATIC_CONST_SAME_STENCIL(kStencilPass, 100c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org kZero_StencilOp, 101c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org kZero_StencilOp, 102c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org kNotEqual_StencilFunc, 103c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 0xffff, 104c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 0x0000, 105c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 0xffff); 106c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 107c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org *drawState->stencil() = kStencilPass; 108ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } 109c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 110e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com target->drawPath(p, path.getFillType()); 111c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org 112ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com target->drawState()->stencil()->setDisabled(); 113ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com return true; 114ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com} 115