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#include "GrSoftwarePathRenderer.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrContext.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrSWMaskHelper.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////
14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool GrSoftwarePathRenderer::canDrawPath(const SkPath&,
15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                         const SkStrokeRec&,
16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                         const GrDrawTarget*,
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                         bool antiAlias) const {
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!antiAlias || NULL == fContext) {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // TODO: We could allow the SW path to also handle non-AA paths but
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // this would mean that GrDefaultPathRenderer would never be called
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // (since it appears after the SW renderer in the path renderer
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // chain). Some testing would need to be done r.e. performance
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // and consistency of the resulting images before removing
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // the "!antiAlias" clause from the above test
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrPathRenderer::StencilSupport GrSoftwarePathRenderer::onGetStencilSupport(
3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const SkPath&,
3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const SkStrokeRec&,
3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const GrDrawTarget*) const {
35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return GrPathRenderer::kNoSupport_StencilSupport;
36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace {
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// gets device coord bounds of path (not considering the fill) and clip. The
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// path bounds will be a subset of the clip bounds. returns false if
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// path bounds would be empty.
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool get_path_and_clip_bounds(const GrDrawTarget* target,
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                              const SkPath& path,
46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                              const SkMatrix& matrix,
4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                              SkIRect* devPathBounds,
4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                              SkIRect* devClipBounds) {
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // compute bounds as intersection of rt size, clip, and path
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const GrRenderTarget* rt = target->getDrawState().getRenderTarget();
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == rt) {
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height());
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    target->getClip()->getConservativeBounds(rt, devClipBounds);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // TODO: getConservativeBounds already intersects with the
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // render target's bounding box. Remove this next line
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!devPathBounds->intersect(*devClipBounds)) {
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!path.getBounds().isEmpty()) {
6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkRect pathSBounds;
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        matrix.mapRect(&pathSBounds, path.getBounds());
6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkIRect pathIBounds;
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        pathSBounds.roundOut(&pathIBounds);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!devPathBounds->intersect(pathIBounds)) {
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // set the correct path bounds, as this would be used later.
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *devPathBounds = pathIBounds;
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        *devPathBounds = SkIRect::EmptyIRect();
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid draw_around_inv_path(GrDrawTarget* target,
8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          const SkIRect& devClipBounds,
8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                          const SkIRect& devPathBounds) {
8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    GrDrawState::AutoViewMatrixRestore avmr;
8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if (!avmr.setIdentity(target->drawState())) {
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkRect rect;
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (devClipBounds.fTop < devPathBounds.fTop) {
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  devClipBounds.fRight, devPathBounds.fTop);
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        target->drawSimpleRect(rect, NULL);
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (devClipBounds.fLeft < devPathBounds.fLeft) {
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  devPathBounds.fLeft, devPathBounds.fBottom);
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        target->drawSimpleRect(rect, NULL);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (devClipBounds.fRight > devPathBounds.fRight) {
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        rect.iset(devPathBounds.fRight, devPathBounds.fTop,
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  devClipBounds.fRight, devPathBounds.fBottom);
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        target->drawSimpleRect(rect, NULL);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (devClipBounds.fBottom > devPathBounds.fBottom) {
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  devClipBounds.fRight, devClipBounds.fBottom);
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        target->drawSimpleRect(rect, NULL);
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// return true on success; false on failure
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrSoftwarePathRenderer::onDrawPath(const SkPath& path,
117363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                        const SkStrokeRec& stroke,
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        GrDrawTarget* target,
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        bool antiAlias) {
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == fContext) {
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrDrawState* drawState = target->drawState();
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
127363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    SkMatrix vm = drawState->getViewMatrix();
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkIRect devPathBounds, devClipBounds;
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!get_path_and_clip_bounds(target, path, vm,
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                  &devPathBounds, &devClipBounds)) {
132363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        if (path.isInverseFillType()) {
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            draw_around_inv_path(target, devClipBounds, devPathBounds);
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoTUnref<GrTexture> texture(
139363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke,
140363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                                  devPathBounds,
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                  antiAlias, &vm));
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == texture) {
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds);
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
148363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (path.isInverseFillType()) {
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        draw_around_inv_path(target, devClipBounds, devPathBounds);
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
154