GrSoftwarePathRenderer.cpp revision 12b4e27ae1a29460e91a59f38122483e1faec697
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//////////////////////////////////////////////////////////////////////////////// 14f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.combool GrSoftwarePathRenderer::canDrawPath(const SkPath& path, 1512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com const SkStroke& stroke, 16f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com const GrDrawTarget* target, 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 31ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comnamespace { 32ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 33ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 34ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// gets device coord bounds of path (not considering the fill) and clip. The 35d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com// path bounds will be a subset of the clip bounds. returns false if 36ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// path bounds would be empty. 37ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.combool get_path_and_clip_bounds(const GrDrawTarget* target, 38ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const SkPath& path, 39b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& matrix, 407b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrIRect* devPathBounds, 417b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrIRect* devClipBounds) { 42ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // compute bounds as intersection of rt size, clip, and path 43ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 44ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == rt) { 45ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 46ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 477b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com *devPathBounds = GrIRect::MakeWH(rt->width(), rt->height()); 483e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 497b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com target->getClip()->getConservativeBounds(rt, devClipBounds); 507b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com 51d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // TODO: getConservativeBounds already intersects with the 527b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com // render target's bounding box. Remove this next line 537b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (!devPathBounds->intersect(*devClipBounds)) { 543e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com return false; 55ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 563e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 57366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!path.getBounds().isEmpty()) { 58366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com GrRect pathSBounds; 59366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com matrix.mapRect(&pathSBounds, path.getBounds()); 60ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrIRect pathIBounds; 61ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com pathSBounds.roundOut(&pathIBounds); 627b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (!devPathBounds->intersect(pathIBounds)) { 63276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com // set the correct path bounds, as this would be used later. 647b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com *devPathBounds = pathIBounds; 65ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 66ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 67ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } else { 687b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com *devPathBounds = GrIRect::EmptyIRect(); 69ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 70ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 71ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 72ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 73ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 74ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 75ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comvoid draw_around_inv_path(GrDrawTarget* target, 767b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com const GrIRect& devClipBounds, 777b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com const GrIRect& devPathBounds) { 785b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com GrDrawState::AutoDeviceCoordDraw adcd(target->drawState()); 79e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (!adcd.succeeded()) { 80e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 81e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 82ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrRect rect; 837b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fTop < devPathBounds.fTop) { 84d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devClipBounds.fTop, 857b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fTop); 86e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, NULL); 87ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 887b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fLeft < devPathBounds.fLeft) { 89d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fTop, 907b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devPathBounds.fLeft, devPathBounds.fBottom); 91e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, NULL); 92ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 937b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fRight > devPathBounds.fRight) { 94d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devPathBounds.fRight, devPathBounds.fTop, 957b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fBottom); 96e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, NULL); 97ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 987b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fBottom > devPathBounds.fBottom) { 99d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, 1007b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devClipBounds.fBottom); 101e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, NULL); 102ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 103f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 104f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 105ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 106ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 107ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 108ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// return true on success; false on failure 109f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.combool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, 11012b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com const SkStroke& stroke, 111f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com GrDrawTarget* target, 112f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) { 113f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 114ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == fContext) { 115ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 116ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 117ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 118366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com GrDrawState* drawState = target->drawState(); 119366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 120b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix vm = drawState->getViewMatrix(); 121366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 1227b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrIRect devPathBounds, devClipBounds; 123366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!get_path_and_clip_bounds(target, path, vm, 1247b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com &devPathBounds, &devClipBounds)) { 12512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com if (path.isInverseFillType()) { 1267b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com draw_around_inv_path(target, devClipBounds, devPathBounds); 127276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com } 128276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com return true; 129ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 130366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 1315dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com SkAutoTUnref<GrTexture> texture( 13212b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke, 13312b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com devPathBounds, 1345dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com antiAlias, &vm)); 1355dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com if (NULL == texture) { 1365dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return false; 137ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 138ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 1397b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds); 1405dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 14112b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com if (path.isInverseFillType()) { 1427b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com draw_around_inv_path(target, devClipBounds, devPathBounds); 1435dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com } 1445dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 1455dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return true; 146f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 147