GrClipMaskManager.cpp revision 5acc0e36d987dff3172fd45a14b66c52a51d49e4
11e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 21e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com/* 31e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com * Copyright 2012 Google Inc. 41e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com * 51e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 61e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com * found in the LICENSE file. 71e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com */ 81e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 91e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#include "GrClipMaskManager.h" 101e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#include "GrGpu.h" 111e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#include "GrRenderTarget.h" 121e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#include "GrStencilBuffer.h" 131e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#include "GrPathRenderer.h" 14a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com#include "GrPaint.h" 156b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com#include "SkRasterClip.h" 16a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 17a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com//#define GR_AA_CLIP 1 186b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com//#define GR_SW_CLIP 1 19a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 20f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 211e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.comvoid ScissoringSettings::setupScissoring(GrGpu* gpu) { 221e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (!fEnableScissoring) { 231e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->disableScissor(); 241e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com return; 251e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 261e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 271e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->enableScissoring(fScissorRect); 281e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com} 291e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 30a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.comnamespace { 31a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com// set up the draw state to enable the aa clipping mask. Besides setting up the 32a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com// sampler matrix this also alters the vertex layout 336b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.comvoid setup_drawstate_aaclip(GrGpu* gpu, 346b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com GrTexture* result, 356623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com const GrIRect &bound) { 36a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com GrDrawState* drawState = gpu->drawState(); 37a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com GrAssert(drawState); 38a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 39a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com static const int maskStage = GrPaint::kTotalStages+1; 40a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 41a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com GrMatrix mat; 42a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com mat.setIDiv(result->width(), result->height()); 436623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com mat.preTranslate(SkIntToScalar(-bound.fLeft), SkIntToScalar(-bound.fTop)); 44a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com mat.preConcat(drawState->getViewMatrix()); 45a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 46a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com drawState->sampler(maskStage)->reset(GrSamplerState::kClamp_WrapMode, 47a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com GrSamplerState::kNearest_Filter, 48a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com mat); 49a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 50a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com drawState->setTexture(maskStage, result); 51a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 52a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com // The AA clipping determination happens long after the geometry has 53a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com // been set up to draw. Here we directly enable the AA clip mask stage 54a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com gpu->addToVertexLayout( 55a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(maskStage)); 56a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com} 57a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 586b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.combool create_mask_in_sw() { 596b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com return false; 606b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com} 616b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 62a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com} 63a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 64f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 656b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com// sort out what kind of clip mask needs to be created: alpha, stencil, 666b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com// scissor, or entirely software 671e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.combool GrClipMaskManager::createClipMask(GrGpu* gpu, 681e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com const GrClip& clipIn, 691e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com ScissoringSettings* scissorSettings) { 701e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 711e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrAssert(scissorSettings); 721e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 731e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com scissorSettings->fEnableScissoring = false; 741e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fClipMaskInStencil = false; 75f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com fClipMaskInAlpha = false; 761e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 771e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrDrawState* drawState = gpu->drawState(); 781e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (!drawState->isClipState()) { 791e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com return true; 801e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 811e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 821e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrRenderTarget* rt = drawState->getRenderTarget(); 831e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 841e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // GrDrawTarget should have filtered this for us 851e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrAssert(NULL != rt); 861e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 876b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com#if GR_SW_CLIP 886b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com if (create_mask_in_sw()) { 896b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // The clip geometry is complex enough that it will be more 906b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // efficient to create it entirely in software 916b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com GrTexture* result = NULL; 926623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com GrIRect bound; 936b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com if (this->createSoftwareClipMask(gpu, clipIn, &result, &bound)) { 946b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com fClipMaskInAlpha = true; 956b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 966b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com setup_drawstate_aaclip(gpu, result, bound); 976b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com return true; 986b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com } 996b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com } 1006b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com#endif 1016b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 102f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com#if GR_AA_CLIP 103f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // If MSAA is enabled use the (faster) stencil path for AA clipping 104f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // otherwise the alpha clip mask is our only option 105f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (clipIn.requiresAA() && 0 == rt->numSamples()) { 106f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // Since we are going to create a destination texture of the correct 107f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // size for the mask (rather than being bound by the size of the 108f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // render target) we aren't going to use scissoring like the stencil 109f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // path does (see scissorSettings below) 110a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com GrTexture* result = NULL; 1116623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com GrIRect bound; 112a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com if (this->createAlphaClipMask(gpu, clipIn, &result, &bound)) { 113f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com fClipMaskInAlpha = true; 114a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 1156b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com setup_drawstate_aaclip(gpu, result, bound); 116f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return true; 117f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 118f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 119f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // if alpha clip mask creation fails fall through to the stencil 120f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // buffer method 121f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 122f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com#endif // GR_AA_CLIP 123f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 1245acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // Either a hard (stencil buffer) clip was explicitly requested or 1255acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // an antialiased clip couldn't be created. In either case, free up 1265acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // the texture in the antialiased mask cache. 1275acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // TODO: this may require more investigation. Ganesh performs a lot of 1285acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // utility draws (e.g., clears, InOderDrawBuffer playbacks) that hit 1295acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // the stencil buffer path. These may be incorrectly messing up the 1305acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // AA cache. 1315acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com fAACache.reset(); 1325acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 1331e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrRect bounds; 1341e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrRect rtRect; 1351e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com rtRect.setLTRB(0, 0, 1361e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrIntToScalar(rt->width()), GrIntToScalar(rt->height())); 1371e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (clipIn.hasConservativeBounds()) { 1381e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bounds = clipIn.getConservativeBounds(); 1391e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (!bounds.intersect(rtRect)) { 1401e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bounds.setEmpty(); 1411e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 1421e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } else { 1431e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bounds = rtRect; 1441e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 1451e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 1461e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bounds.roundOut(&scissorSettings->fScissorRect); 1471e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (scissorSettings->fScissorRect.isEmpty()) { 1481e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com scissorSettings->fScissorRect.setLTRB(0,0,0,0); 1491e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // TODO: I think we can do an early exit here - after refactoring try: 1501e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // set fEnableScissoring to true but leave fClipMaskInStencil false 1511e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // and return - everything is going to be scissored away anyway! 1521e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 1531e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com scissorSettings->fEnableScissoring = true; 1541e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 1551e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // use the stencil clip if we can't represent the clip as a rectangle. 1561e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fClipMaskInStencil = !clipIn.isRect() && !clipIn.isEmpty() && 1571e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com !bounds.isEmpty(); 1581e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 1591e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (fClipMaskInStencil) { 1601e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com return this->createStencilClipMask(gpu, clipIn, bounds, scissorSettings); 1611e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 1621e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 1631e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com return true; 1641e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com} 1651e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 1661e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#define VISUALIZE_COMPLEX_CLIP 0 1671e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 1681e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#if VISUALIZE_COMPLEX_CLIP 1691e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com #include "GrRandom.h" 1701e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrRandom gRandom; 1711e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com #define SET_RANDOM_COLOR drawState->setColor(0xff000000 | gRandom.nextU()); 1721e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#else 1731e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com #define SET_RANDOM_COLOR 1741e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#endif 1751e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 1761e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.comnamespace { 1776623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com/** 1786623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com * Does "container" contain "containee"? If either is empty then 1796623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com * no containment is possible. 1806623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com */ 1816623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.combool contains(const SkRect& container, const SkIRect& containee) { 1826623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com return !containee.isEmpty() && !container.isEmpty() && 1836623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com container.fLeft <= SkIntToScalar(containee.fLeft) && 1846623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com container.fTop <= SkIntToScalar(containee.fTop) && 1856623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com container.fRight >= SkIntToScalar(containee.fRight) && 1866623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com container.fBottom >= SkIntToScalar(containee.fBottom); 1876623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com} 1886623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com 1896623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com 190f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 1911e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com// determines how many elements at the head of the clip can be skipped and 1921e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com// whether the initial clear should be to the inside- or outside-the-clip value, 1931e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com// and what op should be used to draw the first element that isn't skipped. 1941e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.comint process_initial_clip_elements(const GrClip& clip, 1956623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com const GrIRect& bounds, 1961e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bool* clearToInside, 1970f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com SkRegion::Op* startOp) { 1981e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 1991e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // logically before the first element of the clip stack is 2001e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // processed the clip is entirely open. However, depending on the 2011e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // first set op we may prefer to clear to 0 for performance. We may 2021e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // also be able to skip the initial clip paths/rects. We loop until 2031e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // we cannot skip an element. 2041e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com int curr; 2051e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bool done = false; 2061e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com *clearToInside = true; 2071e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com int count = clip.getElementCount(); 2081e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 2091e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com for (curr = 0; curr < count && !done; ++curr) { 2101e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com switch (clip.getOp(curr)) { 2110f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com case SkRegion::kReplace_Op: 2121e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // replace ignores everything previous 2130f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com *startOp = SkRegion::kReplace_Op; 2141e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com *clearToInside = false; 2151e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com done = true; 2161e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com break; 2170f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com case SkRegion::kIntersect_Op: 2181e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // if this element contains the entire bounds then we 2191e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // can skip it. 2201e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (kRect_ClipType == clip.getElementType(curr) 2216623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com && contains(clip.getRect(curr), bounds)) { 2221e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com break; 2231e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 2241e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // if everything is initially clearToInside then intersect is 2251e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // same as clear to 0 and treat as a replace. Otherwise, 2261e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // set stays empty. 2271e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (*clearToInside) { 2280f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com *startOp = SkRegion::kReplace_Op; 2291e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com *clearToInside = false; 2301e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com done = true; 2311e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 2321e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com break; 2331e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // we can skip a leading union. 2340f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com case SkRegion::kUnion_Op: 2351e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // if everything is initially outside then union is 2361e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // same as replace. Otherwise, every pixel is still 2371e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // clearToInside 2381e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (!*clearToInside) { 2390f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com *startOp = SkRegion::kReplace_Op; 2401e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com done = true; 2411e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 2421e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com break; 2430f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com case SkRegion::kXOR_Op: 2441e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // xor is same as difference or replace both of which 2451e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // can be 1-pass instead of 2 for xor. 2461e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (*clearToInside) { 2470f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com *startOp = SkRegion::kDifference_Op; 2481e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } else { 2490f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com *startOp = SkRegion::kReplace_Op; 2501e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 2511e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com done = true; 2521e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com break; 2530f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com case SkRegion::kDifference_Op: 2541e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // if all pixels are clearToInside then we have to process the 2551e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // difference, otherwise it has no effect and all pixels 2561e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // remain outside. 2571e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (*clearToInside) { 2580f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com *startOp = SkRegion::kDifference_Op; 2591e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com done = true; 2601e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 2611e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com break; 2620f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com case SkRegion::kReverseDifference_Op: 2631e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // if all pixels are clearToInside then reverse difference 2641e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // produces empty set. Otherise it is same as replace 2651e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (*clearToInside) { 2661e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com *clearToInside = false; 2671e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } else { 2680f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com *startOp = SkRegion::kReplace_Op; 2691e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com done = true; 2701e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 2711e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com break; 2721e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com default: 2731e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrCrash("Unknown set op."); 2741e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 2751e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 2761e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com return done ? curr-1 : count; 2771e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com} 278f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 279f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com} 280f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 281f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 282f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.comnamespace { 283f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 284f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 285f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com// set up the OpenGL blend function to perform the specified 286f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com// boolean operation for alpha clip mask creation 2876b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.comvoid setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) { 288f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 289f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com switch (op) { 290f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com case SkRegion::kReplace_Op: 291f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff); 292f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com break; 293f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com case SkRegion::kIntersect_Op: 294f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setBlendFunc(kDC_BlendCoeff, kZero_BlendCoeff); 295f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com break; 296f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com case SkRegion::kUnion_Op: 297f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setBlendFunc(kOne_BlendCoeff, kISC_BlendCoeff); 298f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com break; 299f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com case SkRegion::kXOR_Op: 300f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setBlendFunc(kIDC_BlendCoeff, kISC_BlendCoeff); 301f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com break; 302f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com case SkRegion::kDifference_Op: 303f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setBlendFunc(kZero_BlendCoeff, kISC_BlendCoeff); 304f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com break; 305f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com case SkRegion::kReverseDifference_Op: 306f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setBlendFunc(kIDC_BlendCoeff, kZero_BlendCoeff); 307f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com break; 308f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com default: 309f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrAssert(false); 310f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com break; 311f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 312f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com} 313f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 314f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com} 315f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 316f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 317f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.combool GrClipMaskManager::drawPath(GrGpu* gpu, 3188d033a1b125886c62906d975b5cc28a382064526bsalomon@google.com const SkPath& path, 319f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrPathFill fill, 320f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com bool doAA) { 321f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 322f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrPathRenderer* pr = this->getClipPathRenderer(gpu, path, fill, doAA); 323f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (NULL == pr) { 324f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return false; 325f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 326f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 327f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com pr->drawPath(path, fill, NULL, gpu, 0, doAA); 328f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return true; 329f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com} 330f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 331f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 332f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.combool GrClipMaskManager::drawClipShape(GrGpu* gpu, 333f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrTexture* target, 334f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com const GrClip& clipIn, 335f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com int index) { 336f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrDrawState* drawState = gpu->drawState(); 337f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrAssert(NULL != drawState); 338f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 339f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setRenderTarget(target->asRenderTarget()); 340f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 341f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (kRect_ClipType == clipIn.getElementType(index)) { 342f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (clipIn.getDoAA(index)) { 343f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // convert the rect to a path for AA 344f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com SkPath temp; 345f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com temp.addRect(clipIn.getRect(index)); 346f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 347f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return this->drawPath(gpu, temp, 348f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com kEvenOdd_PathFill, clipIn.getDoAA(index)); 349f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } else { 350f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com gpu->drawSimpleRect(clipIn.getRect(index), NULL, 0); 351f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 352f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } else { 353f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return this->drawPath(gpu, 354f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com clipIn.getPath(index), 355f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com clipIn.getPathFill(index), 356f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com clipIn.getDoAA(index)); 357f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 358f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return true; 359f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com} 360f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 361f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.comvoid GrClipMaskManager::drawTexture(GrGpu* gpu, 362f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrTexture* target, 363f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrTexture* texture) { 364f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrDrawState* drawState = gpu->drawState(); 365f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrAssert(NULL != drawState); 366f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 367f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // no AA here since it is encoded in the texture 368f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setRenderTarget(target->asRenderTarget()); 369f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 370f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrMatrix sampleM; 371f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com sampleM.setIDiv(texture->width(), texture->height()); 372f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setTexture(0, texture); 373f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 374f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 375f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrSamplerState::kNearest_Filter, 376f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com sampleM); 377f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 378f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com GrRect rect = GrRect::MakeWH(SkIntToScalar(target->width()), 379f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com SkIntToScalar(target->height())); 380f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com 381f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com gpu->drawSimpleRect(rect, NULL, 1 << 0); 382f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 383f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setTexture(0, NULL); 384f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com} 385f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 386f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.comnamespace { 387f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 388f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.comvoid clear(GrGpu* gpu, 389f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrTexture* target, 390f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrColor color) { 391f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrDrawState* drawState = gpu->drawState(); 392f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrAssert(NULL != drawState); 393f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 394f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // zap entire target to specified color 395f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->setRenderTarget(target->asRenderTarget()); 396f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com gpu->clear(NULL, color); 397f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com} 398f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 399f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com} 400f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com 4016d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com// get a texture to act as a temporary buffer for AA clip boolean operations 4026d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com// TODO: given the expense of createTexture we may want to just cache this too 4036623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.comvoid GrClipMaskManager::getTemp(const GrIRect& bounds, 404f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com GrAutoScratchTexture* temp) { 405f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com if (NULL != temp->texture()) { 4066d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com // we've already allocated the temp texture 4076d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com return; 4086d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com } 4096d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com 4106b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com const GrTextureDesc desc = { 4116b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit, 4126623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com bounds.width(), 4136623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com bounds.height(), 4146b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com kAlpha_8_GrPixelConfig, 4156b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 0 // samples 4166b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com }; 4176b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 418f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com temp->set(fAACache.getContext(), desc); 4196d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com} 4206d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com 4216d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com 422f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.comvoid GrClipMaskManager::setupCache(const GrClip& clipIn, 4236623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com const GrIRect& bounds) { 424f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com // Since we are setting up the cache we know the last lookup was a miss 425f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com // Free up the currently cached mask so it can be reused 426f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com fAACache.reset(); 4276d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com 428f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com const GrTextureDesc desc = { 429f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit, 4306623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com bounds.width(), 4316623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com bounds.height(), 432f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com kAlpha_8_GrPixelConfig, 433f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com 0 // samples 434f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com }; 435f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 436f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com fAACache.acquireMask(clipIn, desc, bounds); 437f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com} 438f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 4396b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 4406b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com// Shared preamble between gpu and SW-only AA clip mask creation paths. 4416b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com// Handles caching, determination of clip mask bound & allocation (if needed) 4426b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com// of the result texture 4436b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com// Returns true if there is no more work to be done (i.e., we got a cache hit) 4446b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.combool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu, 4456b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com const GrClip& clipIn, 4466b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com GrTexture** result, 4476623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com GrIRect *resultBounds) { 448f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrDrawState* origDrawState = gpu->drawState(); 449f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrAssert(origDrawState->isClipState()); 450f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 451f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrRenderTarget* rt = origDrawState->getRenderTarget(); 452f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrAssert(NULL != rt); 453f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 454f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrRect rtRect; 455f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com rtRect.setLTRB(0, 0, 456f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrIntToScalar(rt->width()), GrIntToScalar(rt->height())); 457f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 458f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // unlike the stencil path the alpha path is not bound to the size of the 459f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // render target - determine the minimum size required for the mask 460f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrRect bounds; 461f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 462f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (clipIn.hasConservativeBounds()) { 463f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com bounds = clipIn.getConservativeBounds(); 464f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (!bounds.intersect(rtRect)) { 465f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // the mask will be empty in this case 466f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrAssert(false); 467f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com bounds.setEmpty(); 468f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 469f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } else { 470f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // still locked to the size of the render target 471f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com bounds = rtRect; 472f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 473f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 4746623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com GrIRect intBounds; 4756623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com bounds.roundOut(&intBounds); 476f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 477f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // need to outset a pixel since the standard bounding box computation 478f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // path doesn't leave any room for antialiasing (esp. w.r.t. rects) 4796623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com intBounds.outset(1, 1); 480f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 481a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com // TODO: make sure we don't outset if bounds are still 0,0 @ min 482a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com 4838fff356c8505f2ac78e1fc9dc17c1192e3a608e4robertphillips@google.com if (fAACache.canReuse(clipIn, 4846623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com intBounds.width(), 4856623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com intBounds.height())) { 4868fff356c8505f2ac78e1fc9dc17c1192e3a608e4robertphillips@google.com *result = fAACache.getLastMask(); 4878fff356c8505f2ac78e1fc9dc17c1192e3a608e4robertphillips@google.com fAACache.getLastBound(resultBounds); 4888fff356c8505f2ac78e1fc9dc17c1192e3a608e4robertphillips@google.com return true; 4898fff356c8505f2ac78e1fc9dc17c1192e3a608e4robertphillips@google.com } 4908fff356c8505f2ac78e1fc9dc17c1192e3a608e4robertphillips@google.com 4916623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com this->setupCache(clipIn, intBounds); 492f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com 4936623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com *resultBounds = intBounds; 4946b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com return false; 4956b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com} 496f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 4976b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 4986b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com// Create a 8-bit clip mask in alpha 4996b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.combool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu, 5006b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com const GrClip& clipIn, 5016b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com GrTexture** result, 5026623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com GrIRect *resultBounds) { 5036b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 504f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds)) { 5056b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com return true; 5066b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com } 507f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 508f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com GrTexture* accum = fAACache.getLastMask(); 5096d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com if (NULL == accum) { 510f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com fClipMaskInAlpha = false; 511f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com fAACache.reset(); 512f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return false; 513f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 514f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 515f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit); 516f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrDrawState* drawState = gpu->drawState(); 517f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 518f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrDrawTarget::AutoGeometryPush agp(gpu); 519f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 520f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com int count = clipIn.getElementCount(); 521f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 5226b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) { 523f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // if we were able to trim down the size of the mask we need to 524f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // offset the paths & rects that will be used to compute it 525f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrMatrix m; 526f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 5276623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com m.setTranslate(SkIntToScalar(-resultBounds->fLeft), 5286623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com SkIntToScalar(-resultBounds->fTop)); 529f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 5306d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com drawState->setViewMatrix(m); 531f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 532f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 533f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com bool clearToInside; 534f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com SkRegion::Op startOp = SkRegion::kReplace_Op; // suppress warning 535f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com int start = process_initial_clip_elements(clipIn, 5366b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com *resultBounds, 537f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com &clearToInside, 538f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com &startOp); 539f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 5406d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com clear(gpu, accum, clearToInside ? 0xffffffff : 0x00000000); 541f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 542f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com GrAutoScratchTexture temp; 5436b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 544f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // walk through each clip element and perform its set op 545f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com for (int c = start; c < count; ++c) { 546f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 547f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com SkRegion::Op op = (c == start) ? startOp : clipIn.getOp(c); 548f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 549f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (SkRegion::kReplace_Op == op) { 550f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // TODO: replace is actually a lot faster then intersection 551f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // for this path - refactor the stencil path so it can handle 552f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // replace ops and alter GrClip to allow them through 553f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 554f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // clear the accumulator and draw the new object directly into it 5556d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com clear(gpu, accum, 0x00000000); 556f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 5576b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com setup_boolean_blendcoeffs(drawState, op); 558f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com this->drawClipShape(gpu, accum, clipIn, c); 559f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 560f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } else if (SkRegion::kReverseDifference_Op == op || 561f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com SkRegion::kIntersect_Op == op) { 562f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // there is no point in intersecting a screen filling rectangle. 563f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (SkRegion::kIntersect_Op == op && 564f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com kRect_ClipType == clipIn.getElementType(c) && 5656623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com contains(clipIn.getRect(c), *resultBounds)) { 566f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com continue; 567f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 568f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 569f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com getTemp(*resultBounds, &temp); 570f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com if (NULL == temp.texture()) { 5716d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com fClipMaskInAlpha = false; 572f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com fAACache.reset(); 5736d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com return false; 5746d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com } 5756d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com 576f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // clear the temp target & draw into it 577f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com clear(gpu, temp.texture(), 0x00000000); 578f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 5796b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op); 580f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com this->drawClipShape(gpu, temp.texture(), clipIn, c); 581f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 582f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // TODO: rather than adding these two translations here 583f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // compute the bounding box needed to render the texture 584f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // into temp 5856b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) { 586f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrMatrix m; 587f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 5886623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com m.setTranslate(SkIntToScalar(resultBounds->fLeft), 5896623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com SkIntToScalar(resultBounds->fTop)); 590f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 591f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->preConcatViewMatrix(m); 592f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 593f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 594f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // Now draw into the accumulator using the real operation 595f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // and the temp buffer as a texture 5966b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com setup_boolean_blendcoeffs(drawState, op); 597f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com this->drawTexture(gpu, accum, temp.texture()); 598f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 5996b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) { 600f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrMatrix m; 601f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 6026623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com m.setTranslate(SkIntToScalar(-resultBounds->fLeft), 6036623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com SkIntToScalar(-resultBounds->fTop)); 604f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 605f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com drawState->preConcatViewMatrix(m); 606f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 607f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 608f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } else { 609f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // all the remaining ops can just be directly draw into 610f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com // the accumulation buffer 6116b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com setup_boolean_blendcoeffs(drawState, op); 612f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com this->drawClipShape(gpu, accum, clipIn, c); 613f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 614f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com } 615f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 616a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com *result = accum; 6176d62df404bf420bedff4d7b5edd061740a673d44robertphillips@google.com 618f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return true; 6191e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com} 6201e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 621f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 6221e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com// Create a 1-bit clip mask in the stencil buffer 6231e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.combool GrClipMaskManager::createStencilClipMask(GrGpu* gpu, 6241e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com const GrClip& clipIn, 6251e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com const GrRect& bounds, 6261e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com ScissoringSettings* scissorSettings) { 6271e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6281e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrAssert(fClipMaskInStencil); 6291e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6301e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrDrawState* drawState = gpu->drawState(); 6311e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrAssert(drawState->isClipState()); 6321e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6331e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrRenderTarget* rt = drawState->getRenderTarget(); 6341e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrAssert(NULL != rt); 6351e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6361e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // TODO: dynamically attach a SB when needed. 6371e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrStencilBuffer* stencilBuffer = rt->getStencilBuffer(); 6381e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (NULL == stencilBuffer) { 6391e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com return false; 6401e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 6411e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6421e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (stencilBuffer->mustRenderClip(clipIn, rt->width(), rt->height())) { 6431e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6441e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com stencilBuffer->setLastClip(clipIn, rt->width(), rt->height()); 6451e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6461e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // we set the current clip to the bounds so that our recursive 6471e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // draws are scissored to them. We use the copy of the complex clip 6481e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // we just stashed on the SB to render from. We set it back after 6491e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // we finish drawing it into the stencil. 6501e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com const GrClip& clipCopy = stencilBuffer->getLastClip(); 6511e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->setClip(GrClip(bounds)); 6521e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6531e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit); 6541e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com drawState = gpu->drawState(); 6551e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com drawState->setRenderTarget(rt); 6561e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrDrawTarget::AutoGeometryPush agp(gpu); 6571e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6581e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->disableScissor(); 6591e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#if !VISUALIZE_COMPLEX_CLIP 6601e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com drawState->enableState(GrDrawState::kNoColorWrites_StateBit); 6611e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com#endif 6621e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6631e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com int count = clipCopy.getElementCount(); 6641e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com int clipBit = stencilBuffer->bits(); 6651e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com SkASSERT((clipBit <= 16) && 6661e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com "Ganesh only handles 16b or smaller stencil buffers"); 6671e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com clipBit = (1 << (clipBit-1)); 6681e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6696623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com GrIRect rtRect = GrIRect::MakeWH(rt->width(), rt->height()); 6701e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6711e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bool clearToInside; 6720f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com SkRegion::Op startOp = SkRegion::kReplace_Op; // suppress warning 6731e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com int start = process_initial_clip_elements(clipCopy, 6741e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com rtRect, 6751e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com &clearToInside, 6761e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com &startOp); 6771e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6781e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->clearStencilClip(scissorSettings->fScissorRect, clearToInside); 6791e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6801e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // walk through each clip element and perform its set op 6811e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // with the existing clip. 6821e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com for (int c = start; c < count; ++c) { 6831e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrPathFill fill; 6841e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bool fillInverted; 6851e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // enabled at bottom of loop 6861e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com drawState->disableState(GrGpu::kModifyStencilClip_StateBit); 6871e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 6881e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bool canRenderDirectToStencil; // can the clip element be drawn 6896b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // directly to the stencil buffer 6906b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // with a non-inverted fill rule 6916b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // without extra passes to 6926b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // resolve in/out status. 6931e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 694f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com SkRegion::Op op = (c == start) ? startOp : clipCopy.getOp(c); 695f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com 6961e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrPathRenderer* pr = NULL; 6978d033a1b125886c62906d975b5cc28a382064526bsalomon@google.com const SkPath* clipPath = NULL; 6981e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (kRect_ClipType == clipCopy.getElementType(c)) { 6991e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com canRenderDirectToStencil = true; 7001e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fill = kEvenOdd_PathFill; 7011e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fillInverted = false; 7021e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // there is no point in intersecting a screen filling 7031e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // rectangle. 704f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com if (SkRegion::kIntersect_Op == op && 7056623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com contains(clipCopy.getRect(c), rtRect)) { 7061e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com continue; 7071e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7081e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } else { 7091e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fill = clipCopy.getPathFill(c); 7101e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fillInverted = GrIsFillInverted(fill); 7111e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fill = GrNonInvertedFill(fill); 7121e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com clipPath = &clipCopy.getPath(c); 713f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com pr = this->getClipPathRenderer(gpu, *clipPath, fill, false); 7141e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (NULL == pr) { 7151e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fClipMaskInStencil = false; 7161e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->setClip(clipCopy); // restore to the original 7171e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com return false; 7181e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7191e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com canRenderDirectToStencil = 7201e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com !pr->requiresStencilPass(*clipPath, fill, gpu); 7211e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7221e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 7231e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com int passes; 7241e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClipPasses]; 7251e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 7261e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com bool canDrawDirectToClip; // Given the renderer, the element, 7271e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // fill rule, and set operation can 7281e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // we render the element directly to 7291e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // stencil bit used for clipping. 7301e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com canDrawDirectToClip = 7311e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrStencilSettings::GetClipPasses(op, 7321e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com canRenderDirectToStencil, 7331e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com clipBit, 7341e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fillInverted, 7351e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com &passes, stencilSettings); 7361e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 7371e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // draw the element to the client stencil bits if necessary 7381e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (!canDrawDirectToClip) { 7391e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, 7401e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com kIncClamp_StencilOp, 7411e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com kIncClamp_StencilOp, 7421e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com kAlways_StencilFunc, 7431e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 0xffff, 7441e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 0x0000, 7451e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 0xffff); 7461e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com SET_RANDOM_COLOR 7471e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (kRect_ClipType == clipCopy.getElementType(c)) { 7481e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com *drawState->stencil() = gDrawToStencil; 7491e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->drawSimpleRect(clipCopy.getRect(c), NULL, 0); 7501e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } else { 7511e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (canRenderDirectToStencil) { 7521e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com *drawState->stencil() = gDrawToStencil; 7531e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com pr->drawPath(*clipPath, fill, NULL, gpu, 0, false); 7541e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } else { 7551e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com pr->drawPathToStencil(*clipPath, fill, gpu); 7561e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7571e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7581e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7591e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 7601e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // now we modify the clip bit by rendering either the clip 7611e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // element directly or a bounding rect of the entire clip. 7621e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com drawState->enableState(GrGpu::kModifyStencilClip_StateBit); 7631e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com for (int p = 0; p < passes; ++p) { 7641e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com *drawState->stencil() = stencilSettings[p]; 7651e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (canDrawDirectToClip) { 7661e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (kRect_ClipType == clipCopy.getElementType(c)) { 7671e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com SET_RANDOM_COLOR 7681e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->drawSimpleRect(clipCopy.getRect(c), NULL, 0); 7691e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } else { 7701e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com SET_RANDOM_COLOR 7711e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com pr->drawPath(*clipPath, fill, NULL, gpu, 0, false); 7721e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7731e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } else { 7741e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com SET_RANDOM_COLOR 7751e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->drawSimpleRect(bounds, NULL, 0); 7761e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7771e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7781e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7791e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // restore clip 7801e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com gpu->setClip(clipCopy); 7811e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // recusive draws would have disabled this since they drew with 7821e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // the clip bounds as clip. 7831e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fClipMaskInStencil = true; 7841e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 7851e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 7861e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com return true; 7871e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com} 7881e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 789f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 7906b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.combool GrClipMaskManager::createSoftwareClipMask(GrGpu* gpu, 7916b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com const GrClip& clipIn, 7926b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com GrTexture** result, 7936623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com GrIRect *resultBounds) { 7946b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 795f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds)) { 7966b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com return true; 7976b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com } 7986b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 799f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com GrTexture* accum = fAACache.getLastMask(); 8006b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com if (NULL == accum) { 8016b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com fClipMaskInAlpha = false; 802f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com fAACache.reset(); 8036b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com return false; 8046b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com } 8056b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8066b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com#if 0 8076b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com SkRasterClip rasterClip; 8086b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8096b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // TODO: refactor GrClip out of existance and use SkCanvas's ClipVisitor 8106b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // - may have to move it to SkClipStack 8116b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com for (int i = 0; i < clipIn.getElementCount(); ++i) { 8126b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com if (kRect_ClipType == clipIn.getElementType(i)) { 8136b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com rasterClip.op(clipIn.getRect(i), clipIn.getOp(i), clipIn.getDoAA(i)); 8146b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com } else { 8156b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com GrAssert(kPath_ClipType == clipIn.getElementType(i)); 8166b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8176b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com SkIPoint deviceSize = SkIPoint::Make(resultBounds->width(), 8186b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com resultBounds->height()); 8196b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8206b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com SkRasterClip::clipPathHelper(&rasterClip, 8216b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com clipIn.getPath(i), 8226b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com clipIn.getOp(i), 8236b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com clipIn.getDoAA(i), 8246b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com deviceSize); 8256b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com } 8266b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com } 8276b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8286b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com // TODO: need to get pixels out of SkRasterClip & into the texture! 8296b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com#endif 8306b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8316b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com *result = accum; 8326b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8336b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com return true; 8346b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com} 8356b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8366b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com 8376b70a7bd3328ea0a12be47b1a7f835c905f16147robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 8381e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.comGrPathRenderer* GrClipMaskManager::getClipPathRenderer(GrGpu* gpu, 8398d033a1b125886c62906d975b5cc28a382064526bsalomon@google.com const SkPath& path, 840f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrPathFill fill, 841f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com bool antiAlias) { 8421e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com if (NULL == fPathRendererChain) { 8431e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com fPathRendererChain = 8441e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com new GrPathRendererChain(gpu->getContext(), 845f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com GrPathRendererChain::kNone_UsageFlag); 8461e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com } 847f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com return fPathRendererChain->getPathRenderer(path, fill, gpu, antiAlias); 8481e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com} 8491e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com 850f294b773f0b2b9f05eb45b52dd3cb4d97b96af06robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 851f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.comvoid GrClipMaskManager::releaseResources() { 8521e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com // in case path renderer has any GrResources, start from scratch 8531e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com GrSafeSetNull(fPathRendererChain); 854f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com fAACache.releaseResources(); 8551e945b7e708c633d4aed937ebfce57d52ba21d83robertphillips@google.com} 856