1509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com 2509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com/* 3509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com * Copyright 2012 Google Inc. 4509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com * 5509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 6509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com * found in the LICENSE file. 7509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com */ 8509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com 9509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com#include "GrSoftwarePathRenderer.h" 101c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com#include "GrContext.h" 11fe39b2270e725e82f3598adba36d1b5b4cd60186robertphillips@google.com#include "GrSWMaskHelper.h" 12509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com 131c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 145c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.combool GrSoftwarePathRenderer::canDrawPath(const SkPath&, 155c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com const SkStrokeRec&, 165c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com const GrDrawTarget*, 17509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com bool antiAlias) const { 181c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com if (!antiAlias || NULL == fContext) { 191c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com // TODO: We could allow the SW path to also handle non-AA paths but 201c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com // this would mean that GrDefaultPathRenderer would never be called 211c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com // (since it appears after the SW renderer in the path renderer 22dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com // chain). Some testing would need to be done r.e. performance 231c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com // and consistency of the resulting images before removing 241c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com // the "!antiAlias" clause from the above test 25509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com return false; 26509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com } 27509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com 281c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com return true; 291c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com} 301c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com 310afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.comGrPathRenderer::StencilSupport GrSoftwarePathRenderer::onGetStencilSupport( 32a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkPath&, 33a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkStrokeRec&, 34a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const GrDrawTarget*) const { 350afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com return GrPathRenderer::kNoSupport_StencilSupport; 360afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com} 370afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com 381c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.comnamespace { 391c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com 401c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 411c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com// gets device coord bounds of path (not considering the fill) and clip. The 42dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com// path bounds will be a subset of the clip bounds. returns false if 431c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com// path bounds would be empty. 441c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.combool get_path_and_clip_bounds(const GrDrawTarget* target, 451c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com const SkPath& path, 46a4e2f5beb2d73243c15ab871f013d2ba29e8fea3bsalomon@google.com const SkMatrix& matrix, 47a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org SkIRect* devPathBounds, 48a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org SkIRect* devClipBounds) { 491c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com // compute bounds as intersection of rt size, clip, and path 501c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 511c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com if (NULL == rt) { 521c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com return false; 531c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 54a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); 5515e7ae449c45978bc7ed7aba427369e4f78bc6derobertphillips@google.com 56b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com target->getClip()->getConservativeBounds(rt, devClipBounds); 57b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com 58dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com // TODO: getConservativeBounds already intersects with the 59b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com // render target's bounding box. Remove this next line 60b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com if (!devPathBounds->intersect(*devClipBounds)) { 6115e7ae449c45978bc7ed7aba427369e4f78bc6derobertphillips@google.com return false; 621c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 6315e7ae449c45978bc7ed7aba427369e4f78bc6derobertphillips@google.com 64eeb064d9572cc6a9859260de155096c43c0a2116robertphillips@google.com if (!path.getBounds().isEmpty()) { 65a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org SkRect pathSBounds; 66eeb064d9572cc6a9859260de155096c43c0a2116robertphillips@google.com matrix.mapRect(&pathSBounds, path.getBounds()); 67a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org SkIRect pathIBounds; 681c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com pathSBounds.roundOut(&pathIBounds); 69b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com if (!devPathBounds->intersect(pathIBounds)) { 706f14f6e86c3c528f3801e96ae21531e6900d6d16bsalomon@google.com // set the correct path bounds, as this would be used later. 71b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com *devPathBounds = pathIBounds; 721c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com return false; 731c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 741c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } else { 75a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org *devPathBounds = SkIRect::EmptyIRect(); 761c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com return false; 771c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 781c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com return true; 791c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com} 801c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com 811c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 821c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.comvoid draw_around_inv_path(GrDrawTarget* target, 83a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkIRect& devClipBounds, 84a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkIRect& devPathBounds) { 85fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 86fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 877cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com return; 887cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com } 89a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org SkRect rect; 90b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com if (devClipBounds.fTop < devPathBounds.fTop) { 91dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com rect.iset(devClipBounds.fLeft, devClipBounds.fTop, 92b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com devClipBounds.fRight, devPathBounds.fTop); 937cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com target->drawSimpleRect(rect, NULL); 941c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 95b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com if (devClipBounds.fLeft < devPathBounds.fLeft) { 96dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fTop, 97b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com devPathBounds.fLeft, devPathBounds.fBottom); 987cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com target->drawSimpleRect(rect, NULL); 991c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 100b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com if (devClipBounds.fRight > devPathBounds.fRight) { 101dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com rect.iset(devPathBounds.fRight, devPathBounds.fTop, 102b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com devClipBounds.fRight, devPathBounds.fBottom); 1037cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com target->drawSimpleRect(rect, NULL); 1041c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 105b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com if (devClipBounds.fBottom > devPathBounds.fBottom) { 106dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, 107b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com devClipBounds.fRight, devClipBounds.fBottom); 1087cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com target->drawSimpleRect(rect, NULL); 1091c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 110509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com} 111509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com 1121c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com} 1131c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com 1141c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 1151c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com// return true on success; false on failure 116509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.combool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, 1175c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com const SkStrokeRec& stroke, 118509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com GrDrawTarget* target, 119509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com bool antiAlias) { 120509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com 1211c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com if (NULL == fContext) { 1221c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com return false; 1231c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 1241c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com 125eeb064d9572cc6a9859260de155096c43c0a2116robertphillips@google.com GrDrawState* drawState = target->drawState(); 126eeb064d9572cc6a9859260de155096c43c0a2116robertphillips@google.com 127a4e2f5beb2d73243c15ab871f013d2ba29e8fea3bsalomon@google.com SkMatrix vm = drawState->getViewMatrix(); 128eeb064d9572cc6a9859260de155096c43c0a2116robertphillips@google.com 129a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org SkIRect devPathBounds, devClipBounds; 130eeb064d9572cc6a9859260de155096c43c0a2116robertphillips@google.com if (!get_path_and_clip_bounds(target, path, vm, 131b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com &devPathBounds, &devClipBounds)) { 132290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com if (path.isInverseFillType()) { 133b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com draw_around_inv_path(target, devClipBounds, devPathBounds); 1346f14f6e86c3c528f3801e96ae21531e6900d6d16bsalomon@google.com } 1356f14f6e86c3c528f3801e96ae21531e6900d6d16bsalomon@google.com return true; 1361c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 137eeb064d9572cc6a9859260de155096c43c0a2116robertphillips@google.com 13885de99c7514564c198712fa1c205b3eba41525a1robertphillips@google.com SkAutoTUnref<GrTexture> texture( 139290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke, 140290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com devPathBounds, 14185de99c7514564c198712fa1c205b3eba41525a1robertphillips@google.com antiAlias, &vm)); 14285de99c7514564c198712fa1c205b3eba41525a1robertphillips@google.com if (NULL == texture) { 14385de99c7514564c198712fa1c205b3eba41525a1robertphillips@google.com return false; 1441c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com } 1451c8b85ec1a7658510e4809d376439cf9fc0a76aarobertphillips@google.com 146b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds); 14785de99c7514564c198712fa1c205b3eba41525a1robertphillips@google.com 148290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com if (path.isInverseFillType()) { 149b6b643945182d1df391fdd11e2e788af8445914frobertphillips@google.com draw_around_inv_path(target, devClipBounds, devPathBounds); 15085de99c7514564c198712fa1c205b3eba41525a1robertphillips@google.com } 15185de99c7514564c198712fa1c205b3eba41525a1robertphillips@google.com 15285de99c7514564c198712fa1c205b3eba41525a1robertphillips@google.com return true; 153509a5db5e14dd358d2ea7ea950d073513231184drobertphillips@google.com} 154