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//////////////////////////////////////////////////////////////////////////////// 14e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.combool GrSoftwarePathRenderer::canDrawPath(const SkPath&, 15e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com const SkStrokeRec&, 165f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com const GrDrawTarget*, 17f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) const { 18730c0447916909f01df7fa12e9c82dd7cf7989dcrobertphillips if (NULL == fContext) { 19f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com return false; 20f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com } 21f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 22ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 23ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 24ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 2545a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.comGrPathRenderer::StencilSupport GrSoftwarePathRenderer::onGetStencilSupport( 26e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com const SkPath&, 27fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkStrokeRec&, 28fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const GrDrawTarget*) const { 2945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com return GrPathRenderer::kNoSupport_StencilSupport; 3045a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com} 3145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 32ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comnamespace { 33ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 34ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 35ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// gets device coord bounds of path (not considering the fill) and clip. The 36d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com// path bounds will be a subset of the clip bounds. returns false if 37ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// path bounds would be empty. 38ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.combool get_path_and_clip_bounds(const GrDrawTarget* target, 39ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const SkPath& path, 40b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& matrix, 41fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect* devPathBounds, 42fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect* devClipBounds) { 43ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // compute bounds as intersection of rt size, clip, and path 44ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 45ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == rt) { 46ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 47ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 48fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); 493e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 507b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com target->getClip()->getConservativeBounds(rt, devClipBounds); 517b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com 52d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // TODO: getConservativeBounds already intersects with the 537b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com // render target's bounding box. Remove this next line 547b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (!devPathBounds->intersect(*devClipBounds)) { 553e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com return false; 56ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 573e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 58366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!path.getBounds().isEmpty()) { 59fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect pathSBounds; 60366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com matrix.mapRect(&pathSBounds, path.getBounds()); 61fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect pathIBounds; 62ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com pathSBounds.roundOut(&pathIBounds); 637b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (!devPathBounds->intersect(pathIBounds)) { 64276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com // set the correct path bounds, as this would be used later. 657b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com *devPathBounds = pathIBounds; 66ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 67ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 68ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } else { 69fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org *devPathBounds = SkIRect::EmptyIRect(); 70ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 71ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 72ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 73ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 74ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 75ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 76ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comvoid draw_around_inv_path(GrDrawTarget* target, 77fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkIRect& devClipBounds, 78fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkIRect& devPathBounds) { 79137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 80137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 81e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 82e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 83fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect rect; 847b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fTop < devPathBounds.fTop) { 85d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devClipBounds.fTop, 867b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fTop); 8701c8da1eef36570374f7e8764a38b25bf16ab7a6bsalomon target->drawSimpleRect(rect); 88ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 897b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fLeft < devPathBounds.fLeft) { 90d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fTop, 917b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devPathBounds.fLeft, devPathBounds.fBottom); 9201c8da1eef36570374f7e8764a38b25bf16ab7a6bsalomon target->drawSimpleRect(rect); 93ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 947b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fRight > devPathBounds.fRight) { 95d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devPathBounds.fRight, devPathBounds.fTop, 967b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fBottom); 9701c8da1eef36570374f7e8764a38b25bf16ab7a6bsalomon target->drawSimpleRect(rect); 98ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 997b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fBottom > devPathBounds.fBottom) { 100d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, 1017b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devClipBounds.fBottom); 10201c8da1eef36570374f7e8764a38b25bf16ab7a6bsalomon target->drawSimpleRect(rect); 103ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 104f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 105f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 106ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 107ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 108ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 109ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// return true on success; false on failure 110e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.combool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, 111e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com const SkStrokeRec& stroke, 112f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com GrDrawTarget* target, 113f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) { 114f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 115ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == fContext) { 116ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 117ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 118ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 119366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com GrDrawState* drawState = target->drawState(); 120366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 121b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix vm = drawState->getViewMatrix(); 122366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 123fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect devPathBounds, devClipBounds; 124e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (!get_path_and_clip_bounds(target, path, vm, 1257b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com &devPathBounds, &devClipBounds)) { 126e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (path.isInverseFillType()) { 1277b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com draw_around_inv_path(target, devClipBounds, devPathBounds); 128276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com } 129276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com return true; 130ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 131366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 1325dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com SkAutoTUnref<GrTexture> texture( 133e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke, 13412b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com devPathBounds, 1355dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com antiAlias, &vm)); 1365dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com if (NULL == texture) { 1375dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return false; 138ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 139ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 1407b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds); 1415dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 142e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (path.isInverseFillType()) { 1437b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com draw_around_inv_path(target, devClipBounds, devPathBounds); 1445dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com } 1455dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 1465dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return true; 147f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 148