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" 1272e3ae486c66871c2043eac4f08d85d419fbca2absalomon#include "GrVertexBuffer.h" 13f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 14ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 159853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrSoftwarePathRenderer::canDrawPath(const GrDrawTarget*, 168dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrPipelineBuilder*, 178059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 189853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath&, 191899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo& stroke, 20f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) const { 21730c0447916909f01df7fa12e9c82dd7cf7989dcrobertphillips if (NULL == fContext) { 22f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com return false; 23f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com } 241899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (stroke.isDashed()) { 251899651ffc459f5462aa989cd6d08507947b67e4kkinnunen return false; 261899651ffc459f5462aa989cd6d08507947b67e4kkinnunen } 27ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 28ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 29ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 309853ccef19c200be93a6211f32589fa82a53067cjoshualittGrPathRenderer::StencilSupport 319853ccef19c200be93a6211f32589fa82a53067cjoshualittGrSoftwarePathRenderer::onGetStencilSupport(const GrDrawTarget*, 328dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrPipelineBuilder*, 339853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath&, 341899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo&) 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, 458dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrPipelineBuilder* pipelineBuilder, 46ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const SkPath& path, 47b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& matrix, 48fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect* devPathBounds, 49fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect* devClipBounds) { 50ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // compute bounds as intersection of rt size, clip, and path 518dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); 52ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == rt) { 53ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 54ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 553e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 5644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt pipelineBuilder->clip().getConservativeBounds(rt, devClipBounds); 577b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com 58e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips if (devClipBounds->isEmpty()) { 59e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); 603e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com return false; 61ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 623e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 63366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!path.getBounds().isEmpty()) { 64fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect pathSBounds; 65366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com matrix.mapRect(&pathSBounds, path.getBounds()); 66fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect pathIBounds; 67ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com pathSBounds.roundOut(&pathIBounds); 68e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips *devPathBounds = *devClipBounds; 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 { 75fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org *devPathBounds = SkIRect::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, 838dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 842e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 858059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 86fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkIRect& devClipBounds, 87fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkIRect& devPathBounds) { 88d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt SkMatrix invert; 898059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!viewMatrix.invert(&invert)) { 90e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 91e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 92d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt 93fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect rect; 947b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fTop < devPathBounds.fTop) { 95d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devClipBounds.fTop, 967b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fTop); 978dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), rect, NULL, &invert); 98ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 997b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fLeft < devPathBounds.fLeft) { 100d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fTop, 1017b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devPathBounds.fLeft, devPathBounds.fBottom); 1028dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), rect, NULL, &invert); 103ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 1047b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fRight > devPathBounds.fRight) { 105d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devPathBounds.fRight, devPathBounds.fTop, 1067b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fBottom); 1078dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), rect, NULL, &invert); 108ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 1097b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fBottom > devPathBounds.fBottom) { 110d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, 1117b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devClipBounds.fBottom); 1128dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), rect, NULL, &invert); 113ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 114f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 115f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 116ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 117ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 118ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 119ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// return true on success; false on failure 1209853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target, 1218dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 1222e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 1238059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 1249853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath& path, 1251899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo& stroke, 126f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) { 127ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == fContext) { 128ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 129ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 130ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 131fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect devPathBounds, devClipBounds; 13244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt if (!get_path_and_clip_bounds(target, pipelineBuilder, path, viewMatrix, &devPathBounds, 13344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt &devClipBounds)) { 134e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (path.isInverseFillType()) { 1358dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel draw_around_inv_path(target, pipelineBuilder, color, viewMatrix, devClipBounds, 1368dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel devPathBounds); 137276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com } 138276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com return true; 139ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 140366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 1415dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com SkAutoTUnref<GrTexture> texture( 1421899651ffc459f5462aa989cd6d08507947b67e4kkinnunen GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke.getStrokeRec(), 14312b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com devPathBounds, 1448059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt antiAlias, &viewMatrix)); 1455dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com if (NULL == texture) { 1465dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return false; 147ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 148ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 1498dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder copy = *pipelineBuilder; 1508059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, ©, color, viewMatrix, 1518059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt devPathBounds); 1525dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 153e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (path.isInverseFillType()) { 1548dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel draw_around_inv_path(target, pipelineBuilder, color, viewMatrix, devClipBounds, 1558dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel devPathBounds); 1565dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com } 1575dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 1585dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return true; 159f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 160