GrSoftwarePathRenderer.cpp revision 2e3b3e369d79e78f7635d4c20e83a47ab571bdf2
1f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com
2f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com/*
3f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com * Copyright 2012 Google Inc.
4f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com *
5f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
6f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com * found in the LICENSE file.
7f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com */
8f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com
9f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com#include "GrSoftwarePathRenderer.h"
10ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com#include "GrContext.h"
1158b20215f6d88b7e1cacae0b76226fced5109293robertphillips@google.com#include "GrSWMaskHelper.h"
12f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com
13ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com////////////////////////////////////////////////////////////////////////////////
149853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrSoftwarePathRenderer::canDrawPath(const GrDrawTarget*,
159853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                         const GrDrawState*,
169853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                         const SkPath&,
17e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com                                         const SkStrokeRec&,
18f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com                                         bool antiAlias) const {
19730c0447916909f01df7fa12e9c82dd7cf7989dcrobertphillips    if (NULL == fContext) {
20f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com        return false;
21f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com    }
22f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com
23ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    return true;
24ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com}
25ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com
269853ccef19c200be93a6211f32589fa82a53067cjoshualittGrPathRenderer::StencilSupport
279853ccef19c200be93a6211f32589fa82a53067cjoshualittGrSoftwarePathRenderer::onGetStencilSupport(const GrDrawTarget*,
289853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                            const GrDrawState*,
299853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                            const SkPath&,
309853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                            const SkStrokeRec&) const {
3145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com    return GrPathRenderer::kNoSupport_StencilSupport;
3245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com}
3345a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com
34ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comnamespace {
35ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com
36ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com////////////////////////////////////////////////////////////////////////////////
37ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// gets device coord bounds of path (not considering the fill) and clip. The
38d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com// path bounds will be a subset of the clip bounds. returns false if
39ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// path bounds would be empty.
40ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.combool get_path_and_clip_bounds(const GrDrawTarget* target,
419853ccef19c200be93a6211f32589fa82a53067cjoshualitt                              const GrDrawState* drawState,
42ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com                              const SkPath& path,
43b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                              const SkMatrix& matrix,
44fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                              SkIRect* devPathBounds,
45fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                              SkIRect* devClipBounds) {
46ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    // compute bounds as intersection of rt size, clip, and path
479853ccef19c200be93a6211f32589fa82a53067cjoshualitt    const GrRenderTarget* rt = drawState->getRenderTarget();
48ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    if (NULL == rt) {
49ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com        return false;
50ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
51fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height());
523e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com
537b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com    target->getClip()->getConservativeBounds(rt, devClipBounds);
547b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com
55d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // TODO: getConservativeBounds already intersects with the
567b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com    // render target's bounding box. Remove this next line
577b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com    if (!devPathBounds->intersect(*devClipBounds)) {
583e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com        return false;
59ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
603e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com
61366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com    if (!path.getBounds().isEmpty()) {
62fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org        SkRect pathSBounds;
63366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com        matrix.mapRect(&pathSBounds, path.getBounds());
64fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org        SkIRect pathIBounds;
65ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com        pathSBounds.roundOut(&pathIBounds);
667b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com        if (!devPathBounds->intersect(pathIBounds)) {
67276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com            // set the correct path bounds, as this would be used later.
687b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com            *devPathBounds = pathIBounds;
69ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com            return false;
70ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com        }
71ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    } else {
72fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org        *devPathBounds = SkIRect::EmptyIRect();
73ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com        return false;
74ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
75ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    return true;
76ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com}
77ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com
78ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com////////////////////////////////////////////////////////////////////////////////
79ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comvoid draw_around_inv_path(GrDrawTarget* target,
809853ccef19c200be93a6211f32589fa82a53067cjoshualitt                          GrDrawState* drawState,
812e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                          GrColor color,
82fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                          const SkIRect& devClipBounds,
83fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                          const SkIRect& devPathBounds) {
84137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    GrDrawState::AutoViewMatrixRestore avmr;
859853ccef19c200be93a6211f32589fa82a53067cjoshualitt    if (!avmr.setIdentity(drawState)) {
86e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        return;
87e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    }
88fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkRect rect;
897b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com    if (devClipBounds.fTop < devPathBounds.fTop) {
90d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
917b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com                  devClipBounds.fRight, devPathBounds.fTop);
922e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        target->drawSimpleRect(drawState, color, rect);
93ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
947b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com    if (devClipBounds.fLeft < devPathBounds.fLeft) {
95d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
967b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com                  devPathBounds.fLeft, devPathBounds.fBottom);
972e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        target->drawSimpleRect(drawState, color, rect);
98ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
997b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com    if (devClipBounds.fRight > devPathBounds.fRight) {
100d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        rect.iset(devPathBounds.fRight, devPathBounds.fTop,
1017b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com                  devClipBounds.fRight, devPathBounds.fBottom);
1022e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        target->drawSimpleRect(drawState, color, rect);
103ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
1047b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com    if (devClipBounds.fBottom > devPathBounds.fBottom) {
105d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
1067b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com                  devClipBounds.fRight, devClipBounds.fBottom);
1072e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        target->drawSimpleRect(drawState, color, rect);
108ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
109f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com}
110f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com
111ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com}
112ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com
113ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com////////////////////////////////////////////////////////////////////////////////
114ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// return true on success; false on failure
1159853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target,
1169853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                        GrDrawState* drawState,
1172e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                                        GrColor color,
1189853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                        const SkPath& path,
119e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com                                        const SkStrokeRec& stroke,
120f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com                                        bool antiAlias) {
121f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com
122ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    if (NULL == fContext) {
123ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com        return false;
124ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
125ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com
126b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    SkMatrix vm = drawState->getViewMatrix();
127366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com
128fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkIRect devPathBounds, devClipBounds;
1299853ccef19c200be93a6211f32589fa82a53067cjoshualitt    if (!get_path_and_clip_bounds(target, drawState, path, vm,
1307b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com                                  &devPathBounds, &devClipBounds)) {
131e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com        if (path.isInverseFillType()) {
1322e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt            draw_around_inv_path(target, drawState, color, devClipBounds, devPathBounds);
133276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com        }
134276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com        return true;
135ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
136366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com
1375dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com    SkAutoTUnref<GrTexture> texture(
138e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com            GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke,
13912b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com                                                  devPathBounds,
1405dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com                                                  antiAlias, &vm));
1415dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com    if (NULL == texture) {
1425dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com        return false;
143ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com    }
144ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com
1459853ccef19c200be93a6211f32589fa82a53067cjoshualitt    GrDrawState copy = *drawState;
1462e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, &copy, color, devPathBounds);
1475dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com
148e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com    if (path.isInverseFillType()) {
1492e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        draw_around_inv_path(target, drawState, color, devClipBounds, devPathBounds);
1505dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com    }
1515dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com
1525dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com    return true;
153f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com}
154