GrSoftwarePathRenderer.cpp revision 1899651ffc459f5462aa989cd6d08507947b67e4
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//////////////////////////////////////////////////////////////////////////////// 149853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrSoftwarePathRenderer::canDrawPath(const GrDrawTarget*, 158dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrPipelineBuilder*, 168059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 179853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath&, 181899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo& stroke, 19f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) const { 20730c0447916909f01df7fa12e9c82dd7cf7989dcrobertphillips if (NULL == fContext) { 21f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com return false; 22f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com } 231899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (stroke.isDashed()) { 241899651ffc459f5462aa989cd6d08507947b67e4kkinnunen return false; 251899651ffc459f5462aa989cd6d08507947b67e4kkinnunen } 26ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 27ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 28ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 299853ccef19c200be93a6211f32589fa82a53067cjoshualittGrPathRenderer::StencilSupport 309853ccef19c200be93a6211f32589fa82a53067cjoshualittGrSoftwarePathRenderer::onGetStencilSupport(const GrDrawTarget*, 318dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrPipelineBuilder*, 329853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath&, 331899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo&) const { 3445a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com return GrPathRenderer::kNoSupport_StencilSupport; 3545a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com} 3645a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 37ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comnamespace { 38ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 39ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 40ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// gets device coord bounds of path (not considering the fill) and clip. The 41d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com// path bounds will be a subset of the clip bounds. returns false if 42ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// path bounds would be empty. 43ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.combool get_path_and_clip_bounds(const GrDrawTarget* target, 448dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrPipelineBuilder* pipelineBuilder, 45ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com const SkPath& path, 46b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& matrix, 47fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect* devPathBounds, 48fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect* devClipBounds) { 49ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com // compute bounds as intersection of rt size, clip, and path 508dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); 51ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == rt) { 52ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 53ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 543e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 5544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt pipelineBuilder->clip().getConservativeBounds(rt, devClipBounds); 567b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com 57e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips if (devClipBounds->isEmpty()) { 58e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); 593e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com return false; 60ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 613e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 62366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com if (!path.getBounds().isEmpty()) { 63fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect pathSBounds; 64366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com matrix.mapRect(&pathSBounds, path.getBounds()); 65fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect pathIBounds; 66ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com pathSBounds.roundOut(&pathIBounds); 67e85a32d4f8ce7fb9b6aaae89137dbf3766d833f2robertphillips *devPathBounds = *devClipBounds; 687b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (!devPathBounds->intersect(pathIBounds)) { 69276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com // set the correct path bounds, as this would be used later. 707b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com *devPathBounds = pathIBounds; 71ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 72ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 73ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } else { 74fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org *devPathBounds = SkIRect::EmptyIRect(); 75ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 76ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 77ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return true; 78ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 79ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 80ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 81ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.comvoid draw_around_inv_path(GrDrawTarget* target, 828dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 832e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 848059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 85fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkIRect& devClipBounds, 86fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkIRect& devPathBounds) { 87d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt SkMatrix invert; 888059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!viewMatrix.invert(&invert)) { 89e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 90e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 91d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt 92fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect rect; 937b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fTop < devPathBounds.fTop) { 94d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devClipBounds.fTop, 957b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fTop); 968dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), rect, NULL, &invert); 97ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 987b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fLeft < devPathBounds.fLeft) { 99d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fTop, 1007b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devPathBounds.fLeft, devPathBounds.fBottom); 1018dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), rect, NULL, &invert); 102ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 1037b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fRight > devPathBounds.fRight) { 104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devPathBounds.fRight, devPathBounds.fTop, 1057b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devPathBounds.fBottom); 1068dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), rect, NULL, &invert); 107ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 1087b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com if (devClipBounds.fBottom > devPathBounds.fBottom) { 109d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, 1107b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com devClipBounds.fRight, devClipBounds.fBottom); 1118dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), rect, NULL, &invert); 112ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 113f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 114f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com 115ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com} 116ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 117ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 118ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com// return true on success; false on failure 1199853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target, 1208dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 1212e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 1228059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 1239853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath& path, 1241899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo& stroke, 125f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com bool antiAlias) { 126ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com if (NULL == fContext) { 127ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com return false; 128ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 129ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 130fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkIRect devPathBounds, devClipBounds; 13144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt if (!get_path_and_clip_bounds(target, pipelineBuilder, path, viewMatrix, &devPathBounds, 13244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt &devClipBounds)) { 133e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (path.isInverseFillType()) { 1348dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel draw_around_inv_path(target, pipelineBuilder, color, viewMatrix, devClipBounds, 1358dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel devPathBounds); 136276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com } 137276c1fabc22d4980c2ed8fe879f6510289b87cdebsalomon@google.com return true; 138ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 139366f1c6a09f63c76e78145cb08028f66062f31fdrobertphillips@google.com 1405dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com SkAutoTUnref<GrTexture> texture( 1411899651ffc459f5462aa989cd6d08507947b67e4kkinnunen GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke.getStrokeRec(), 14212b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com devPathBounds, 1438059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt antiAlias, &viewMatrix)); 1445dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com if (NULL == texture) { 1455dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return false; 146ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com } 147ed4155d610442b75e906a3489c984394c34b5ff9robertphillips@google.com 1488dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder copy = *pipelineBuilder; 1498059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, ©, color, viewMatrix, 1508059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt devPathBounds); 1515dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 152e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (path.isInverseFillType()) { 1538dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel draw_around_inv_path(target, pipelineBuilder, color, viewMatrix, devClipBounds, 1548dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel devPathBounds); 1555dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com } 1565dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com 1575dfb67219a308edecafbe09eebb35c5e149db6e6robertphillips@google.com return true; 158f4c2c527dd3cab979621fdfbc07eb22fee103472robertphillips@google.com} 159