180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrSoftwarePathRenderer.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrContext.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrSWMaskHelper.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool GrSoftwarePathRenderer::canDrawPath(const SkPath&, 15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkStrokeRec&, 16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const GrDrawTarget*, 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool antiAlias) const { 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!antiAlias || NULL == fContext) { 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: We could allow the SW path to also handle non-AA paths but 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this would mean that GrDefaultPathRenderer would never be called 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // (since it appears after the SW renderer in the path renderer 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // chain). Some testing would need to be done r.e. performance 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // and consistency of the resulting images before removing 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the "!antiAlias" clause from the above test 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrPathRenderer::StencilSupport GrSoftwarePathRenderer::onGetStencilSupport( 3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkPath&, 3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkStrokeRec&, 3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const GrDrawTarget*) const { 35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return GrPathRenderer::kNoSupport_StencilSupport; 36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// gets device coord bounds of path (not considering the fill) and clip. The 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// path bounds will be a subset of the clip bounds. returns false if 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// path bounds would be empty. 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool get_path_and_clip_bounds(const GrDrawTarget* target, 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPath& path, 46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix& matrix, 4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkIRect* devPathBounds, 4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkIRect* devClipBounds) { 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // compute bounds as intersection of rt size, clip, and path 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == rt) { 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height()); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->getClip()->getConservativeBounds(rt, devClipBounds); 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: getConservativeBounds already intersects with the 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // render target's bounding box. Remove this next line 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!devPathBounds->intersect(*devClipBounds)) { 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!path.getBounds().isEmpty()) { 6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkRect pathSBounds; 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix.mapRect(&pathSBounds, path.getBounds()); 6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkIRect pathIBounds; 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pathSBounds.roundOut(&pathIBounds); 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!devPathBounds->intersect(pathIBounds)) { 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // set the correct path bounds, as this would be used later. 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *devPathBounds = pathIBounds; 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *devPathBounds = SkIRect::EmptyIRect(); 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid draw_around_inv_path(GrDrawTarget* target, 8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkIRect& devClipBounds, 8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkIRect& devPathBounds) { 8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawState::AutoViewMatrixRestore avmr; 8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!avmr.setIdentity(target->drawState())) { 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkRect rect; 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (devClipBounds.fTop < devPathBounds.fTop) { 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect.iset(devClipBounds.fLeft, devClipBounds.fTop, 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devClipBounds.fRight, devPathBounds.fTop); 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawSimpleRect(rect, NULL); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (devClipBounds.fLeft < devPathBounds.fLeft) { 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect.iset(devClipBounds.fLeft, devPathBounds.fTop, 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devPathBounds.fLeft, devPathBounds.fBottom); 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawSimpleRect(rect, NULL); 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (devClipBounds.fRight > devPathBounds.fRight) { 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect.iset(devPathBounds.fRight, devPathBounds.fTop, 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devClipBounds.fRight, devPathBounds.fBottom); 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawSimpleRect(rect, NULL); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (devClipBounds.fBottom > devPathBounds.fBottom) { 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devClipBounds.fRight, devClipBounds.fBottom); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawSimpleRect(rect, NULL); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// return true on success; false on failure 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, 117363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkStrokeRec& stroke, 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget* target, 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool antiAlias) { 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fContext) { 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = target->drawState(); 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 127363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix vm = drawState->getViewMatrix(); 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkIRect devPathBounds, devClipBounds; 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!get_path_and_clip_bounds(target, path, vm, 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru &devPathBounds, &devClipBounds)) { 132363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (path.isInverseFillType()) { 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru draw_around_inv_path(target, devClipBounds, devPathBounds); 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoTUnref<GrTexture> texture( 139363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke, 140363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger devPathBounds, 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru antiAlias, &vm)); 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == texture) { 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds); 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 148363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (path.isInverseFillType()) { 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru draw_around_inv_path(target, devClipBounds, devPathBounds); 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 154