13f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
23f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/*
33f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Copyright 2011 Google Inc.
43f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *
53f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
63f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * found in the LICENSE file.
73f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com */
83f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
93f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrPathRendererChain.h"
113f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
123f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrContext.h"
133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrDefaultPathRenderer.h"
14516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.com#include "GrDrawTargetCaps.h"
153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrGpu.h"
163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
175402c06820a293e8293e052266d9fbdb8ab42033robertphillips@google.comSK_DEFINE_INST_COUNT(GrPathRendererChain)
185402c06820a293e8293e052266d9fbdb8ab42033robertphillips@google.com
190afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.comGrPathRendererChain::GrPathRendererChain(GrContext* context)
203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    : fInit(false)
210afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    , fOwner(context) {
223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
23be0ce063fdb3226fa2c40dcc93b35f658867422bbsalomon@google.com
243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrPathRendererChain::~GrPathRendererChain() {
253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    for (int i = 0; i < fChain.count(); ++i) {
263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        fChain[i]->unref();
273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) {
313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fChain.push_back() = pr;
323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    pr->ref();
333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    return pr;
343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
36111fa9c0003b99e052d665af57b51ff973dcb416bsalomon@google.comGrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path,
375c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com                                                     const SkStrokeRec& stroke,
38111fa9c0003b99e052d665af57b51ff973dcb416bsalomon@google.com                                                     const GrDrawTarget* target,
390afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                                                     DrawType drawType,
400afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                                                     StencilSupport* stencilSupport) {
413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (!fInit) {
423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        this->init();
433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
440afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    bool antiAlias = (kColorAntiAlias_DrawType == drawType ||
450afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                      kStencilAndColorAntiAlias_DrawType == drawType);
460afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com
470afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport <
480afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                     GrPathRenderer::kStencilOnly_StencilSupport);
490afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport <
500afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                     GrPathRenderer::kNoRestriction_StencilSupport);
510afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    GrPathRenderer::StencilSupport minStencilSupport;
520afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    if (kStencilOnly_DrawType == drawType) {
530afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com        minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport;
540afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    } else if (kStencilAndColor_DrawType == drawType ||
550afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com               kStencilAndColorAntiAlias_DrawType == drawType) {
560afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com        minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
570afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    } else {
580afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com        minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport;
590afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    }
600afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com
610afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com
623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    for (int i = 0; i < fChain.count(); ++i) {
63290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com        if (fChain[i]->canDrawPath(path, stroke, target, antiAlias)) {
640afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com            if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
650afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(path,
660afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                                                                                      stroke,
670afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                                                                                      target);
680afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                if (support < minStencilSupport) {
690afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                    continue;
700afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                } else if (NULL != stencilSupport) {
710afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                    *stencilSupport = support;
720afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com                }
730afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com            }
74f9ba6e3339b8414de3674c55d86267212b99b07fbsalomon@google.com            return fChain[i];
753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        }
763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
77f9ba6e3339b8414de3674c55d86267212b99b07fbsalomon@google.com    return NULL;
783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrPathRendererChain::init() {
813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GrAssert(!fInit);
823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GrGpu* gpu = fOwner->getGpu();
8359831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    bool twoSided = gpu->caps()->twoSidedStencilSupport();
8459831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    bool wrapOp = gpu->caps()->stencilWrapOpsSupport();
850afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com    GrPathRenderer::AddPathRenderers(fOwner, this);
863697dec537a5d9941c5662d1b6c948c921edb5d4tomhudson@google.com    this->addPathRenderer(SkNEW_ARGS(GrDefaultPathRenderer,
873697dec537a5d9941c5662d1b6c948c921edb5d4tomhudson@google.com                                     (twoSided, wrapOp)))->unref();
883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fInit = true;
893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
90