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, ©, 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