GrSoftwarePathRenderer.cpp revision 3e11c0bd92fbd12f59080c3f9450201d6105db83
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, 15f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com GrPathFill fill, 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 22ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@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 35ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@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, 39366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com const GrMatrix& matrix, 40ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrIRect* pathBounds, 41ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrIRect* clipBounds) { 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 } 47ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com *pathBounds = GrIRect::MakeWH(rt->width(), rt->height()); 48ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const GrClip& clip = target->getClip(); 493e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 503e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com clip.getConservativeBounds().roundOut(clipBounds); 513e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com if (!pathBounds->intersect(*clipBounds)) { 523e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com return false; 53ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 543e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 55366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!path.getBounds().isEmpty()) { 56366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com GrRect pathSBounds; 57366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com matrix.mapRect(&pathSBounds, path.getBounds()); 58ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrIRect pathIBounds; 59ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com pathSBounds.roundOut(&pathIBounds); 60ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (!pathBounds->intersect(pathIBounds)) { 61276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com // set the correct path bounds, as this would be used later. 62276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com *pathBounds = pathIBounds; 63ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 64ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 65ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } else { 66276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com *pathBounds = GrIRect::EmptyIRect(); 67ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 68ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 69ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 70ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 71ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 72ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 73ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comvoid draw_around_inv_path(GrDrawTarget* target, 74ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrDrawState::StageMask stageMask, 75ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const GrIRect& clipBounds, 76ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const GrIRect& pathBounds) { 77ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 78ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrRect rect; 79ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (clipBounds.fTop < pathBounds.fTop) { 80ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com rect.iset(clipBounds.fLeft, clipBounds.fTop, 81ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com clipBounds.fRight, pathBounds.fTop); 82ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com target->drawSimpleRect(rect, NULL, stageMask); 83ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 84ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (clipBounds.fLeft < pathBounds.fLeft) { 85ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com rect.iset(clipBounds.fLeft, pathBounds.fTop, 86ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com pathBounds.fLeft, pathBounds.fBottom); 87ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com target->drawSimpleRect(rect, NULL, stageMask); 88ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 89ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (clipBounds.fRight > pathBounds.fRight) { 90ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com rect.iset(pathBounds.fRight, pathBounds.fTop, 91ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com clipBounds.fRight, pathBounds.fBottom); 92ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com target->drawSimpleRect(rect, NULL, stageMask); 93ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 94ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (clipBounds.fBottom > pathBounds.fBottom) { 95ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com rect.iset(clipBounds.fLeft, pathBounds.fBottom, 96ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com clipBounds.fRight, clipBounds.fBottom); 97ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com target->drawSimpleRect(rect, NULL, stageMask); 98ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 99f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 100f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 101ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 102ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 103ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 104ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// return true on success; false on failure 105f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.combool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, 106f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com GrPathFill fill, 107f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com const GrVec* translate, 108f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com GrDrawTarget* target, 109f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com GrDrawState::StageMask stageMask, 110f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) { 111f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 112ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == fContext) { 113ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 114ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 115ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 116366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com GrDrawState* drawState = target->drawState(); 117366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 118366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com GrMatrix vm = drawState->getViewMatrix(); 119366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (NULL != translate) { 120366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com vm.postTranslate(translate->fX, translate->fY); 121366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com } 122366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 123ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com GrIRect pathBounds, clipBounds; 124366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!get_path_and_clip_bounds(target, path, vm, 125ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com &pathBounds, &clipBounds)) { 126276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com if (GrIsFillInverted(fill)) { 127276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com draw_around_inv_path(target, stageMask, 128276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com clipBounds, pathBounds); 129276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com } 130276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com return true; 131ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 132366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 1335dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com SkAutoTUnref<GrTexture> texture( 1345dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, 1355dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com pathBounds, fill, 1365dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com antiAlias, &vm)); 1375dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com if (NULL == texture) { 1385dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return false; 139ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 140ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 1415dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, 1425dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com stageMask, pathBounds); 1435dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 1445dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com if (GrIsFillInverted(fill)) { 1455dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com draw_around_inv_path(target, stageMask, 1465dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com clipBounds, pathBounds); 1475dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com } 1485dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 1495dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return true; 150f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 151