GrSoftwarePathRenderer.cpp revision 137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3
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//////////////////////////////////////////////////////////////////////////////// 145f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.combool GrSoftwarePathRenderer::canDrawPath(const SkPath&, 155f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com const SkStrokeRec&, 165f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com const GrDrawTarget*, 17f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) const { 18ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (!antiAlias || NULL == fContext) { 19ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // TODO: We could allow the SW path to also handle non-AA paths but 20ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // this would mean that GrDefaultPathRenderer would never be called 21ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // (since it appears after the SW renderer in the path renderer 22d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // chain). Some testing would need to be done r.e. performance 23ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // and consistency of the resulting images before removing 24ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // the "!antiAlias" clause from the above test 25f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com return false; 26f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com } 27f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 28ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 29ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 30ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 3145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.comGrPathRenderer::StencilSupport GrSoftwarePathRenderer::onGetStencilSupport( 3245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com const SkPath&, 335f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com const SkStrokeRec&, 3445a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com const GrDrawTarget*) const { 3545a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com return GrPathRenderer::kNoSupport_StencilSupport; 3645a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com} 3745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 38ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comnamespace { 39ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 40ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 41ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// gets device coord bounds of path (not considering the fill) and clip. The 42d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com// path bounds will be a subset of the clip bounds. returns false if 43ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// path bounds would be empty. 44ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.combool get_path_and_clip_bounds(const GrDrawTarget* target, 45ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const SkPath& path, 46b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& matrix, 477b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrIRect* devPathBounds, 487b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrIRect* devClipBounds) { 49ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // compute bounds as intersection of rt size, clip, and path 50ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 51ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == rt) { 52ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 53ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 547b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com *devPathBounds = GrIRect::MakeWH(rt->width(), rt->height()); 553e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 567b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com target->getClip()->getConservativeBounds(rt, devClipBounds); 577b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com 58d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // TODO: getConservativeBounds already intersects with the 597b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com // render target's bounding box. Remove this next line 607b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (!devPathBounds->intersect(*devClipBounds)) { 613e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com return false; 62ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 633e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 64366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!path.getBounds().isEmpty()) { 65366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com GrRect pathSBounds; 66366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com matrix.mapRect(&pathSBounds, path.getBounds()); 67ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrIRect pathIBounds; 68ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com pathSBounds.roundOut(&pathIBounds); 697b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (!devPathBounds->intersect(pathIBounds)) { 70276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com // set the correct path bounds, as this would be used later. 717b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com *devPathBounds = pathIBounds; 72ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 73ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 74ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } else { 757b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com *devPathBounds = GrIRect::EmptyIRect(); 76ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 77ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 78ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 79ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 80ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 81ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 82ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comvoid draw_around_inv_path(GrDrawTarget* target, 837b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com const GrIRect& devClipBounds, 847b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com const GrIRect& devPathBounds) { 85137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 86137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 87e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 88e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 89ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrRect rect; 907b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fTop < devPathBounds.fTop) { 91d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devClipBounds.fTop, 927b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fTop); 93e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, NULL); 94ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 957b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fLeft < devPathBounds.fLeft) { 96d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fTop, 977b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devPathBounds.fLeft, devPathBounds.fBottom); 98e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, NULL); 99ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 1007b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fRight > devPathBounds.fRight) { 101d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devPathBounds.fRight, devPathBounds.fTop, 1027b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fBottom); 103e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, NULL); 104ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 1057b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fBottom > devPathBounds.fBottom) { 106d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, 1077b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devClipBounds.fBottom); 108e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, NULL); 109ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 110f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 111f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 112ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 113ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 114ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 115ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// return true on success; false on failure 116f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.combool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, 1175f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com const SkStrokeRec& stroke, 118f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com GrDrawTarget* target, 119f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) { 120f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 121ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == fContext) { 122ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 123ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 124ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 125366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com GrDrawState* drawState = target->drawState(); 126366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 127b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix vm = drawState->getViewMatrix(); 128366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 1297b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrIRect devPathBounds, devClipBounds; 130366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!get_path_and_clip_bounds(target, path, vm, 1317b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com &devPathBounds, &devClipBounds)) { 13212b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com if (path.isInverseFillType()) { 1337b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com draw_around_inv_path(target, devClipBounds, devPathBounds); 134276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com } 135276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com return true; 136ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 137366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 1385dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com SkAutoTUnref<GrTexture> texture( 13912b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke, 14012b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com devPathBounds, 1415dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com antiAlias, &vm)); 1425dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com if (NULL == texture) { 1435dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return false; 144ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 145ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 1467b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds); 1475dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 14812b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com if (path.isInverseFillType()) { 1497b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com draw_around_inv_path(target, devClipBounds, devPathBounds); 1505dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com } 1515dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 1525dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return true; 153f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 154