127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 91fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com#include "GrContext.h" 101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com 11bfe2b9d3a290d0153b82617cd6b65a4814fe89e3jvanverth@google.com#include "GrAARectRenderer.h" 121d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt#include "GrAtlasTextContext.h" 130823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt#include "GrBatch.h" 147c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt#include "GrBatchFontCache.h" 150823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt#include "GrBatchTarget.h" 16e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt#include "GrBatchTest.h" 175478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "GrDefaultGeoProcFactory.h" 18453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon#include "GrGpuResource.h" 193582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h" 204784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "GrDrawTargetCaps.h" 215478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "GrGpu.h" 22dcb8ef9e866b2674e8f9a70b761fcc4fec87dbbecommit-bot@chromium.org#include "GrIndexBuffer.h" 234784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "GrInOrderDrawBuffer.h" 24e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com#include "GrLayerCache.h" 2581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrOvalRenderer.h" 2627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h" 27d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h" 286bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon#include "GrRenderTargetPriv.h" 290ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon#include "GrResourceCache.h" 30d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon#include "GrResourceProvider.h" 3172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com#include "GrSoftwarePathRenderer.h" 32c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen#include "GrStencilAndCoverTextContext.h" 33d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "GrStrokeInfo.h" 34afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrSurfacePriv.h" 35b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt#include "GrTextBlobCache.h" 36afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrTexturePriv.h" 37bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel#include "GrTraceMarker.h" 382a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org#include "GrTracing.h" 39cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon#include "GrVertices.h" 40d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "SkDashPathPriv.h" 4181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon#include "SkConfig8888.h" 427111d463cee893a479280c7af41757e709e33ef5reed@google.com#include "SkGr.h" 434784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "SkRRect.h" 445f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkStrokeRec.h" 45dcb8ef9e866b2674e8f9a70b761fcc4fec87dbbecommit-bot@chromium.org#include "SkTLazy.h" 464784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "SkTLS.h" 47933e65d914eb86b1fbbf8ea9cf1da58ac7c42500commit-bot@chromium.org#include "SkTraceEvent.h" 4827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 495478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "effects/GrConfigConversionEffect.h" 505478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "effects/GrDashingEffect.h" 515478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "effects/GrSingleTextureEffect.h" 525478d427c6e67c986a3390162c8fec77c466058ajoshualitt 53f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) 545f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#define RETURN_IF_ABANDONED if (!fDrawBuffer) { return; } 555f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#define RETURN_FALSE_IF_ABANDONED if (!fDrawBuffer) { return false; } 565f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#define RETURN_NULL_IF_ABANDONED if (!fDrawBuffer) { return NULL; } 57bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 58f21dab95405979a4aff9f6a741c818304a67f220bsalomonclass GrContext::AutoCheckFlush { 59f21dab95405979a4aff9f6a741c818304a67f220bsalomonpublic: 60f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); } 61f21dab95405979a4aff9f6a741c818304a67f220bsalomon 62f21dab95405979a4aff9f6a741c818304a67f220bsalomon ~AutoCheckFlush() { 63f21dab95405979a4aff9f6a741c818304a67f220bsalomon if (fContext->fFlushToReduceCacheSize) { 64f21dab95405979a4aff9f6a741c818304a67f220bsalomon fContext->flush(); 65f21dab95405979a4aff9f6a741c818304a67f220bsalomon } 66f21dab95405979a4aff9f6a741c818304a67f220bsalomon } 67f21dab95405979a4aff9f6a741c818304a67f220bsalomon 68f21dab95405979a4aff9f6a741c818304a67f220bsalomonprivate: 69f21dab95405979a4aff9f6a741c818304a67f220bsalomon GrContext* fContext; 70f21dab95405979a4aff9f6a741c818304a67f220bsalomon}; 71f21dab95405979a4aff9f6a741c818304a67f220bsalomon 729c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevskiGrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext, 739c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski const Options* opts) { 749c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski GrContext* context; 759c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski if (NULL == opts) { 769c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski context = SkNEW_ARGS(GrContext, (Options())); 779c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski } else { 789c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski context = SkNEW_ARGS(GrContext, (*opts)); 799c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski } 809c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski 816e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com if (context->init(backend, backendContext)) { 826e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return context; 836e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com } else { 846e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com context->unref(); 856e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return NULL; 8627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 8727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 8827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 890acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualittstatic int32_t gNextID = 1; 900acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualittstatic int32_t next_id() { 910acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt int32_t id; 920acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt do { 930acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt id = sk_atomic_inc(&gNextID); 940acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt } while (id == SK_InvalidGenID); 950acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt return id; 960acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt} 970acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt 980acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualittGrContext::GrContext(const Options& opts) : fOptions(opts), fUniqueID(next_id()) { 996e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fGpu = NULL; 100d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon fResourceCache = NULL; 101d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon fResourceProvider = NULL; 1026e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fPathRendererChain = NULL; 1036e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fSoftwarePathRenderer = NULL; 1047c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt fBatchFontCache = NULL; 1056e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBuffer = NULL; 106f21dab95405979a4aff9f6a741c818304a67f220bsalomon fFlushToReduceCacheSize = false; 1076e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fAARectRenderer = NULL; 10881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org fOvalRenderer = NULL; 10944a91dcf2542c2aa93f159ebbb5bf813ae7362c0robertphillips@google.com fMaxTextureSizeOverride = 1 << 20; 1106e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com} 1116e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1126e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.combool GrContext::init(GrBackend backend, GrBackendContext backendContext) { 113f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fGpu); 1146e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1156e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fGpu = GrGpu::Create(backend, backendContext, this); 1166e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com if (NULL == fGpu) { 1176e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return false; 1186e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com } 119334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon this->initCommon(); 120334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon return true; 121334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon} 1226e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 123334355742137cc238887d4f85856e6c4d9ec8aa8bsalomonvoid GrContext::initCommon() { 1240ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon fResourceCache = SkNEW(GrResourceCache); 1250ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon fResourceCache->setOverBudgetCallback(OverBudgetCB, this); 126d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon fResourceProvider = SkNEW_ARGS(GrResourceProvider, (fGpu, fResourceCache)); 1271836d337a85b82689287231091823f404d8cab43commit-bot@chromium.org 1284ec84da746d66e1bcb76ab2f8b94602b8e966589robertphillips fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this))); 129e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com 130ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon fAARectRenderer = SkNEW(GrAARectRenderer); 131ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon fOvalRenderer = SkNEW(GrOvalRenderer); 1326e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1336e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDidTestPMConversions = false; 1346e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 135e40d39725908d99d255496025411e5c9ca32663erobertphillips fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (this)); 1367c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt 1377c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt // GrBatchFontCache will eventually replace GrFontCache 13862db8ba68b980245e0927b792747864ebd6fcb6ajoshualitt fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this)); 139b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt 1400db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt fTextBlobCache.reset(SkNEW_ARGS(GrTextBlobCache, (TextBlobCacheOverBudgetCB, this))); 141c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 142c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 14327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() { 144733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com if (NULL == fGpu) { 145733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com return; 146733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com } 147733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com 1488fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 1495acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 150950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com for (int i = 0; i < fCleanUpData.count(); ++i) { 151950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); 152950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com } 153950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com 154d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon SkDELETE(fResourceProvider); 1550ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDELETE(fResourceCache); 1567c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt SkDELETE(fBatchFontCache); 157334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon SkDELETE(fDrawBuffer); 1583008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 159f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->unref(); 16081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org fOvalRenderer->unref(); 161f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 162205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->unref(); 163a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeUnref(fPathRendererChain); 164a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeUnref(fSoftwarePathRenderer); 16527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 16627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1672354f8432a7205571f04f9638a0018fb0b1fb282bsalomonvoid GrContext::abandonContext() { 168d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon fResourceProvider->abandon(); 169205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // abandon first to so destructors 170205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // don't try to free the resources in the API. 1710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon fResourceCache->abandonAll(); 172c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon 173e3371304b8c06a29aa3581c8decd9046c712c5f6robertphillips fGpu->contextAbandoned(); 174205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1753008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources that 1763008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // are now unusable 177a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fPathRendererChain); 178a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fSoftwarePathRenderer); 1793008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 180e40d39725908d99d255496025411e5c9ca32663erobertphillips SkDELETE(fDrawBuffer); 1818fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 182205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1837c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt fBatchFontCache->freeAll(); 184e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com fLayerCache->freeAll(); 18526ffc00bfa09fe85c22ddcbeb0fc54c0eacb7859joshualitt fTextBlobCache->freeAll(); 1868fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1878fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1880a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.comvoid GrContext::resetContext(uint32_t state) { 1890a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fGpu->markContextDirty(state); 1908fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1918fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1928fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() { 1938fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 194fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 19549f085dddff10473b6ebf832a974288300224e60bsalomon if (fDrawBuffer) { 196c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon fDrawBuffer->purgeResources(); 197c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon } 198ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com 1997c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt fBatchFontCache->freeAll(); 200e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com fLayerCache->freeAll(); 2013008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources 202a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fPathRendererChain); 203a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fSoftwarePathRenderer); 2043033b9faac476fc22e264950764d3551a32e4db7bsalomon 2053033b9faac476fc22e264950764d3551a32e4db7bsalomon fResourceCache->purgeAllUnlocked(); 20627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 20727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 20895c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.orgvoid GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const { 20971cb0c241e439b6ed746b90294d0b6916644a644bsalomon if (resourceCount) { 2100ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon *resourceCount = fResourceCache->getBudgetedResourceCount(); 21171cb0c241e439b6ed746b90294d0b6916644a644bsalomon } 21271cb0c241e439b6ed746b90294d0b6916644a644bsalomon if (resourceBytes) { 2130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon *resourceBytes = fResourceCache->getBudgetedResourceBytes(); 21471cb0c241e439b6ed746b90294d0b6916644a644bsalomon } 215d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org} 216d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org 217c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunenGrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget, 2186e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkGpuDevice* gpuDevice, 219c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen const SkDeviceProperties& 220c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen leakyProperties, 221c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen bool enableDistanceFieldFonts) { 222e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth if (fGpu->caps()->shaderCaps()->pathRenderingSupport() && renderTarget->isMultisampled()) { 2238dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel GrStencilAttachment* sb = renderTarget->renderTargetPriv().attachStencilAttachment(); 2246bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon if (sb) { 2256e8cd9671958c69babde9338c5c18a4c3d895575joshualitt return GrStencilAndCoverTextContext::Create(this, gpuDevice, leakyProperties); 2266bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 2278c27a188a0b216021d439eb627622d17b9f78343jvanverth } 2288c27a188a0b216021d439eb627622d17b9f78343jvanverth 2299bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt return GrAtlasTextContext::Create(this, gpuDevice, leakyProperties, enableDistanceFieldFonts); 230c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen} 231c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen 232fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 233fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 234d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomonbool GrContext::isConfigTexturable(GrPixelConfig config) const { 235d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon return fGpu->caps()->isConfigTexturable(config); 236d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon} 237d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon 238d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomonbool GrContext::npotTextureTileSupport() const { 239d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon return fGpu->caps()->npotTextureTileSupport(); 240d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon} 241d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon 24271cb0c241e439b6ed746b90294d0b6916644a644bsalomonvoid GrContext::OverBudgetCB(void* data) { 24349f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(data); 244f21dab95405979a4aff9f6a741c818304a67f220bsalomon 245cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org GrContext* context = reinterpret_cast<GrContext*>(data); 246f21dab95405979a4aff9f6a741c818304a67f220bsalomon 247f21dab95405979a4aff9f6a741c818304a67f220bsalomon // Flush the InOrderDrawBuffer to possibly free up some textures 248f21dab95405979a4aff9f6a741c818304a67f220bsalomon context->fFlushToReduceCacheSize = true; 249cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org} 250cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 2510db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualittvoid GrContext::TextBlobCacheOverBudgetCB(void* data) { 2520db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt SkASSERT(data); 2530db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt 2540db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they 2550db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush. The solution is to move 2560db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt // drawText calls to below the GrContext level, but this is not trivial because they call 2570db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt // drawPath on SkGpuDevice 2580db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt GrContext* context = reinterpret_cast<GrContext*>(data); 2590db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt context->flush(); 2600db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt} 2610db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt 262919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const { 263972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); 264919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 265919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 266919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 267bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com return fGpu->caps()->maxRenderTargetSize(); 26827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 26927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2708a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.comint GrContext::getMaxSampleCount() const { 271bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com return fGpu->caps()->maxSampleCount(); 2728a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com} 2738a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com 27427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 27527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 276fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgvoid GrContext::clear(const SkIRect* rect, 27707ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com const GrColor color, 27856ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com bool canIgnoreRect, 27941ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon GrRenderTarget* renderTarget) { 2805f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 28141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon ASSERT_OWNED_RESOURCE(renderTarget); 28289c62980c1eb50b2090f33312086c7e8c66739b4bsalomon SkASSERT(renderTarget); 28389c62980c1eb50b2090f33312086c7e8c66739b4bsalomon 284f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 285d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this); 286570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(); 28741ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon if (NULL == target) { 28841ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return; 28941ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 29041ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon target->clear(rect, color, canIgnoreRect, renderTarget); 29127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 29227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 29325d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawPaint(GrRenderTarget* rt, 294570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 29525d9c154087d2132a51d1ca74a104726f60ef380joshualitt const GrPaint& origPaint, 29625d9c154087d2132a51d1ca74a104726f60ef380joshualitt const SkMatrix& viewMatrix) { 2975f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 29827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 29927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // don't overflow fixed-point implementations 300fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect r; 301d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com r.setLTRB(0, 0, 30225d9c154087d2132a51d1ca74a104726f60ef380joshualitt SkIntToScalar(rt->width()), 30325d9c154087d2132a51d1ca74a104726f60ef380joshualitt SkIntToScalar(rt->height())); 3045dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkTCopyOnFirstWrite<GrPaint> paint(origPaint); 3058fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt 3068fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt // by definition this fills the entire clip, no need for AA 3078fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt if (paint->isAntiAlias()) { 3088fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt paint.writable()->setAntiAlias(false); 3098fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt } 3108fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt 3118fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt bool isPerspective = viewMatrix.hasPerspective(); 3128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 3134f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 3144f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // map the four corners and bound them with a new rect. This will not 3154f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // produce a correct result for some perspective matrices. 3168fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt if (!isPerspective) { 3175531d51ce7426bdae7563547326fcf0bf926a083joshualitt SkMatrix inverse; 3185531d51ce7426bdae7563547326fcf0bf926a083joshualitt if (!viewMatrix.invert(&inverse)) { 31938406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("Could not invert matrix\n"); 3208c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 3218c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 32227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com inverse.mapRect(&r); 323570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt this->drawRect(rt, clip, *paint, viewMatrix, r); 32427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 3258fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt SkMatrix localMatrix; 3268fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt if (!viewMatrix.invert(&localMatrix)) { 32738406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("Could not invert matrix\n"); 3283cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com return; 3298c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 3308fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt 3318fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt AutoCheckFlush acf(this); 3328dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 333570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, paint, &acf); 3348fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt if (NULL == target) { 3358fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt return; 3368fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt } 3378fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt 3388fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt GR_CREATE_TRACE_MARKER("GrContext::drawPaintWithPerspective", target); 33944701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt target->drawRect(&pipelineBuilder, 34044701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt paint->getColor(), 34144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt SkMatrix::I(), 34244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt r, 34344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt NULL, 34444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt &localMatrix); 34527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 34627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 34727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 348205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 349205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 350c30aaa0e40a2957b847910f80665616e0d103d50bsalomonstatic inline bool is_irect(const SkRect& r) { 35138406c82b913350e55fa04af8c1941cd9b4aff52tfarina return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && 35238406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); 353c30aaa0e40a2957b847910f80665616e0d103d50bsalomon} 354c30aaa0e40a2957b847910f80665616e0d103d50bsalomon 355205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 3568dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 3579853ccef19c200be93a6211f32589fa82a53067cjoshualitt SkRect* devBoundRect, 358fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& rect, 359df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com SkScalar strokeWidth, 3602e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt const SkMatrix& combinedMatrix, 3612e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color) { 3628dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel if (pipelineBuilder->getRenderTarget()->isMultisampled()) { 363205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 364205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 365205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3664b140b5fbedcb75d0b9587fa9d232ce54d9c7eb5robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 367df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com if (strokeWidth >= 0) { 368df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com#endif 36924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!combinedMatrix.preservesAxisAlignment()) { 370df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com return false; 371df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } 372205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3734b140b5fbedcb75d0b9587fa9d232ce54d9c7eb5robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 374df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } else { 37524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!combinedMatrix.preservesRightAngles()) { 376df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com return false; 377df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } 378205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 379df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com#endif 380205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 38124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org combinedMatrix.mapRect(devBoundRect, rect); 382e638d1c29b2895a4dcf41b5bc8868278192bf819derekf if (!combinedMatrix.rectStaysRect()) { 383e638d1c29b2895a4dcf41b5bc8868278192bf819derekf return true; 384e638d1c29b2895a4dcf41b5bc8868278192bf819derekf } 385e638d1c29b2895a4dcf41b5bc8868278192bf819derekf 386c30aaa0e40a2957b847910f80665616e0d103d50bsalomon if (strokeWidth < 0) { 387c30aaa0e40a2957b847910f80665616e0d103d50bsalomon return !is_irect(*devBoundRect); 388c30aaa0e40a2957b847910f80665616e0d103d50bsalomon } 38928ac96e40d705f7fb08a61ac027e15de8d91823crobertphillips@google.com 3909c0822a4150e23cec9f9b72bd1abc2c5f9ea5a3bbsalomon return true; 391205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 392205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 39324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.orgstatic inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) { 39424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return point.fX >= rect.fLeft && point.fX <= rect.fRight && 39524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org point.fY >= rect.fTop && point.fY <= rect.fBottom; 39624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org} 39724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 3980823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittclass StrokeRectBatch : public GrBatch { 3990823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittpublic: 4000823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt struct Geometry { 4010823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrColor fColor; 4020823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkMatrix fViewMatrix; 4030823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkRect fRect; 4040823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkScalar fStrokeWidth; 4050823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt }; 4060823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4074c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt static GrBatch* Create(const Geometry& geometry, bool snapToPixelCenters) { 4084c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt return SkNEW_ARGS(StrokeRectBatch, (geometry, snapToPixelCenters)); 4090823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 4100823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 41136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "StrokeRectBatch"; } 4120823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 41336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 4140823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // When this is called on a batch, there is only one geometry bundle 4150823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt out->setKnownFourComponents(fGeoData[0].fColor); 4160823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 4170823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 41836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 4190823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt out->setKnownSingleComponent(0xff); 4200823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 4210823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 42236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(const GrPipelineInfo& init) override { 4230823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // Handle any color overrides 4240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (init.fColorIgnored) { 4250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 4260823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else if (GrColor_ILLEGAL != init.fOverrideColor) { 4270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fGeoData[0].fColor = init.fOverrideColor; 4280823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 4290823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4300823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // setup batch properties 4310823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fColorIgnored = init.fColorIgnored; 4320823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fColor = fGeoData[0].fColor; 4330823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 4340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fCoverageIgnored = init.fCoverageIgnored; 4350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 4360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 43736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 4380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkAutoTUnref<const GrGeometryProcessor> gp( 4390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType, 4400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt this->color(), 4410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt this->viewMatrix(), 4420823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkMatrix::I())); 4430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt batchTarget->initDraw(gp, pipeline); 4450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // TODO this is hacky, but the only way we have to initialize the GP is to use the 4470823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch 4480823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // everywhere we can remove this nastiness 4490823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrPipelineInfo init; 4500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt init.fColorIgnored = fBatch.fColorIgnored; 4510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt init.fOverrideColor = GrColor_ILLEGAL; 4520823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt init.fCoverageIgnored = fBatch.fCoverageIgnored; 4530823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt init.fUsesLocalCoords = this->usesLocalCoords(); 4540823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt gp->initBatchTracker(batchTarget->currentBatchTracker(), init); 4550823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt size_t vertexStride = gp->getVertexStride(); 4570823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr)); 4590823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt Geometry& args = fGeoData[0]; 4610823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4620823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int vertexCount = kVertsPerHairlineRect; 4630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (args.fStrokeWidth > 0) { 4640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt vertexCount = kVertsPerStrokeRect; 4650823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 4660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4670823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const GrVertexBuffer* vertexBuffer; 4680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int firstVertex; 4690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 470e40d39725908d99d255496025411e5c9ca32663erobertphillips void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount, 471e40d39725908d99d255496025411e5c9ca32663erobertphillips &vertexBuffer, &firstVertex); 4720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 473cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon if (!verts) { 4744b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate vertices\n"); 4754b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 4764b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 4774b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 478cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon SkPoint* vertex = reinterpret_cast<SkPoint*>(verts); 4790823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4800823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrPrimitiveType primType; 4810823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 4820823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (args.fStrokeWidth > 0) {; 4830823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt primType = kTriangleStrip_GrPrimitiveType; 4840823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt args.fRect.sort(); 4850823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt this->setStrokeRectStrip(vertex, args.fRect, args.fStrokeWidth); 4860823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else { 4870823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // hairline 4880823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt primType = kLineStrip_GrPrimitiveType; 4890823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt vertex[0].set(args.fRect.fLeft, args.fRect.fTop); 4900823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt vertex[1].set(args.fRect.fRight, args.fRect.fTop); 4910823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt vertex[2].set(args.fRect.fRight, args.fRect.fBottom); 4920823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt vertex[3].set(args.fRect.fLeft, args.fRect.fBottom); 4930823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt vertex[4].set(args.fRect.fLeft, args.fRect.fTop); 4940823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 4950823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 496cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon GrVertices vertices; 497cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon vertices.init(primType, vertexBuffer, firstVertex, vertexCount); 498cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon batchTarget->draw(vertices); 4990823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 5000823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5010823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 5020823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5030823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittprivate: 5044c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt StrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) { 5050823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt this->initClassID<StrokeRectBatch>(); 5060823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5070823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fHairline = geometry.fStrokeWidth == 0; 5080823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5090823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fGeoData.push_back(geometry); 51099c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 51199c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt // setup bounds 51299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt fBounds = geometry.fRect; 51399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt SkScalar rad = SkScalarHalf(geometry.fStrokeWidth); 51499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt fBounds.outset(rad, rad); 51599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt geometry.fViewMatrix.mapRect(&fBounds); 5164c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt 5174c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt // If our caller snaps to pixel centers then we have to round out the bounds 5184c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt if (snapToPixelCenters) { 5194c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt fBounds.roundOut(); 5204c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt } 5210823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 5220823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5230823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt /* create a triangle strip that strokes the specified rect. There are 8 5240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt unique vertices, but we repeat the last 2 to close up. Alternatively we 5250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt could use an indices array, and then only send 8 verts, but not sure that 5260823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt would be faster. 5270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt */ 5280823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt void setStrokeRectStrip(SkPoint verts[10], const SkRect& rect, SkScalar width) { 5290823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const SkScalar rad = SkScalarHalf(width); 5300823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // TODO we should be able to enable this assert, but we'd have to filter these draws 5310823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // this is a bug 5320823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt //SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2); 5330823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[0].set(rect.fLeft + rad, rect.fTop + rad); 5350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[1].set(rect.fLeft - rad, rect.fTop - rad); 5360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[2].set(rect.fRight - rad, rect.fTop + rad); 5370823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[3].set(rect.fRight + rad, rect.fTop - rad); 5380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[4].set(rect.fRight - rad, rect.fBottom - rad); 5390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[5].set(rect.fRight + rad, rect.fBottom + rad); 5400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 5410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 5420823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[8] = verts[0]; 5430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt verts[9] = verts[1]; 5440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 5450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5470823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrColor color() const { return fBatch.fColor; } 5480823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 5490823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool colorIgnored() const { return fBatch.fColorIgnored; } 5500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 5510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool hairline() const { return fBatch.fHairline; } 5520823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 55336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onCombineIfPossible(GrBatch* t) override { 5540823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // StrokeRectBatch* that = t->cast<StrokeRectBatch>(); 5550823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // NonAA stroke rects cannot batch right now 5570823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // TODO make these batchable 5580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return false; 5590823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 5600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5610823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt struct BatchTracker { 5620823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrColor fColor; 5630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fUsesLocalCoords; 5640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fColorIgnored; 5650823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fCoverageIgnored; 5660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fHairline; 5670823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt }; 5680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const static int kVertsPerHairlineRect = 5; 5700823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const static int kVertsPerStrokeRect = 10; 5710823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 5720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt BatchTracker fBatch; 5730823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkSTArray<1, Geometry, true> fGeoData; 5740823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt}; 5750823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 57625d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawRect(GrRenderTarget* rt, 577570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 57825d9c154087d2132a51d1ca74a104726f60ef380joshualitt const GrPaint& paint, 5795531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 580fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& rect, 58101c8da1eef36570374f7e8764a38b25bf16ab7a6bsalomon const GrStrokeInfo* strokeInfo) { 5825f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 58349f085dddff10473b6ebf832a974288300224e60bsalomon if (strokeInfo && strokeInfo->isDashed()) { 584d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkPath path; 585d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel path.addRect(rect); 586570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt this->drawPath(rt, clip, paint, viewMatrix, path, *strokeInfo); 587d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel return; 588d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel } 589d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 590f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 5918dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 592570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); 59341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon if (NULL == target) { 59441ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return; 59541ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 59627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5972a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); 598d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWidth(); 59924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 60024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking 60124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // cases where the RT is fully inside a stroke. 60224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (width < 0) { 60324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect rtRect; 6048dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel pipelineBuilder.getRenderTarget()->getBoundsRect(&rtRect); 60524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect clipSpaceRTRect = rtRect; 606570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType(); 60744701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt if (checkClip) { 608570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX), 609570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt SkIntToScalar(clip.origin().fY)); 61024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 61124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Does the clip contain the entire RT? 612570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt if (!checkClip || clip.quickContains(clipSpaceRTRect)) { 61324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkMatrix invM; 6148059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!viewMatrix.invert(&invM)) { 61524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return; 61624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 61724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Does the rect bound the RT? 61824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkPoint srcSpaceRTQuad[4]; 61924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org invM.mapRectToQuad(srcSpaceRTQuad, rtRect); 62024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) && 62124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[1]) && 62224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[2]) && 62324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[3])) { 62424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Will it blend? 62524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org GrColor clearColor; 62624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (paint.isOpaqueAndConstantColor(&clearColor)) { 62725d9c154087d2132a51d1ca74a104726f60ef380joshualitt target->clear(NULL, clearColor, true, rt); 62824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return; 62924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 63024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 63124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 63224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 63324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 6342e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color = paint.getColor(); 63524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect devBoundRect; 6368dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel bool needAA = paint.isAntiAlias() && !pipelineBuilder.getRenderTarget()->isMultisampled(); 6378dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel bool doAA = needAA && apply_aa_to_rect(target, &pipelineBuilder, &devBoundRect, rect, width, 6388059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix, color); 639d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 640205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 641205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 642395ef0568dac793020f66cbec4b6ef86736d4db0bsalomon const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec(); 6439853ccef19c200be93a6211f32589fa82a53067cjoshualitt fAARectRenderer->strokeAARect(target, 6448dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel &pipelineBuilder, 6452e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt color, 6468059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix, 6479853ccef19c200be93a6211f32589fa82a53067cjoshualitt rect, 6489853ccef19c200be93a6211f32589fa82a53067cjoshualitt devBoundRect, 6499853ccef19c200be93a6211f32589fa82a53067cjoshualitt strokeRec); 650205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 651df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com // filled AA rect 6528059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt fAARectRenderer->fillAARect(target, 6538dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel &pipelineBuilder, 6548059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt color, 6558059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix, 6568059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt rect, 657d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt devBoundRect); 658205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 659205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 660205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 661205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 66227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 6630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt StrokeRectBatch::Geometry geometry; 6640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt geometry.fViewMatrix = viewMatrix; 6650823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt geometry.fColor = color; 6660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt geometry.fRect = rect; 6670823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt geometry.fStrokeWidth = width; 6680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 6694c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt // Non-AA hairlines are snapped to pixel centers to make which pixels are hit deterministic 6704c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt bool snapToPixelCenters = (0 == width && !rt->isMultisampled()); 6714c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt SkAutoTUnref<GrBatch> batch(StrokeRectBatch::Create(geometry, snapToPixelCenters)); 6720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 673d79c549467e5e7be025e38357f179b7965ed2ec3bsalomon // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of 674d79c549467e5e7be025e38357f179b7965ed2ec3bsalomon // hairline rects. We jam all the vertices to pixel centers to avoid this, but not when MSAA 675d79c549467e5e7be025e38357f179b7965ed2ec3bsalomon // is enabled because it can cause ugly artifacts. 676d79c549467e5e7be025e38357f179b7965ed2ec3bsalomon pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag, 6774c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt snapToPixelCenters); 67899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt target->drawBatch(&pipelineBuilder, batch); 67927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 680df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com // filled BW rect 6818dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawSimpleRect(&pipelineBuilder, color, viewMatrix, rect); 68227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 68327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 68427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 68525d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawNonAARectToRect(GrRenderTarget* rt, 686570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 68725d9c154087d2132a51d1ca74a104726f60ef380joshualitt const GrPaint& paint, 68816b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt const SkMatrix& viewMatrix, 68916b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt const SkRect& rectToDraw, 69016b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt const SkRect& localRect, 69116b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt const SkMatrix* localMatrix) { 6925f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 693f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 6948dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 695570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); 69641ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon if (NULL == target) { 69741ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return; 69841ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 6996438695222333981fafee9c8c09f3bf51dce3816bsalomon@google.com 7002a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); 7012a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 70244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt target->drawRect(&pipelineBuilder, 70344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt paint.getColor(), 70444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt viewMatrix, 70544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt rectToDraw, 70644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt &localRect, 7078dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel localMatrix); 70827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 70927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 7100823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittstatic const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords, 7110823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool hasColors, 71256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt int* colorOffset, 71356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt int* texOffset, 7148059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt GrColor color, 7158059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix) { 716429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *texOffset = -1; 717429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *colorOffset = -1; 7185478d427c6e67c986a3390162c8fec77c466058ajoshualitt uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType; 7190823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (hasLocalCoords && hasColors) { 7205478d427c6e67c986a3390162c8fec77c466058ajoshualitt *colorOffset = sizeof(SkPoint); 7215478d427c6e67c986a3390162c8fec77c466058ajoshualitt *texOffset = sizeof(SkPoint) + sizeof(GrColor); 7225478d427c6e67c986a3390162c8fec77c466058ajoshualitt flags |= GrDefaultGeoProcFactory::kColor_GPType | 7235478d427c6e67c986a3390162c8fec77c466058ajoshualitt GrDefaultGeoProcFactory::kLocalCoord_GPType; 7240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else if (hasLocalCoords) { 725972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org *texOffset = sizeof(SkPoint); 7265478d427c6e67c986a3390162c8fec77c466058ajoshualitt flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType; 7270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else if (hasColors) { 728972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org *colorOffset = sizeof(SkPoint); 7295478d427c6e67c986a3390162c8fec77c466058ajoshualitt flags |= GrDefaultGeoProcFactory::kColor_GPType; 730429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } 7318059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt return GrDefaultGeoProcFactory::Create(flags, color, viewMatrix, SkMatrix::I()); 732429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com} 733429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 7340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittclass DrawVerticesBatch : public GrBatch { 7350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittpublic: 7360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt struct Geometry { 7370823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrColor fColor; 7380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkTDArray<SkPoint> fPositions; 7390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkTDArray<uint16_t> fIndices; 7400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkTDArray<GrColor> fColors; 7410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkTDArray<SkPoint> fLocalCoords; 7420823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt }; 7430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 7440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt static GrBatch* Create(const Geometry& geometry, GrPrimitiveType primitiveType, 7450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const SkMatrix& viewMatrix, 7460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const SkPoint* positions, int vertexCount, 7470823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const uint16_t* indices, int indexCount, 74899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt const GrColor* colors, const SkPoint* localCoords, 74999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt const SkRect& bounds) { 7500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return SkNEW_ARGS(DrawVerticesBatch, (geometry, primitiveType, viewMatrix, positions, 7510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt vertexCount, indices, indexCount, colors, 75299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt localCoords, bounds)); 7530823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 7540823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 75536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "DrawVerticesBatch"; } 7560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 75736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 7580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // When this is called on a batch, there is only one geometry bundle 7590823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasColors()) { 7600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt out->setUnknownFourComponents(); 7610823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else { 7620823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt out->setKnownFourComponents(fGeoData[0].fColor); 7630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 7640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 7650823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 76636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 767d4c7d55594d94a00b6cecf6b2fdbb811836ce2ffjoshualitt out->setKnownSingleComponent(0xff); 7680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 7690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 77036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(const GrPipelineInfo& init) override { 7710823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // Handle any color overrides 7720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (init.fColorIgnored) { 7730823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 7740823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else if (GrColor_ILLEGAL != init.fOverrideColor) { 7750823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fGeoData[0].fColor = init.fOverrideColor; 7760823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 7770823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 7780823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // setup batch properties 7790823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fColorIgnored = init.fColorIgnored; 7800823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fColor = fGeoData[0].fColor; 7810823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 7820823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fCoverageIgnored = init.fCoverageIgnored; 7830823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 7840823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 78536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 7860823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int colorOffset = -1, texOffset = -1; 7870823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkAutoTUnref<const GrGeometryProcessor> gp( 7880823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset, 7890823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt &texOffset, this->color(), this->viewMatrix())); 7900823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 7910823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt batchTarget->initDraw(gp, pipeline); 7920823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 7930823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // TODO this is hacky, but the only way we have to initialize the GP is to use the 7940823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch 7950823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // everywhere we can remove this nastiness 7960823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrPipelineInfo init; 7970823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt init.fColorIgnored = fBatch.fColorIgnored; 7980823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt init.fOverrideColor = GrColor_ILLEGAL; 7990823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt init.fCoverageIgnored = fBatch.fCoverageIgnored; 8000823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt init.fUsesLocalCoords = this->usesLocalCoords(); 8010823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt gp->initBatchTracker(batchTarget->currentBatchTracker(), init); 8020823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8030823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt size_t vertexStride = gp->getVertexStride(); 8040823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8050823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? sizeof(SkPoint) : 0) 8060823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt + (this->hasColors() ? sizeof(GrColor) : 0)); 8070823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8080823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int instanceCount = fGeoData.count(); 8090823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8100823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const GrVertexBuffer* vertexBuffer; 8110823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int firstVertex; 8120823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 813e40d39725908d99d255496025411e5c9ca32663erobertphillips void* verts = batchTarget->makeVertSpace(vertexStride, this->vertexCount(), 814e40d39725908d99d255496025411e5c9ca32663erobertphillips &vertexBuffer, &firstVertex); 8150823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 816cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon if (!verts) { 8174b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate vertices\n"); 8184b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 8194b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 8204b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 821b5238a7571c243ba4a154a62575570c3078b3741bsalomon const GrIndexBuffer* indexBuffer = NULL; 822b5238a7571c243ba4a154a62575570c3078b3741bsalomon int firstIndex = 0; 8230823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 824e40d39725908d99d255496025411e5c9ca32663erobertphillips uint16_t* indices = NULL; 8250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasIndices()) { 826e40d39725908d99d255496025411e5c9ca32663erobertphillips indices = batchTarget->makeIndexSpace(this->indexCount(), &indexBuffer, &firstIndex); 8274b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 8284b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt if (!indices) { 8294b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate indices\n"); 8304b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 8314b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 8320823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8330823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int indexOffset = 0; 8350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int vertexOffset = 0; 8360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt for (int i = 0; i < instanceCount; i++) { 8370823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const Geometry& args = fGeoData[i]; 8380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // TODO we can actually cache this interleaved and then just memcopy 8400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasIndices()) { 8410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt for (int j = 0; j < args.fIndices.count(); ++j, ++indexOffset) { 842e40d39725908d99d255496025411e5c9ca32663erobertphillips *(indices + indexOffset) = args.fIndices[j] + vertexOffset; 8430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt for (int j = 0; j < args.fPositions.count(); ++j) { 847cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon *((SkPoint*)verts) = args.fPositions[j]; 8480823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasColors()) { 849cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j]; 8500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasLocalCoords()) { 852cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j]; 8530823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 854cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon verts = (void*)((intptr_t)verts + vertexStride); 8550823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt vertexOffset++; 8560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8570823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 859cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon GrVertices vertices; 8600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasIndices()) { 861cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex, 862b5238a7571c243ba4a154a62575570c3078b3741bsalomon firstIndex, this->vertexCount(), this->indexCount()); 863b5238a7571c243ba4a154a62575570c3078b3741bsalomon 8640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else { 865cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount()); 8660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 867cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon batchTarget->draw(vertices); 8680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8700823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 8710823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittprivate: 8730823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt DrawVerticesBatch(const Geometry& geometry, GrPrimitiveType primitiveType, 8740823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const SkMatrix& viewMatrix, 8750823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const SkPoint* positions, int vertexCount, 8760823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const uint16_t* indices, int indexCount, 87799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt const GrColor* colors, const SkPoint* localCoords, const SkRect& bounds) { 8780823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt this->initClassID<DrawVerticesBatch>(); 8790823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkASSERT(positions); 8800823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8810823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fViewMatrix = viewMatrix; 8820823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt Geometry& installedGeo = fGeoData.push_back(geometry); 8830823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8840823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt installedGeo.fPositions.append(vertexCount, positions); 8850823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (indices) { 8860823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt installedGeo.fIndices.append(indexCount, indices); 8870823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fHasIndices = true; 8880823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else { 8890823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fHasIndices = false; 8900823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8910823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8920823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (colors) { 8930823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt installedGeo.fColors.append(vertexCount, colors); 8940823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fHasColors = true; 8950823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else { 8960823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fHasColors = false; 8970823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 8980823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 8990823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (localCoords) { 9000823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt installedGeo.fLocalCoords.append(vertexCount, localCoords); 9010823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fHasLocalCoords = true; 9020823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } else { 9030823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fHasLocalCoords = false; 9040823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9050823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fVertexCount = vertexCount; 9060823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fIndexCount = indexCount; 9070823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fPrimitiveType = primitiveType; 90899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 90999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->setBounds(bounds); 9100823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9110823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9120823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrPrimitiveType primitiveType() const { return fBatch.fPrimitiveType; } 9130823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool batchablePrimitiveType() const { 9140823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return kTriangles_GrPrimitiveType == fBatch.fPrimitiveType || 9150823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt kLines_GrPrimitiveType == fBatch.fPrimitiveType || 9160823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt kPoints_GrPrimitiveType == fBatch.fPrimitiveType; 9170823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9180823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrColor color() const { return fBatch.fColor; } 9190823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 9200823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool colorIgnored() const { return fBatch.fColorIgnored; } 9210823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } 9220823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool hasColors() const { return fBatch.fHasColors; } 9230823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool hasIndices() const { return fBatch.fHasIndices; } 9240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool hasLocalCoords() const { return fBatch.fHasLocalCoords; } 9250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int vertexCount() const { return fBatch.fVertexCount; } 9260823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int indexCount() const { return fBatch.fIndexCount; } 9270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 92836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onCombineIfPossible(GrBatch* t) override { 9290823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt DrawVerticesBatch* that = t->cast<DrawVerticesBatch>(); 9300823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9310823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (!this->batchablePrimitiveType() || this->primitiveType() != that->primitiveType()) { 9320823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return false; 9330823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 9360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9370823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt // We currently use a uniform viewmatrix for this batch 9380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 9390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return false; 9400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9420823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasColors() != that->hasColors()) { 9430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return false; 9440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasIndices() != that->hasIndices()) { 9470823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return false; 9480823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9490823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->hasLocalCoords() != that->hasLocalCoords()) { 9510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return false; 9520823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9530823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9540823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (!this->hasColors() && this->color() != that->color()) { 9550823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return false; 9560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9570823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt if (this->color() != that->color()) { 9590823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fColor = GrColor_ILLEGAL; 9600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9610823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 9620823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fVertexCount += that->vertexCount(); 9630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt fBatch.fIndexCount += that->indexCount(); 96499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 96599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 9660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt return true; 9670823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt } 9680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt struct BatchTracker { 9700823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrPrimitiveType fPrimitiveType; 9710823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkMatrix fViewMatrix; 9720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt GrColor fColor; 9730823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fUsesLocalCoords; 9740823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fColorIgnored; 9750823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fCoverageIgnored; 9760823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fHasColors; 9770823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fHasIndices; 9780823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt bool fHasLocalCoords; 9790823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int fVertexCount; 9800823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt int fIndexCount; 9810823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt }; 9820823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 9830823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt BatchTracker fBatch; 9840823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkSTArray<1, Geometry, true> fGeoData; 9850823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt}; 9860823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt 98725d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawVertices(GrRenderTarget* rt, 988570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 98925d9c154087d2132a51d1ca74a104726f60ef380joshualitt const GrPaint& paint, 9905531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 99127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 99227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 993972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint positions[], 994972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint texCoords[], 99527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 99627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 99727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 9985f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 999f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 10008dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 10015a56793b2a19eaf90b67d6f24441cc475d74ef17commit-bot@chromium.org 1002570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); 100341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon if (NULL == target) { 100441ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return; 100541ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 100627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 10072a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); 10082a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 1009a09c0461463a5976908af5232b755e1663b972bfjoshualitt // TODO clients should give us bounds 1010a09c0461463a5976908af5232b755e1663b972bfjoshualitt SkRect bounds; 1011a09c0461463a5976908af5232b755e1663b972bfjoshualitt if (!bounds.setBoundsCheck(positions, vertexCount)) { 1012a09c0461463a5976908af5232b755e1663b972bfjoshualitt SkDebugf("drawVertices call empty bounds\n"); 1013a09c0461463a5976908af5232b755e1663b972bfjoshualitt return; 1014a09c0461463a5976908af5232b755e1663b972bfjoshualitt } 1015a09c0461463a5976908af5232b755e1663b972bfjoshualitt 10160c14bccc3195e395594d5a737f14b4a6ccd8859djoshualitt viewMatrix.mapRect(&bounds); 10170c14bccc3195e395594d5a737f14b4a6ccd8859djoshualitt 10184c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt // If we don't have AA then we outset for a half pixel in each direction to account for 10194c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt // snapping 10204c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt if (!paint.isAntiAlias()) { 10214c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt bounds.outset(0.5f, 0.5f); 10224c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt } 10234c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt 10240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt DrawVerticesBatch::Geometry geometry; 10250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt geometry.fColor = paint.getColor(); 10260823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt SkAutoTUnref<GrBatch> batch(DrawVerticesBatch::Create(geometry, primitiveType, viewMatrix, 10270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt positions, vertexCount, indices, 102899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt indexCount, colors, texCoords, 102999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt bounds)); 103027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 103199c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt target->drawBatch(&pipelineBuilder, batch); 103227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 103327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 103406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 103593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 103625d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawRRect(GrRenderTarget*rt, 1037570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 103825d9c154087d2132a51d1ca74a104726f60ef380joshualitt const GrPaint& paint, 10395531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 10400a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org const SkRRect& rrect, 1041d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const GrStrokeInfo& strokeInfo) { 10425f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 10430a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (rrect.isEmpty()) { 104419dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org return; 104519dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org } 1046f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1047d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (strokeInfo.isDashed()) { 1048d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkPath path; 1049d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel path.addRRect(rrect); 1050570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo); 1051d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel return; 1052d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel } 1053d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1054f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 10558dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 1056570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); 105741ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon if (NULL == target) { 105841ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return; 105941ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 1060f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 10612a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target); 10622a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 1063d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); 1064d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 10652e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color = paint.getColor(); 106644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt if (!fOvalRenderer->drawRRect(target, 106744701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt &pipelineBuilder, 106844701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt color, 106944701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt viewMatrix, 107044701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt paint.isAntiAlias(), 107144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt rrect, 107244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt strokeRec)) { 1073f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkPath path; 10740a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org path.addRRect(rrect); 10758dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), 10768dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel path, strokeInfo); 1077f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1078f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org} 1079f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1080f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 1081f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 108225d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawDRRect(GrRenderTarget* rt, 1083570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 108425d9c154087d2132a51d1ca74a104726f60ef380joshualitt const GrPaint& paint, 10855531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 10860a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org const SkRRect& outer, 10870a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org const SkRRect& inner) { 10885f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 10890a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (outer.isEmpty()) { 10900a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org return; 10910a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 10920a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 1093f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 10948dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 1095570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); 10960a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 10970a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target); 10980a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 10992e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color = paint.getColor(); 110044701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt if (!fOvalRenderer->drawDRRect(target, 110144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt &pipelineBuilder, 110244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt color, 110344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt viewMatrix, 110444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt paint.isAntiAlias(), 110544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt outer, 110644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt inner)) { 11070a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org SkPath path; 11080a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org path.addRRect(inner); 11090a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org path.addRRect(outer); 11100a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org path.setFillType(SkPath::kEvenOdd_FillType); 11110a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 1112d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle); 11138dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), 11148dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel path, fillRec); 11150a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 11160a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org} 11170a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 11180a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 11190a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 1120570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualittvoid GrContext::drawOval(GrRenderTarget* rt, 1121570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 112225d9c154087d2132a51d1ca74a104726f60ef380joshualitt const GrPaint& paint, 11235531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 1124fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& oval, 1125d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const GrStrokeInfo& strokeInfo) { 11265f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 112719dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org if (oval.isEmpty()) { 112819dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org return; 112919dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org } 113093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1131d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (strokeInfo.isDashed()) { 1132d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkPath path; 1133d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel path.addOval(oval); 1134570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo); 1135d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel return; 1136d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel } 1137d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1138f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 11398dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 1140570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); 114141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon if (NULL == target) { 114241ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return; 114341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 11440982d35187da7e1ed6c0eba5951bbdadca8b33e7bsalomon@google.com 11452a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawOval", target); 11462a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 1147d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); 1148d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 11492e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color = paint.getColor(); 115044701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt if (!fOvalRenderer->drawOval(target, 115144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt &pipelineBuilder, 115244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt color, 115344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt viewMatrix, 115444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt paint.isAntiAlias(), 115544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt oval, 115644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt strokeRec)) { 115781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkPath path; 115881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org path.addOval(oval); 11598dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), 11608dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel path, strokeInfo); 116146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 1162150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 116327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 116483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com// Can 'path' be drawn as a pair of filled nested rectangles? 116583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.comstatic bool is_nested_rects(GrDrawTarget* target, 11668dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 11672e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 11688059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 116983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com const SkPath& path, 117083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com const SkStrokeRec& stroke, 11719c0822a4150e23cec9f9b72bd1abc2c5f9ea5a3bbsalomon SkRect rects[2]) { 117283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkASSERT(stroke.isFillStyle()); 117383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 117483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (path.isInverseFillType()) { 117583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 117683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 117783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 117883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // TODO: this restriction could be lifted if we were willing to apply 117983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // the matrix to all the points individually rather than just to the rect 11808059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!viewMatrix.preservesAxisAlignment()) { 118183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 118283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 118383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 118483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkPath::Direction dirs[2]; 118595bc5f349561fef2d6fbae71adb08cf5c2eec0c9caryclark if (!path.isNestedFillRects(rects, dirs)) { 118683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 118783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 118883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 11898d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { 119083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // The two rects need to be wound opposite to each other 11918d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com return false; 119283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 119383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 11948d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com // Right now, nested rects where the margin is not the same width 11958d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com // all around do not render correctly 11968d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com const SkScalar* outer = rects[0].asScalars(); 11978d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com const SkScalar* inner = rects[1].asScalars(); 11988d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com 1199183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips bool allEq = true; 1200183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips 12018d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com SkScalar margin = SkScalarAbs(outer[0] - inner[0]); 1202183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips bool allGoE1 = margin >= SK_Scalar1; 1203183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips 12048d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com for (int i = 1; i < 4; ++i) { 12058d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com SkScalar temp = SkScalarAbs(outer[i] - inner[i]); 1206183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips if (temp < SK_Scalar1) { 1207183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips allGoE1 = false; 1208183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips } 12098d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com if (!SkScalarNearlyEqual(margin, temp)) { 1210183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips allEq = false; 12118d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com } 12128d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com } 12138d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com 1214183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips return allEq || allGoE1; 12158d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com} 121683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 121725d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawPath(GrRenderTarget* rt, 1218570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 121925d9c154087d2132a51d1ca74a104726f60ef380joshualitt const GrPaint& paint, 12205531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 12215531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkPath& path, 12225531d51ce7426bdae7563547326fcf0bf926a083joshualitt const GrStrokeInfo& strokeInfo) { 12235f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 1224fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 122512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com if (path.isInverseFillType()) { 1226570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt this->drawPaint(rt, clip, paint, viewMatrix); 1227fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1228fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1229fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1230fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 12312e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color = paint.getColor(); 1232d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 123381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // Note that internalDrawPath may sw-rasterize the path into a scratch texture. 123481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // Scratch textures can be recycled after they are returned to the texture 123581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // cache. This presents a potential hazard for buffered drawing. However, 123681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // the writePixels that uploads to the scratch will perform a flush so we're 123781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // OK. 1238f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 12398dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 1240570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); 124141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon if (NULL == target) { 124241ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return; 124341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 124481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 124593a37bc91a40a7cd14f9f8eca6097535ab1099e4egdaniel GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isConvex()); 12462a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 12471899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (!strokeInfo.isDashed()) { 12481899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); 12491899651ffc459f5462aa989cd6d08507947b67e4kkinnunen bool useCoverageAA = paint.isAntiAlias() && 12501899651ffc459f5462aa989cd6d08507947b67e4kkinnunen !pipelineBuilder.getRenderTarget()->isMultisampled(); 1251e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org 12521899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { 12531899651ffc459f5462aa989cd6d08507947b67e4kkinnunen // Concave AA paths are expensive - try to avoid them for special cases 12541899651ffc459f5462aa989cd6d08507947b67e4kkinnunen SkRect rects[2]; 125583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 12561899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (is_nested_rects(target, &pipelineBuilder, color, viewMatrix, path, strokeRec, 12571899651ffc459f5462aa989cd6d08507947b67e4kkinnunen rects)) { 12581899651ffc459f5462aa989cd6d08507947b67e4kkinnunen fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, color, viewMatrix, 12591899651ffc459f5462aa989cd6d08507947b67e4kkinnunen rects); 12601899651ffc459f5462aa989cd6d08507947b67e4kkinnunen return; 12611899651ffc459f5462aa989cd6d08507947b67e4kkinnunen } 126283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 12631899651ffc459f5462aa989cd6d08507947b67e4kkinnunen SkRect ovalRect; 12641899651ffc459f5462aa989cd6d08507947b67e4kkinnunen bool isOval = path.isOval(&ovalRect); 126583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 12661899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (isOval && !path.isInverseFillType()) { 12671899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (fOvalRenderer->drawOval(target, 12681899651ffc459f5462aa989cd6d08507947b67e4kkinnunen &pipelineBuilder, 12691899651ffc459f5462aa989cd6d08507947b67e4kkinnunen color, 12701899651ffc459f5462aa989cd6d08507947b67e4kkinnunen viewMatrix, 12711899651ffc459f5462aa989cd6d08507947b67e4kkinnunen paint.isAntiAlias(), 12721899651ffc459f5462aa989cd6d08507947b67e4kkinnunen ovalRect, 12731899651ffc459f5462aa989cd6d08507947b67e4kkinnunen strokeRec)) { 12741899651ffc459f5462aa989cd6d08507947b67e4kkinnunen return; 12751899651ffc459f5462aa989cd6d08507947b67e4kkinnunen } 12761899651ffc459f5462aa989cd6d08507947b67e4kkinnunen } 127793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 12781899651ffc459f5462aa989cd6d08507947b67e4kkinnunen this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), 12791899651ffc459f5462aa989cd6d08507947b67e4kkinnunen path, strokeInfo); 128093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 128193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 12829853ccef19c200be93a6211f32589fa82a53067cjoshualittvoid GrContext::internalDrawPath(GrDrawTarget* target, 12838dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 12845531d51ce7426bdae7563547326fcf0bf926a083joshualitt const SkMatrix& viewMatrix, 12852e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 12869853ccef19c200be93a6211f32589fa82a53067cjoshualitt bool useAA, 12879853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath& path, 1288d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const GrStrokeInfo& strokeInfo) { 12895f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 129019dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org SkASSERT(!path.isEmpty()); 129193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 12922a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); 12932a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 12942a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 1295d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1296d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1297d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1298d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1299e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org bool useCoverageAA = useAA && 13000bdeec9640640922eb6b0a9f798bcd85eb898f29egdaniel !pipelineBuilder->getRenderTarget()->isMultisampled(); 1301e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org 1302289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1303e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org GrPathRendererChain::DrawType type = 1304e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : 13059853ccef19c200be93a6211f32589fa82a53067cjoshualitt GrPathRendererChain::kColor_DrawType; 130645a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 1307eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com const SkPath* pathPtr = &path; 1308f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org SkTLazy<SkPath> tmpPath; 13091899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo* strokeInfoPtr = &strokeInfo; 1310eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1311eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com // Try a 1st time without stroking the path and without allowing the SW renderer 13128dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPathRenderer* pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, 13131899651ffc459f5462aa989cd6d08507947b67e4kkinnunen *strokeInfoPtr, false, type); 13141899651ffc459f5462aa989cd6d08507947b67e4kkinnunen 13151899651ffc459f5462aa989cd6d08507947b67e4kkinnunen GrStrokeInfo dashlessStrokeInfo(strokeInfo, false); 13161899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (NULL == pr && strokeInfo.isDashed()) { 13171899651ffc459f5462aa989cd6d08507947b67e4kkinnunen // It didn't work above, so try again with dashed stroke converted to a dashless stroke. 131807ab9f3beda017d06089797de8c79d833b5a7659bsalomon if (!strokeInfo.applyDash(tmpPath.init(), &dashlessStrokeInfo, *pathPtr)) { 131907ab9f3beda017d06089797de8c79d833b5a7659bsalomon return; 132007ab9f3beda017d06089797de8c79d833b5a7659bsalomon } 132107ab9f3beda017d06089797de8c79d833b5a7659bsalomon pathPtr = tmpPath.get(); 132207ab9f3beda017d06089797de8c79d833b5a7659bsalomon if (pathPtr->isEmpty()) { 132307ab9f3beda017d06089797de8c79d833b5a7659bsalomon return; 13241899651ffc459f5462aa989cd6d08507947b67e4kkinnunen } 132507ab9f3beda017d06089797de8c79d833b5a7659bsalomon strokeInfoPtr = &dashlessStrokeInfo; 13261899651ffc459f5462aa989cd6d08507947b67e4kkinnunen pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr, 13271899651ffc459f5462aa989cd6d08507947b67e4kkinnunen false, type); 13281899651ffc459f5462aa989cd6d08507947b67e4kkinnunen } 1329eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1330e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (NULL == pr) { 133107ab9f3beda017d06089797de8c79d833b5a7659bsalomon if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*strokeInfoPtr, viewMatrix, NULL) && 133207ab9f3beda017d06089797de8c79d833b5a7659bsalomon !strokeInfoPtr->isFillStyle()) { 13331899651ffc459f5462aa989cd6d08507947b67e4kkinnunen // It didn't work above, so try again with stroke converted to a fill. 13341899651ffc459f5462aa989cd6d08507947b67e4kkinnunen if (!tmpPath.isValid()) { 13351899651ffc459f5462aa989cd6d08507947b67e4kkinnunen tmpPath.init(); 13361899651ffc459f5462aa989cd6d08507947b67e4kkinnunen } 13371899651ffc459f5462aa989cd6d08507947b67e4kkinnunen SkStrokeRec* strokeRec = dashlessStrokeInfo.getStrokeRecPtr(); 13381899651ffc459f5462aa989cd6d08507947b67e4kkinnunen strokeRec->setResScale(SkScalarAbs(viewMatrix.getMaxScale())); 133907ab9f3beda017d06089797de8c79d833b5a7659bsalomon if (!strokeRec->applyToPath(tmpPath.get(), *pathPtr)) { 134007ab9f3beda017d06089797de8c79d833b5a7659bsalomon return; 134107ab9f3beda017d06089797de8c79d833b5a7659bsalomon } 134207ab9f3beda017d06089797de8c79d833b5a7659bsalomon pathPtr = tmpPath.get(); 134307ab9f3beda017d06089797de8c79d833b5a7659bsalomon if (pathPtr->isEmpty()) { 134407ab9f3beda017d06089797de8c79d833b5a7659bsalomon return; 1345eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 134607ab9f3beda017d06089797de8c79d833b5a7659bsalomon strokeRec->setFillStyle(); 134707ab9f3beda017d06089797de8c79d833b5a7659bsalomon strokeInfoPtr = &dashlessStrokeInfo; 1348eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 134919dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org 1350eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com // This time, allow SW renderer 13511899651ffc459f5462aa989cd6d08507947b67e4kkinnunen pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr, 13521899651ffc459f5462aa989cd6d08507947b67e4kkinnunen true, type); 1353eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 1354eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1355e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (NULL == pr) { 1356515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 135738406c82b913350e55fa04af8c1941cd9b4aff52tfarina SkDebugf("Unable to find path renderer compatible with path.\n"); 13581983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 13593008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 13603008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 13613008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 13621899651ffc459f5462aa989cd6d08507947b67e4kkinnunen pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *strokeInfoPtr, useCoverageAA); 136327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 13648295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 136527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 136627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1367a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1368e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com if (NULL == fDrawBuffer) { 1369e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com return; 1370e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com } 1371e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com 1372a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1373a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1374a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 13756e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBuffer->flush(); 137653a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 13773f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon fResourceCache->notifyFlushOccurred(); 1378f21dab95405979a4aff9f6a741c818304a67f220bsalomon fFlushToReduceCacheSize = false; 137927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 138027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 138181beccc4fb1396fe94af15bfce26e68b82b93809bsalomonbool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes, 138281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon const void* inPixels, size_t outRowBytes, void* outPixels) { 138381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon SkSrcPixelInfo srcPI; 1384fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth if (!GrPixelConfig2ColorAndProfileType(srcConfig, &srcPI.fColorType, NULL)) { 138581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon return false; 138681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 138781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon srcPI.fAlphaType = kUnpremul_SkAlphaType; 138881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon srcPI.fPixels = inPixels; 138981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon srcPI.fRowBytes = inRowBytes; 139081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon 139181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon SkDstPixelInfo dstPI; 139281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon dstPI.fColorType = srcPI.fColorType; 139381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon dstPI.fAlphaType = kPremul_SkAlphaType; 139481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon dstPI.fPixels = outPixels; 139581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon dstPI.fRowBytes = outRowBytes; 139681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon 139781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon return srcPI.convertPixelsTo(&dstPI, width, height); 139881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon} 139981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon 140081beccc4fb1396fe94af15bfce26e68b82b93809bsalomonbool GrContext::writeSurfacePixels(GrSurface* surface, 14010342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 140281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, 140381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon uint32_t pixelOpsFlags) { 14045f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_FALSE_IF_ABANDONED 140581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon { 140681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon GrTexture* texture = NULL; 140781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) && 140881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon fGpu->canWriteTexturePixels(texture, srcConfig)) { 140981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon 141081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && 141181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon surface->surfacePriv().hasPendingIO()) { 141281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon this->flush(); 141381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 141481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon return fGpu->writeTexturePixels(texture, left, top, width, height, 141581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon srcConfig, buffer, rowBytes); 141681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // Don't need to check kFlushWrites_PixelOp here, we just did a direct write so the 141781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // upload is already flushed. 14189c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } 14196f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 14209c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com 142181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // If we didn't do a direct texture write then we upload the pixels to a texture and draw. 142281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon GrRenderTarget* renderTarget = surface->asRenderTarget(); 142381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (NULL == renderTarget) { 142481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon return false; 14250342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com } 14266f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 142781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // We ignore the preferred config unless it is a R/B swap of the src config. In that case 142881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // we will upload the original src data to a scratch texture but we will spoof it as the swapped 142981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // config. This scratch will then have R and B swapped. We correct for this by swapping again 143081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // when drawing the scratch to the dst using a conversion effect. 143181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon bool swapRAndB = false; 143281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon GrPixelConfig writeConfig = srcConfig; 143381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (GrPixelConfigSwapRAndB(srcConfig) == 143481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon fGpu->preferredWritePixelsConfig(srcConfig, renderTarget->config())) { 143581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon writeConfig = GrPixelConfigSwapRAndB(srcConfig); 143681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon swapRAndB = true; 143781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 1438f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon 1439f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc; 144081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon desc.fWidth = width; 144181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon desc.fHeight = height; 144281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon desc.fConfig = writeConfig; 1443d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon SkAutoTUnref<GrTexture> texture(this->textureProvider()->refScratchTexture(desc, 1444d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon GrTextureProvider::kApprox_ScratchTexMatch)); 1445e30597375c19dfb5197fd065a3d1768401eb00fabsalomon if (!texture) { 144681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon return false; 144781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 14486f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 144981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon SkAutoTUnref<const GrFragmentProcessor> fp; 145081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon SkMatrix textureMatrix; 145181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon textureMatrix.setIDiv(texture->width(), texture->height()); 14523f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org 145381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // allocate a tmp buffer and sw convert the pixels to premul 145481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); 145581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon 145681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { 145781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (!GrPixelConfigIs8888(srcConfig)) { 145881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon return false; 145981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 146081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); 146181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // handle the unpremul step on the CPU if we couldn't create an effect to do it. 146281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (NULL == fp) { 146381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon size_t tmpRowBytes = 4 * width; 146481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon tmpPixels.reset(width * height); 146581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes, 146681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon tmpPixels.get())) { 146781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon return false; 146881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 146981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon rowBytes = tmpRowBytes; 147081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon buffer = tmpPixels.get(); 14713f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org } 147281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 147381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (NULL == fp) { 147481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon fp.reset(GrConfigConversionEffect::Create(texture, 147581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon swapRAndB, 147681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon GrConfigConversionEffect::kNone_PMConversion, 147781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon textureMatrix)); 147881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 1479583b18a20959c9ac360316a366f4ddd9598bdf52skia.committer@gmail.com 148081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // Even if the client told us not to flush, we still flush here. The client may have known that 148181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // writes to the original surface caused no data hazards, but they can't know that the scratch 148281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // we just got is safe. 148381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (texture->surfacePriv().hasPendingIO()) { 148481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon this->flush(); 148581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 148681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (!fGpu->writeTexturePixels(texture, 0, 0, width, height, 148781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon writeConfig, buffer, rowBytes)) { 1488669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1489669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1490669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 149181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon SkMatrix matrix; 149281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); 149381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon 149481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // This function can be called in the midst of drawing another object (e.g., when uploading a 149581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // SW-rasterized clip while issuing a draw). So we push the current geometry state before 149681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // drawing a rect to the render target. 149781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // The bracket ensures we pop the stack if we wind up flushing below. 149881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon { 1499570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* drawTarget = this->prepareToDraw(); 1500570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt if (!drawTarget) { 1501570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt return false; 1502570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt } 15039853ccef19c200be93a6211f32589fa82a53067cjoshualitt 15048dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 15058dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel pipelineBuilder.addColorProcessor(fp); 15068dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel pipelineBuilder.setRenderTarget(renderTarget); 150744701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt drawTarget->drawSimpleRect(&pipelineBuilder, 150844701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt GrColor_WHITE, 150944701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt matrix, 15108059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height))); 151181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 151281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon 151381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon if (kFlushWrites_PixelOp & pixelOpsFlags) { 151481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon this->flushSurfaceWrites(surface); 151581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon } 151681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon 151781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon return true; 151881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon} 1519a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 15207111d463cee893a479280c7af41757e709e33ef5reed@google.com// toggles between RGBA and BGRA 15217111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic SkColorType toggle_colortype32(SkColorType ct) { 15227111d463cee893a479280c7af41757e709e33ef5reed@google.com if (kRGBA_8888_SkColorType == ct) { 15237111d463cee893a479280c7af41757e709e33ef5reed@google.com return kBGRA_8888_SkColorType; 15247111d463cee893a479280c7af41757e709e33ef5reed@google.com } else { 15257111d463cee893a479280c7af41757e709e33ef5reed@google.com SkASSERT(kBGRA_8888_SkColorType == ct); 15267111d463cee893a479280c7af41757e709e33ef5reed@google.com return kRGBA_8888_SkColorType; 1527231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org } 1528231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org} 1529231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org 15300342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.combool GrContext::readRenderTargetPixels(GrRenderTarget* target, 15310342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 15329c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig dstConfig, void* buffer, size_t rowBytes, 15330342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 15345f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_FALSE_IF_ABANDONED 1535bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 153689c62980c1eb50b2090f33312086c7e8c66739b4bsalomon SkASSERT(target); 1537669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1538afbf2d6273cd22c683f20a7e5773843876af3085bsalomon if (!(kDontFlush_PixelOpsFlag & flags) && target->surfacePriv().hasPendingWrite()) { 15396f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 15406f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1541c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1542a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul. 1543c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1544a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll 1545a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read. 1546a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top, 15479c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com width, height, dstConfig, 1548c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 15499c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // We ignore the preferred config if it is different than our config unless it is an R/B swap. 15509c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // In that case we'll perform an R and B swap while drawing to a scratch texture of the swapped 15519c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // config. Then we will call readPixels on the scratch with the swapped config. The swaps during 15529c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from 15539c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // dstConfig. 15549c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig readConfig = dstConfig; 15559c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com bool swapRAndB = false; 15565d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org if (GrPixelConfigSwapRAndB(dstConfig) == 15575d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org fGpu->preferredReadPixelsConfig(dstConfig, target->config())) { 15589c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com readConfig = GrPixelConfigSwapRAndB(readConfig); 15599c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com swapRAndB = true; 15609c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } 1561a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 15620342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); 1563c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 15649c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (unpremul && !GrPixelConfigIs8888(dstConfig)) { 1565a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // The unpremul flag is only allowed for these two configs. 15660a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 15670a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 1568a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1569191bcc008ea6b4cc445e105f6d36cbc057246e29bsalomon SkAutoTUnref<GrTexture> tempTexture; 1570191bcc008ea6b4cc445e105f6d36cbc057246e29bsalomon 1571a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If the src is a texture and we would have to do conversions after read pixels, we instead 1572a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // do the conversions by drawing the src to a scratch texture. If we handle any of the 1573a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // conversions in the draw we set the corresponding bool to false so that we don't reapply it 1574a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // on the read back pixels. 1575a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrTexture* src = target->asTexture(); 157649f085dddff10473b6ebf832a974288300224e60bsalomon if (src && (swapRAndB || unpremul || flipY)) { 157781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon // Make the scratch a render so we can read its pixels. 1578f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc; 1579f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon desc.fFlags = kRenderTarget_GrSurfaceFlag; 158075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 158175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 1582a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fConfig = readConfig; 15833cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org desc.fOrigin = kTopLeft_GrSurfaceOrigin; 1584c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 15859c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // When a full read back is faster than a partial we could always make the scratch exactly 1586a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // match the passed rect. However, if we see many different size rectangles we will trash 1587a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // our texture cache and pay the cost of creating and destroying many textures. So, we only 1588a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // request an exact match when the caller is reading an entire RT. 1589d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon GrTextureProvider::ScratchTexMatch match = GrTextureProvider::kApprox_ScratchTexMatch; 159056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 159156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 159256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 159356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 159456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 1595d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon match = GrTextureProvider::kExact_ScratchTexMatch; 159656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 1597d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon tempTexture.reset(this->textureProvider()->refScratchTexture(desc, match)); 1598191bcc008ea6b4cc445e105f6d36cbc057246e29bsalomon if (tempTexture) { 1599d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com // compute a matrix to perform the draw 1600b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix textureMatrix; 16013cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1602d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com textureMatrix.postIDiv(src->width(), src->height()); 1603d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1604b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<const GrFragmentProcessor> fp; 1605a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (unpremul) { 1606b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fp.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix)); 1607b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp) { 16089c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com unpremul = false; // we no longer need to do this on CPU after the read back. 1609d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com } 1610a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1611a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If we failed to create a PM->UPM effect and have no other conversions to perform then 1612a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // there is no longer any point to using the scratch. 1613b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (fp || flipY || swapRAndB) { 1614b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (!fp) { 1615b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fp.reset(GrConfigConversionEffect::Create( 1616b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt src, swapRAndB, GrConfigConversionEffect::kNone_PMConversion, 1617b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt textureMatrix)); 1618a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1619a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com swapRAndB = false; // we will handle the swap in the draw. 1620a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 162113f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // We protect the existing geometry here since it may not be 162213f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // clear to the caller that a draw operation (i.e., drawSimpleRect) 162313f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // can be invoked in this method 16245c55fef032d1de01fed6b40ac39081aea9544a75joshualitt { 16258dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder pipelineBuilder; 16265c55fef032d1de01fed6b40ac39081aea9544a75joshualitt SkASSERT(fp); 16278dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel pipelineBuilder.addColorProcessor(fp); 16285c55fef032d1de01fed6b40ac39081aea9544a75joshualitt 16298dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel pipelineBuilder.setRenderTarget(tempTexture->asRenderTarget()); 16305c55fef032d1de01fed6b40ac39081aea9544a75joshualitt SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 163144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt fDrawBuffer->drawSimpleRect(&pipelineBuilder, 163244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt GrColor_WHITE, 163344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt SkMatrix::I(), 16348dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel rect); 16355c55fef032d1de01fed6b40ac39081aea9544a75joshualitt // we want to read back from the scratch's origin 16365c55fef032d1de01fed6b40ac39081aea9544a75joshualitt left = 0; 16375c55fef032d1de01fed6b40ac39081aea9544a75joshualitt top = 0; 1638191bcc008ea6b4cc445e105f6d36cbc057246e29bsalomon target = tempTexture->asRenderTarget(); 16395c55fef032d1de01fed6b40ac39081aea9544a75joshualitt } 16405c55fef032d1de01fed6b40ac39081aea9544a75joshualitt this->flushSurfaceWrites(target); 1641a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1642c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1643a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 16445c55fef032d1de01fed6b40ac39081aea9544a75joshualitt 1645a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fGpu->readPixels(target, 1646a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com left, top, width, height, 16473cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org readConfig, buffer, rowBytes)) { 1648a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return false; 1649a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1650d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com // Perform any conversions we weren't able to perform using a scratch texture. 16513cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (unpremul || swapRAndB) { 16527111d463cee893a479280c7af41757e709e33ef5reed@google.com SkDstPixelInfo dstPI; 1653fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, NULL)) { 16547111d463cee893a479280c7af41757e709e33ef5reed@google.com return false; 16557111d463cee893a479280c7af41757e709e33ef5reed@google.com } 16567111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fAlphaType = kUnpremul_SkAlphaType; 16577111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fPixels = buffer; 16587111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fRowBytes = rowBytes; 1659be41d38f1c076c9e4dc595a6e1a4eb5ccdbd307bskia.committer@gmail.com 16607111d463cee893a479280c7af41757e709e33ef5reed@google.com SkSrcPixelInfo srcPI; 16617111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fColorType = swapRAndB ? toggle_colortype32(dstPI.fColorType) : dstPI.fColorType; 16627111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fAlphaType = kPremul_SkAlphaType; 16637111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fPixels = buffer; 16647111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fRowBytes = rowBytes; 1665be41d38f1c076c9e4dc595a6e1a4eb5ccdbd307bskia.committer@gmail.com 16667111d463cee893a479280c7af41757e709e33ef5reed@google.com return srcPI.convertPixelsTo(&dstPI, width, height); 1667c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1668a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return true; 166927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 167027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 167187a94eb1632d06eeeb89490a91565e786440d6d0bsalomonvoid GrContext::prepareSurfaceForExternalRead(GrSurface* surface) { 16725f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 167387a94eb1632d06eeeb89490a91565e786440d6d0bsalomon SkASSERT(surface); 167487a94eb1632d06eeeb89490a91565e786440d6d0bsalomon ASSERT_OWNED_RESOURCE(surface); 167587a94eb1632d06eeeb89490a91565e786440d6d0bsalomon if (surface->surfacePriv().hasPendingIO()) { 167687a94eb1632d06eeeb89490a91565e786440d6d0bsalomon this->flush(); 167787a94eb1632d06eeeb89490a91565e786440d6d0bsalomon } 167887a94eb1632d06eeeb89490a91565e786440d6d0bsalomon GrRenderTarget* rt = surface->asRenderTarget(); 167987a94eb1632d06eeeb89490a91565e786440d6d0bsalomon if (fGpu && rt) { 168087a94eb1632d06eeeb89490a91565e786440d6d0bsalomon fGpu->resolveRenderTarget(rt); 168141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 168275f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com} 168375f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com 168441ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomonvoid GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { 16855f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 168641ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon SkASSERT(renderTarget); 168741ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon ASSERT_OWNED_RESOURCE(renderTarget); 1688f21dab95405979a4aff9f6a741c818304a67f220bsalomon AutoCheckFlush acf(this); 1689570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(); 169041ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon if (NULL == target) { 169141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return; 169241ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 169341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon target->discard(renderTarget); 169428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 169528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 1696f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomonvoid GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 1697f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon const SkIPoint& dstPoint, uint32_t pixelOpsFlags) { 16985f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 1699ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1700ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1701ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1702e3d4bf234a04e14b6b0f33e11b3e1132b560c145bsalomon ASSERT_OWNED_RESOURCE(src); 17032bb52102b16cf197709797be5e2209868ee2dafejunov ASSERT_OWNED_RESOURCE(dst); 170434a9895baf8b2bf95c4f6944a7914be1a74f1524Brian Salomon 1705f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon // Since we're going to the draw target and not GPU, no need to check kNoFlush 1706f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon // here. 170796c118edff293af93db0a2b1b6775428117924b1junov 1708570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrDrawTarget* target = this->prepareToDraw(); 170996c118edff293af93db0a2b1b6775428117924b1junov if (NULL == target) { 171096c118edff293af93db0a2b1b6775428117924b1junov return; 171196c118edff293af93db0a2b1b6775428117924b1junov } 171296c118edff293af93db0a2b1b6775428117924b1junov target->copySurface(dst, src, srcRect, dstPoint); 1713f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon 1714f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon if (kFlushWrites_PixelOp & pixelOpsFlags) { 1715f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon this->flush(); 1716f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon } 1717ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1718ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 1719f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomonvoid GrContext::flushSurfaceWrites(GrSurface* surface) { 17205f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt RETURN_IF_ABANDONED 1721f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon if (surface->surfacePriv().hasPendingWrite()) { 1722f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon this->flush(); 1723f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon } 1724f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon} 1725f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon 17268dd688b7569df569a672a8a67b2db86a9d376cfcegdanielGrDrawTarget* GrContext::prepareToDraw(GrPipelineBuilder* pipelineBuilder, 172725d9c154087d2132a51d1ca74a104726f60ef380joshualitt GrRenderTarget* rt, 1728570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 17299853ccef19c200be93a6211f32589fa82a53067cjoshualitt const GrPaint* paint, 17309853ccef19c200be93a6211f32589fa82a53067cjoshualitt const AutoCheckFlush* acf) { 17315f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt if (NULL == fGpu || NULL == fDrawBuffer) { 173241ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon return NULL; 173341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon } 173441ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon 1735570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt ASSERT_OWNED_RESOURCE(rt); 1736570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt SkASSERT(rt && paint && acf); 1737570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt pipelineBuilder->setFromPaint(*paint, rt, clip); 1738570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt return fDrawBuffer; 1739570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt} 1740570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt 1741570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualittGrDrawTarget* GrContext::prepareToDraw() { 1742570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt if (NULL == fGpu) { 1743570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt return NULL; 174407ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com } 17455c55fef032d1de01fed6b40ac39081aea9544a75joshualitt return fDrawBuffer; 174627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 174727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 174872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com/* 174972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * This method finds a path renderer that can draw the specified path on 175072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * the provided target. 1751fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Due to its expense, the software path renderer has split out so it can 175272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * can be individually allowed/disallowed via the "allowSW" boolean. 175372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com */ 17549853ccef19c200be93a6211f32589fa82a53067cjoshualittGrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, 17558dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel const GrPipelineBuilder* pipelineBuilder, 17568059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 17579853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkPath& path, 17581899651ffc459f5462aa989cd6d08507947b67e4kkinnunen const GrStrokeInfo& stroke, 175945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com bool allowSW, 176045a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com GrPathRendererChain::DrawType drawType, 176145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com GrPathRendererChain::StencilSupport* stencilSupport) { 176245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 17633008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 176445a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); 17653008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 176672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 17679853ccef19c200be93a6211f32589fa82a53067cjoshualitt GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target, 17688dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel pipelineBuilder, 17698059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix, 17709853ccef19c200be93a6211f32589fa82a53067cjoshualitt path, 177112b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com stroke, 177245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com drawType, 177345a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com stencilSupport); 177472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 177572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == pr && allowSW) { 177672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == fSoftwarePathRenderer) { 1777c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); 177872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 177972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com pr = fSoftwarePathRenderer; 178072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 178172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 178272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com return pr; 17833008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 17843008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 178527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 17866b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.orgbool GrContext::isConfigRenderable(GrPixelConfig config, bool withMSAA) const { 17876b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.org return fGpu->caps()->isConfigRenderable(config, withMSAA); 178899a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com} 178999a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com 1790b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.orgint GrContext::getRecommendedSampleCount(GrPixelConfig config, 1791b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org SkScalar dpi) const { 1792b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org if (!this->isConfigRenderable(config, true)) { 1793b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org return 0; 1794b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org } 1795b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org int chosenSampleCount = 0; 1796e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) { 1797b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org if (dpi >= 250.0f) { 1798b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org chosenSampleCount = 4; 1799b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org } else { 1800b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org chosenSampleCount = 16; 1801b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org } 1802b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org } 1803b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org return chosenSampleCount <= fGpu->caps()->maxSampleCount() ? 1804b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org chosenSampleCount : 0; 1805b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org} 1806b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org 180721c10c5ff50cb8f2fd995fc9396d435d3396258bbsalomon@google.comGrDrawTarget* GrContext::getTextTarget() { 1808570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt return this->prepareToDraw(); 180927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 181027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1811a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comnamespace { 1812a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comvoid test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { 1813a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion pmToUPM; 1814a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion upmToPM; 1815a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM); 1816a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMValue = pmToUPM; 1817a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMValue = upmToPM; 1818a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1819a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1820a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1821b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture, 1822b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool swapRAndB, 1823b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const SkMatrix& matrix) { 1824a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fDidTestPMConversions) { 1825a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 1826d0f3f6825bd5c232da52f4dc1af69b76403b797fbsalomon@google.com fDidTestPMConversions = true; 1827a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1828a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion pmToUPM = 1829a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); 1830a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { 1831adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix); 1832a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 1833adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return NULL; 1834a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1835a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1836a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1837b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture, 1838b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool swapRAndB, 1839b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const SkMatrix& matrix) { 1840a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fDidTestPMConversions) { 1841a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 1842d0f3f6825bd5c232da52f4dc1af69b76403b797fbsalomon@google.com fDidTestPMConversions = true; 1843a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1844a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion upmToPM = 1845a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); 1846a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { 1847adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix); 1848a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 1849adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return NULL; 1850a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1851a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1852a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 185337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon////////////////////////////////////////////////////////////////////////////// 185437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 185537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonvoid GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const { 185637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (maxTextures) { 18570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon *maxTextures = fResourceCache->getMaxResourceCount(); 185837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 185937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon if (maxTextureBytes) { 18600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon *maxTextureBytes = fResourceCache->getMaxResourceBytes(); 186137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon } 186237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon} 186337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 186437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonvoid GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) { 18650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon fResourceCache->setLimits(maxTextures, maxTextureBytes); 186637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon} 186737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 186837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon////////////////////////////////////////////////////////////////////////////// 186937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon 1870bbcb38df4f7477aa0a38da00a0757586a0125954egdanielvoid GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { 1871bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel fGpu->addGpuTraceMarker(marker); 187249f085dddff10473b6ebf832a974288300224e60bsalomon if (fDrawBuffer) { 1873bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel fDrawBuffer->addGpuTraceMarker(marker); 1874bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel } 1875bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel} 1876bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel 1877bbcb38df4f7477aa0a38da00a0757586a0125954egdanielvoid GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { 1878bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel fGpu->removeGpuTraceMarker(marker); 187949f085dddff10473b6ebf832a974288300224e60bsalomon if (fDrawBuffer) { 1880bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel fDrawBuffer->removeGpuTraceMarker(marker); 1881bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel } 1882bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel} 1883e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1884e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt/////////////////////////////////////////////////////////////////////////////////////////////////// 1885e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1886e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt#ifdef GR_TEST_UTILS 1887e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 18886c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualittBATCH_TEST_DEFINE(StrokeRectBatch) { 1889e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt StrokeRectBatch::Geometry geometry; 1890e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt geometry.fViewMatrix = GrTest::TestMatrix(random); 1891e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt geometry.fColor = GrRandomColor(random); 1892e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt geometry.fRect = GrTest::TestRect(random); 1893e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt geometry.fStrokeWidth = random->nextBool() ? 0.0f : 1.0f; 1894e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 18954c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt return StrokeRectBatch::Create(geometry, random->nextBool()); 1896e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt} 1897e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1898e590266294c4c92e4e4c2f06f267ac5751d07562joshualittstatic uint32_t seed_vertices(GrPrimitiveType type) { 1899e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt switch (type) { 1900e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kTriangles_GrPrimitiveType: 1901e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kTriangleStrip_GrPrimitiveType: 1902e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kTriangleFan_GrPrimitiveType: 1903e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return 3; 1904e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kPoints_GrPrimitiveType: 1905e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return 1; 1906e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kLines_GrPrimitiveType: 1907e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kLineStrip_GrPrimitiveType: 1908e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return 2; 1909e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt } 1910e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkFAIL("Incomplete switch\n"); 1911e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return 0; 1912e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt} 1913e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1914e590266294c4c92e4e4c2f06f267ac5751d07562joshualittstatic uint32_t primitive_vertices(GrPrimitiveType type) { 1915e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt switch (type) { 1916e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kTriangles_GrPrimitiveType: 1917e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return 3; 1918e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kLines_GrPrimitiveType: 1919e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return 2; 1920e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kTriangleStrip_GrPrimitiveType: 1921e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kTriangleFan_GrPrimitiveType: 1922e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kPoints_GrPrimitiveType: 1923e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt case kLineStrip_GrPrimitiveType: 1924e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return 1; 1925e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt } 1926e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkFAIL("Incomplete switch\n"); 1927e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return 0; 1928e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt} 1929e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1930e590266294c4c92e4e4c2f06f267ac5751d07562joshualittstatic SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) { 1931e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkPoint p; 1932e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt p.fX = random->nextRangeScalar(min, max); 1933e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt p.fY = random->nextRangeScalar(min, max); 1934e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return p; 1935e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt} 1936e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1937e590266294c4c92e4e4c2f06f267ac5751d07562joshualittstatic void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max, 1938e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkRandom* random, 1939e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkTArray<SkPoint>* positions, 1940e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkTArray<SkPoint>* texCoords, bool hasTexCoords, 1941e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkTArray<GrColor>* colors, bool hasColors, 1942e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkTArray<uint16_t>* indices, bool hasIndices) { 1943e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt for (uint32_t v = 0; v < count; v++) { 1944e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt positions->push_back(random_point(random, min, max)); 1945e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt if (hasTexCoords) { 1946e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt texCoords->push_back(random_point(random, min, max)); 1947e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt } 1948e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt if (hasColors) { 1949e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt colors->push_back(GrRandomColor(random)); 1950e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt } 1951e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt if (hasIndices) { 1952e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkASSERT(maxVertex <= SK_MaxU16); 1953e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt indices->push_back(random->nextULessThan((uint16_t)maxVertex)); 1954e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt } 1955e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt } 1956e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt} 1957e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 19586c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualittBATCH_TEST_DEFINE(VerticesBatch) { 1959e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt GrPrimitiveType type = GrPrimitiveType(random->nextULessThan(kLast_GrPrimitiveType + 1)); 1960e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt uint32_t primitiveCount = random->nextRangeU(1, 100); 1961e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1962e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt // TODO make 'sensible' indexbuffers 1963e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkTArray<SkPoint> positions; 1964e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkTArray<SkPoint> texCoords; 1965e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkTArray<GrColor> colors; 1966e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkTArray<uint16_t> indices; 1967e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1968e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt bool hasTexCoords = random->nextBool(); 1969e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt bool hasIndices = random->nextBool(); 1970e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt bool hasColors = random->nextBool(); 1971e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1972e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type); 1973e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1974e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt static const SkScalar kMinVertExtent = -100.f; 1975e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt static const SkScalar kMaxVertExtent = 100.f; 1976e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, 1977e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt random, 1978e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt &positions, 1979e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt &texCoords, hasTexCoords, 1980e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt &colors, hasColors, 1981e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt &indices, hasIndices); 1982e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1983e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt for (uint32_t i = 1; i < primitiveCount; i++) { 1984e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, 1985e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt random, 1986e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt &positions, 1987e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt &texCoords, hasTexCoords, 1988e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt &colors, hasColors, 1989e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt &indices, hasIndices); 1990e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt } 1991e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1992e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkMatrix viewMatrix = GrTest::TestMatrix(random); 1993e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkRect bounds; 1994e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexCount); 1995e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt SkASSERT(result); 1996e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1997e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt viewMatrix.mapRect(&bounds); 1998e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 1999e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt DrawVerticesBatch::Geometry geometry; 2000e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt geometry.fColor = GrRandomColor(random); 2001e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt return DrawVerticesBatch::Create(geometry, type, viewMatrix, 2002e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt positions.begin(), vertexCount, 2003e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt indices.begin(), hasIndices ? vertexCount : 0, 2004e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt colors.begin(), 2005e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt texCoords.begin(), 2006e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt bounds); 2007e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt} 2008e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt 2009e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt#endif 2010