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 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com#include "GrContext.h" 111fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com 12a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com#include "effects/GrConfigConversionEffect.h" 13e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "effects/GrDashingEffect.h" 14e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel#include "effects/GrSingleTextureEffect.h" 15b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com 16bfe2b9d3a290d0153b82617cd6b65a4814fe89e3jvanverth@google.com#include "GrAARectRenderer.h" 17278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrBufferAllocPool.h" 18dcb8ef9e866b2674e8f9a70b761fcc4fec87dbbecommit-bot@chromium.org#include "GrGpu.h" 194784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "GrDrawTargetCaps.h" 20dcb8ef9e866b2674e8f9a70b761fcc4fec87dbbecommit-bot@chromium.org#include "GrIndexBuffer.h" 214784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "GrInOrderDrawBuffer.h" 22e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com#include "GrLayerCache.h" 2381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrOvalRenderer.h" 2427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h" 25d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h" 2650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#include "GrResourceCache.h" 2772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com#include "GrSoftwarePathRenderer.h" 28558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com#include "GrStencilBuffer.h" 29d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "GrStrokeInfo.h" 30278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrTextStrike.h" 31bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel#include "GrTraceMarker.h" 322a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org#include "GrTracing.h" 33d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "SkDashPathPriv.h" 347111d463cee893a479280c7af41757e709e33ef5reed@google.com#include "SkGr.h" 35dcb8ef9e866b2674e8f9a70b761fcc4fec87dbbecommit-bot@chromium.org#include "SkRTConf.h" 364784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "SkRRect.h" 375f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkStrokeRec.h" 38dcb8ef9e866b2674e8f9a70b761fcc4fec87dbbecommit-bot@chromium.org#include "SkTLazy.h" 394784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "SkTLS.h" 40933e65d914eb86b1fbbf8ea9cf1da58ac7c42500commit-bot@chromium.org#include "SkTraceEvent.h" 4127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 4282b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com// It can be useful to set this to false to test whether a bug is caused by using the 431d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com// InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffer, or to make 4482b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com// debugging simpler. 45e932c98069fd6831a03ff63d331271ef0e9703d9bsalomon@google.comSK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true, 4665eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com "Defers rendering in GrContext via GrInOrderDrawBuffer."); 4782b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com 4882b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com#define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw) 4927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 50515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 514b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com // change this to a 1 to see notifications when partial coverage fails 524b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 534b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#else 544b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 554b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#endif 564b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com 574e5559af8947ae7dc3df531b6d7a73323db20c3frobertphillips@google.comstatic const size_t MAX_RESOURCE_CACHE_COUNT = GR_DEFAULT_RESOURCE_CACHE_COUNT_LIMIT; 584e5559af8947ae7dc3df531b6d7a73323db20c3frobertphillips@google.comstatic const size_t MAX_RESOURCE_CACHE_BYTES = GR_DEFAULT_RESOURCE_CACHE_MB_LIMIT * 1024 * 1024; 5927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 6060361493548d5259d0a8afae84274c2a3c31dcacbsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; 6127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 6227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 631d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; 641d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; 6527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 66f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) 67bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 68eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com// Glorified typedef to avoid including GrDrawState.h in GrContext.h 69eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.comclass GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {}; 70eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com 715dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.orgclass GrContext::AutoCheckFlush { 725dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.orgpublic: 735dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(NULL != context); } 745dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org 755dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org ~AutoCheckFlush() { 765dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org if (fContext->fFlushToReduceCacheSize) { 775dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org fContext->flush(); 785dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org } 795dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org } 805dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org 815dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.orgprivate: 825dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrContext* fContext; 835dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org}; 845dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org 856e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.comGrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) { 866e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com GrContext* context = SkNEW(GrContext); 876e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com if (context->init(backend, backendContext)) { 886e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return context; 896e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com } else { 906e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com context->unref(); 916e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return NULL; 9227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 9327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 9427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 956e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.comGrContext::GrContext() { 966e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawState = NULL; 976e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fGpu = NULL; 98bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fClip = NULL; 996e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fPathRendererChain = NULL; 1006e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fSoftwarePathRenderer = NULL; 10195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache = NULL; 1026e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fFontCache = NULL; 1036e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBuffer = NULL; 1046e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBufferVBAllocPool = NULL; 1056e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBufferIBAllocPool = NULL; 1065dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org fFlushToReduceCacheSize = false; 1076e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fAARectRenderer = NULL; 10881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org fOvalRenderer = NULL; 109bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fViewMatrix.reset(); 11044a91dcf2542c2aa93f159ebbb5bf813ae7362c0robertphillips@google.com fMaxTextureSizeOverride = 1 << 20; 1112a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org fGpuTracingEnabled = false; 1126e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com} 1136e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1146e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.combool GrContext::init(GrBackend backend, GrBackendContext backendContext) { 115f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fGpu); 1166e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1176e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fGpu = GrGpu::Create(backend, backendContext, this); 1186e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com if (NULL == fGpu) { 1196e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return false; 1206e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com } 1216e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1226e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawState = SkNEW(GrDrawState); 1236e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fGpu->setDrawState(fDrawState); 1246e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 12595c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache = SkNEW_ARGS(GrResourceCache, (MAX_RESOURCE_CACHE_COUNT, 12695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org MAX_RESOURCE_CACHE_BYTES)); 12795c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->setOverbudgetCallback(OverbudgetCB, this); 1281836d337a85b82689287231091823f404d8cab43commit-bot@chromium.org 1296e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); 1306e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 131e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (fGpu))); 132e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com 1336e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fLastDrawWasBuffered = kNo_BufferedDraw; 1346e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1356e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fAARectRenderer = SkNEW(GrAARectRenderer); 13681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org fOvalRenderer = SkNEW(GrOvalRenderer); 1376e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1386e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDidTestPMConversions = false; 1396e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1406e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com this->setupDrawBuffer(); 1416e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1426e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return true; 143c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 144c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 14527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() { 146733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com if (NULL == fGpu) { 147733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com return; 148733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com } 149733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com 1508fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 1515acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 152950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com for (int i = 0; i < fCleanUpData.count(); ++i) { 153950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); 154950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com } 155950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com 1565acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // Since the gpu can hold scratch textures, give it a chance to let go 1575acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // of them before freeing the texture cache 1585acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com fGpu->purgeResources(); 1595acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 16095c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org delete fResourceCache; 16195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache = NULL; 16227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fFontCache; 16327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBuffer; 16427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBufferVBAllocPool; 165de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com delete fDrawBufferIBAllocPool; 1663008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 167f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->unref(); 16881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org fOvalRenderer->unref(); 169f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 170205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->unref(); 171a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeUnref(fPathRendererChain); 172a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeUnref(fSoftwarePathRenderer); 17310e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->unref(); 17427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 17527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1768fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::contextLost() { 1776e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com this->contextDestroyed(); 17853a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com this->setupDrawBuffer(); 17953a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com} 18053a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com 18153a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.comvoid GrContext::contextDestroyed() { 182205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // abandon first to so destructors 183205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // don't try to free the resources in the API. 184205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->abandonResources(); 185205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1863008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources that 1873008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // are now unusable 188a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fPathRendererChain); 189a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fSoftwarePathRenderer); 1903008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1918fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBuffer; 1928fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 193205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1948fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferVBAllocPool; 1958fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 196205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1978fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferIBAllocPool; 1988fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 1998fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 200f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->reset(); 201ef284a84f503adfd08ee52b5aee142c548698ea4commit-bot@chromium.org fOvalRenderer->reset(); 202205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 20395c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->purgeAllUnlocked(); 2045c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org 2058fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 206e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com fLayerCache->freeAll(); 2078fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 2088fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 2098fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2100a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.comvoid GrContext::resetContext(uint32_t state) { 2110a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fGpu->markContextDirty(state); 2128fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 2138fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2148fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() { 2158fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 216fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 217ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com fGpu->purgeResources(); 218ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com 219f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->reset(); 220ef284a84f503adfd08ee52b5aee142c548698ea4commit-bot@chromium.org fOvalRenderer->reset(); 221f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 22295c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->purgeAllUnlocked(); 2238fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 224e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com fLayerCache->freeAll(); 2253008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources 226a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fPathRendererChain); 227a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fSoftwarePathRenderer); 22827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 22927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 23095c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.orgvoid GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const { 23195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org if (NULL != resourceCount) { 23295c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org *resourceCount = fResourceCache->getCachedResourceCount(); 23395c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org } 23495c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org if (NULL != resourceBytes) { 23595c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org *resourceBytes = fResourceCache->getCachedResourceBytes(); 23695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org } 237d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org} 238d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org 239fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 240fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 24195ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.comGrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc, 24295ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrCacheID& cacheID, 24395ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrTextureParams* params) { 244e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org GrResourceKey resourceKey = GrTextureImpl::ComputeKey(fGpu, params, desc, cacheID); 24595c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org GrCacheable* resource = fResourceCache->find(resourceKey); 24695ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com SkSafeRef(resource); 2471f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return static_cast<GrTexture*>(resource); 248558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 249558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 25075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.combool GrContext::isTextureInCache(const GrTextureDesc& desc, 2510797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const GrCacheID& cacheID, 252b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com const GrTextureParams* params) const { 253e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org GrResourceKey resourceKey = GrTextureImpl::ComputeKey(fGpu, params, desc, cacheID); 25495c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org return fResourceCache->hasKey(resourceKey); 255fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com} 256fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com 2579fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.comvoid GrContext::addStencilBuffer(GrStencilBuffer* sb) { 258bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sb); 25946a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com 26046a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(sb->width(), 26146a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com sb->height(), 26246a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com sb->numSamples()); 26395c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->addResource(resourceKey, sb); 264558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 265558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 2669fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 267558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt) { 26846a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width, 26946a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com height, 27046a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com sampleCnt); 27195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org GrCacheable* resource = fResourceCache->find(resourceKey); 2721f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return static_cast<GrStencilBuffer*>(resource); 273558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 274558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 275b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.orgstatic void stretch_image(void* dst, 276b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.org int dstW, 277b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.org int dstH, 278f9bd04faffb936602f7f957413a8cd5b7fc44addcommit-bot@chromium.org const void* src, 279b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.org int srcW, 280b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.org int srcH, 281b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.org size_t bpp) { 282972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkFixed dx = (srcW << 16) / dstW; 283972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkFixed dy = (srcH << 16) / dstH; 28427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 285972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkFixed y = dy >> 1; 28627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2878b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t dstXLimit = dstW*bpp; 28827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int j = 0; j < dstH; ++j) { 289972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkFixed x = dx >> 1; 290f9bd04faffb936602f7f957413a8cd5b7fc44addcommit-bot@chromium.org const uint8_t* srcRow = reinterpret_cast<const uint8_t *>(src) + (y>>16)*srcW*bpp; 291f9bd04faffb936602f7f957413a8cd5b7fc44addcommit-bot@chromium.org uint8_t* dstRow = reinterpret_cast<uint8_t *>(dst) + j*dstW*bpp; 2928b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com for (size_t i = 0; i < dstXLimit; i += bpp) { 293f9bd04faffb936602f7f957413a8cd5b7fc44addcommit-bot@chromium.org memcpy(dstRow + i, srcRow + (x>>16)*bpp, bpp); 29427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com x += dx; 29527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 29627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com y += dy; 29727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 29827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 29927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 300429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comnamespace { 301429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 302429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com// position + local coordinate 303429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gVertexAttribs[] = { 304429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 305972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding} 306429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 307429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 308429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 309429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 310fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com// The desired texture is NPOT and tiled but that isn't supported by 3113319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com// the current hardware. Resize the texture to be a POT 3123319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.comGrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, 3130797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const GrCacheID& cacheID, 314f9bd04faffb936602f7f957413a8cd5b7fc44addcommit-bot@chromium.org const void* srcData, 3153319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com size_t rowBytes, 316b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com bool filter) { 31795ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, cacheID, NULL)); 3181f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com if (NULL == clampedTexture) { 31995ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com clampedTexture.reset(this->createTexture(NULL, desc, cacheID, srcData, rowBytes)); 3209fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com 3211f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com if (NULL == clampedTexture) { 3223319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com return NULL; 3233319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3243319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3250d25eefd7a25afe859cb2d4cf733a3cf07f12139robertphillips@google.com 3263319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrTextureDesc rtDesc = desc; 3273319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com rtDesc.fFlags = rtDesc.fFlags | 3283319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com kRenderTarget_GrTextureFlagBit | 3293319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com kNoStencil_GrTextureFlagBit; 3305898dce287b0d1ec535a9cfc1c5870a9cdcf5d1bcommit-bot@chromium.org rtDesc.fWidth = GrNextPow2(desc.fWidth); 3315898dce287b0d1ec535a9cfc1c5870a9cdcf5d1bcommit-bot@chromium.org rtDesc.fHeight = GrNextPow2(desc.fHeight); 3323319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3333319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 3343319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3353319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com if (NULL != texture) { 3363319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 3373319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrDrawState* drawState = fGpu->drawState(); 3383319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com drawState->setRenderTarget(texture->asRenderTarget()); 3393319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3403319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // if filtering is not desired then we want to ensure all 3413319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // texels in the resampled image are copies of texels from 3423319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // the original. 343b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTextureParams::kBilerp_FilterMode : 344b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com GrTextureParams::kNone_FilterMode); 345eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params); 3463319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 347429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs)); 348054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com 349b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0); 3503319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3513319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com if (arg.succeeded()) { 352972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint* verts = (SkPoint*) arg.vertices(); 353972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(SkPoint)); 354972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint)); 35595ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 3563319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3573319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } else { 3583319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // TODO: Our CPU stretch doesn't filter. But we create separate 35908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com // stretched textures when the texture params is either filtered or 3603319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // not. Either implement filtered stretch blit on CPU or just create 3613319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // one when FBO case fails. 3623319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3633319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com rtDesc.fFlags = kNone_GrTextureFlags; 3643319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // no longer need to clamp at min RT size. 3653319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com rtDesc.fWidth = GrNextPow2(desc.fWidth); 3663319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com rtDesc.fHeight = GrNextPow2(desc.fHeight); 3676e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org 3686e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org // We shouldn't be resizing a compressed texture. 3696e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig)); 3706e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org 3718b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t bpp = GrBytesPerPixel(desc.fConfig); 37208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com SkAutoSMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHeight); 373b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.org stretch_image(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 374b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.org srcData, desc.fWidth, desc.fHeight, bpp); 3753319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3763319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com size_t stretchedRowBytes = rtDesc.fWidth * bpp; 3773319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 378b0ce4b6fc8da4c3aa491fc43512e9187df1dfdaecommit-bot@chromium.org texture = fGpu->createTexture(rtDesc, stretchedPixels.get(), stretchedRowBytes); 379f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != texture); 3803319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3813319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3823319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com return texture; 3833319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com} 3843319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 38595ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.comGrTexture* GrContext::createTexture(const GrTextureParams* params, 38695ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrTextureDesc& desc, 38795ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrCacheID& cacheID, 388f9bd04faffb936602f7f957413a8cd5b7fc44addcommit-bot@chromium.org const void* srcData, 38950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org size_t rowBytes, 39050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org GrResourceKey* cacheKey) { 391e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org GrResourceKey resourceKey = GrTextureImpl::ComputeKey(fGpu, params, desc, cacheID); 392a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com 39395ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com GrTexture* texture; 394e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org if (GrTextureImpl::NeedsResizing(resourceKey)) { 3959c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski // We do not know how to resize compressed textures. 3969c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig)); 3979c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski 39895ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com texture = this->createResizedTexture(desc, cacheID, 39995ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com srcData, rowBytes, 400e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org GrTextureImpl::NeedsBilerp(resourceKey)); 40127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 4029c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski texture = fGpu->createTexture(desc, srcData, rowBytes); 4033319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 4043319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 4053319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com if (NULL != texture) { 4061622a6d950a4a1deb13048210bdb78d952375f05robertphillips@google.com // Adding a resource could put us overbudget. Try to free up the 4071622a6d950a4a1deb13048210bdb78d952375f05robertphillips@google.com // necessary space before adding it. 40895c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->purgeAsNeeded(1, texture->gpuMemorySize()); 40995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->addResource(resourceKey, texture); 41050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 41150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org if (NULL != cacheKey) { 41250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org *cacheKey = resourceKey; 41350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org } 41427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 4153319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 4161f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return texture; 41727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 41827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 4191f3c73825b8a1752abc6b74fbce978a430de6473skia.committer@gmail.comstatic GrTexture* create_scratch_texture(GrGpu* gpu, 42095c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org GrResourceCache* resourceCache, 421e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com const GrTextureDesc& desc) { 422e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com GrTexture* texture = gpu->createTexture(desc, NULL, 0); 423e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com if (NULL != texture) { 424e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org GrResourceKey key = GrTextureImpl::ComputeScratchKey(texture->desc()); 425e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // Adding a resource could put us overbudget. Try to free up the 426e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // necessary space before adding it. 42795c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org resourceCache->purgeAsNeeded(1, texture->gpuMemorySize()); 428e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // Make the resource exclusive so future 'find' calls don't return it 42995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org resourceCache->addResource(key, texture, GrResourceCache::kHide_OwnershipFlag); 430e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com } 431e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com return texture; 432e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com} 433e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 43495ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.comGrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match) { 43575b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com 436f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT((inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || 437e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com !(inDesc.fFlags & kNoStencil_GrTextureFlagBit)); 438e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 439e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // Renderable A8 targets are not universally supported (e.g., not on ANGLE) 4408aaac8da36bb88ab13c62e84ee6ac9ebc5cb8466bsalomon@google.com SkASSERT(this->isConfigRenderable(kAlpha_8_GrPixelConfig, inDesc.fSampleCnt > 0) || 441e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || 442e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com (inDesc.fConfig != kAlpha_8_GrPixelConfig)); 443e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 4442d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com if (!fGpu->caps()->reuseScratchTextures() && 4452d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit)) { 4462d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com // If we're never recycling this texture we can always make it the right size 44795c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org return create_scratch_texture(fGpu, fResourceCache, inDesc); 448e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com } 449e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 450e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com GrTextureDesc desc = inDesc; 4512afb8ec738fc50ea6e4500545c3cacbf346ed187rileya@google.com 4520797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com if (kApprox_ScratchTexMatch == match) { 45350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // bin by pow2 with a reasonable min 45440db6dc98d13e4632cdeaab1577a5e09fd2ad18fbsalomon@google.com static const int MIN_SIZE = 16; 455972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org desc.fWidth = SkTMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 456972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org desc.fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 45750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 458b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 459089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org GrCacheable* resource = NULL; 460b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origWidth = desc.fWidth; 461b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origHeight = desc.fHeight; 462b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 463b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com do { 464e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org GrResourceKey key = GrTextureImpl::ComputeScratchKey(desc); 465209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com // Ensure we have exclusive access to the texture so future 'find' calls don't return it 46695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org resource = fResourceCache->find(key, GrResourceCache::kHide_OwnershipFlag); 46795ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com if (NULL != resource) { 46895ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com resource->ref(); 46995ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com break; 47095ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com } 47195ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com if (kExact_ScratchTexMatch == match) { 472b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 473b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 47440db6dc98d13e4632cdeaab1577a5e09fd2ad18fbsalomon@google.com // We had a cache miss and we are in approx mode, relax the fit of the flags. 47595ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com 476fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // We no longer try to reuse textures that were previously used as render targets in 4772afb8ec738fc50ea6e4500545c3cacbf346ed187rileya@google.com // situations where no RT is needed; doing otherwise can confuse the video driver and 4782afb8ec738fc50ea6e4500545c3cacbf346ed187rileya@google.com // cause significant performance problems in some cases. 4792afb8ec738fc50ea6e4500545c3cacbf346ed187rileya@google.com if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 480b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 481b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else { 482b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 483b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 484fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 485b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } while (true); 486b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 4871f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com if (NULL == resource) { 488b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 489b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 490b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight = origHeight; 49195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org resource = create_scratch_texture(fGpu, fResourceCache, desc); 492b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 493b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 4941f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return static_cast<GrTexture*>(resource); 495b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com} 496b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 49715c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.comvoid GrContext::addExistingTextureToCache(GrTexture* texture) { 49815c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 49915c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com if (NULL == texture) { 50015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com return; 50115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com } 50215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 503521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com // This texture should already have a cache entry since it was once 504521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com // attached 505f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != texture->getCacheEntry()); 506521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com 507521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com // Conceptually, the cache entry is going to assume responsibility 5089ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // for the creation ref. Assert refcnt == 1. 509f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(texture->unique()); 510521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com 5112d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) { 5129ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // Since this texture came from an AutoScratchTexture it should 5139ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // still be in the exclusive pile. Recycle it. 51495c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->makeNonExclusive(texture->getCacheEntry()); 515e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com this->purgeCache(); 5169ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } else if (texture->getDeferredRefCount() <= 0) { 517e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // When we aren't reusing textures we know this scratch texture 518e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // will never be reused and would be just wasting time in the cache 51995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->makeNonExclusive(texture->getCacheEntry()); 52095c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->deleteResource(texture->getCacheEntry()); 5219ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } else { 5229ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // In this case (fDeferredRefCount > 0) but the cache is the only 5239ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // one holding a real ref. Mark the object so when the deferred 5249ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // ref count goes to 0 the texture will be deleted (remember 5259ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // in this code path scratch textures aren't getting reused). 5269ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com texture->setNeedsDeferredUnref(); 527e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com } 52815c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com} 52915c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 530a9b0623eac4a473517c15418dbdc1e331ee752d2robertphillips@google.com 5319fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.comvoid GrContext::unlockScratchTexture(GrTexture* texture) { 5321f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com ASSERT_OWNED_RESOURCE(texture); 533f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != texture->getCacheEntry()); 5341f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com 53550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // If this is a scratch texture we detached it from the cache 53650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // while it was locked (to avoid two callers simultaneously getting 53750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // the same texture). 5380797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com if (texture->getCacheEntry()->key().isScratch()) { 5392d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) { 54095c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->makeNonExclusive(texture->getCacheEntry()); 5419ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com this->purgeCache(); 5429ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } else if (texture->unique() && texture->getDeferredRefCount() <= 0) { 543b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com // Only the cache now knows about this texture. Since we're never 544b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com // reusing scratch textures (in this code path) it would just be 5459ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // wasting time sitting in the cache. 54695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->makeNonExclusive(texture->getCacheEntry()); 54795c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->deleteResource(texture->getCacheEntry()); 5489ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } else { 5499ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // In this case (fRefCnt > 1 || defRefCnt > 0) but we don't really 550b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com // want to readd it to the cache (since it will never be reused). 5519ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // Instead, give up the cache's ref and leave the decision up to 5529ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // addExistingTextureToCache once its ref count reaches 0. For 5539ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // this to work we need to leave it in the exclusive list. 554e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org texture->impl()->setFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit); 5559ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // Give up the cache's ref to the texture 5569ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com texture->unref(); 5579ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } 558fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 55950a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.com} 56050a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.com 56150a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.comvoid GrContext::purgeCache() { 56295c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org if (NULL != fResourceCache) { 56395c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->purgeAsNeeded(); 564eb9b3e164e55b8d15e1c25bfb1332917453cbc3arobertphillips@google.com } 56515c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com} 56615c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 567cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.orgbool GrContext::OverbudgetCB(void* data) { 568f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != data); 569cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 570cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org GrContext* context = reinterpret_cast<GrContext*>(data); 571cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 572cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org // Flush the InOrderDrawBuffer to possibly free up some textures 5735dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org context->fFlushToReduceCacheSize = true; 574cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 575cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org return true; 576cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org} 577cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 578cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 57975b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn, 58027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcData, 58127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t rowBytes) { 58275b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc descCopy = descIn; 58375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com return fGpu->createTexture(descCopy, srcData, rowBytes); 58427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 58527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 58695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.orgvoid GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const { 58795c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->getLimits(maxTextures, maxTextureBytes); 58827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 58927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 59095c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.orgvoid GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) { 59195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->setLimits(maxTextures, maxTextureBytes); 59227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 59327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 594919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const { 595972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); 596919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 597919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 598919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 599bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com return fGpu->caps()->maxRenderTargetSize(); 60027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 60127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 6028a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.comint GrContext::getMaxSampleCount() const { 603bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com return fGpu->caps()->maxSampleCount(); 6048a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com} 6058a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com 60627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 60727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 60816e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.comGrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) { 60916e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com return fGpu->wrapBackendTexture(desc); 610e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 611e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 61216e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.comGrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { 61316e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com return fGpu->wrapBackendRenderTarget(desc); 614e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 615e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 6165877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 6175877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com 618b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, 6191f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com int width, int height) const { 620c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com const GrDrawTargetCaps* caps = fGpu->caps(); 6216e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org if (!caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { 62227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 62327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 62427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 625f9dae780c2c46a1f08adbbe8de2faaba091254d4tfarina bool isPow2 = SkIsPow2(width) && SkIsPow2(height); 62627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 62727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!isPow2) { 628b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com bool tiled = NULL != params && params->isTiled(); 629bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com if (tiled && !caps->npotTextureTileSupport()) { 63027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 63127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 63227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 63327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return true; 63427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 63527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 63627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 63727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 63827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 639fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgvoid GrContext::clear(const SkIRect* rect, 64007ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com const GrColor color, 64156ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com bool canIgnoreRect, 642c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com GrRenderTarget* target) { 643eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 6445dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 64518bb41e9563748fbde07c1540da9314cbb7d1dc8skia.committer@gmail.com this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->clear(rect, color, 64656ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com canIgnoreRect, target); 64727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 64827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 6495dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.comvoid GrContext::drawPaint(const GrPaint& origPaint) { 65027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 65127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // don't overflow fixed-point implementations 652fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect r; 653d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com r.setLTRB(0, 0, 65481712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkIntToScalar(getRenderTarget()->width()), 65581712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkIntToScalar(getRenderTarget()->height())); 656b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix inverse; 6575dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkTCopyOnFirstWrite<GrPaint> paint(origPaint); 658fea85ac3e31842f80493e2df8a93a28f21cd815frobertphillips@google.com AutoMatrix am; 6598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6604f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 6614f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // map the four corners and bound them with a new rect. This will not 6624f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // produce a correct result for some perspective matrices. 6638c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!this->getMatrix().hasPerspective()) { 664bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org if (!fViewMatrix.invert(&inverse)) { 665e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrPrintf("Could not invert matrix\n"); 6668c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6678c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 66827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com inverse.mapRect(&r); 66927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 6703cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com if (!am.setIdentity(this, paint.writable())) { 6713cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com GrPrintf("Could not invert matrix\n"); 6723cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com return; 6738c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 67427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 6754f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // by definition this fills the entire clip, no need for AA 6765dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com if (paint->isAntiAlias()) { 6775dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com paint.writable()->setAntiAlias(false); 6784f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com } 6795dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com this->drawRect(*paint, r); 68027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 68127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 68203e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#ifdef SK_DEVELOPER 68303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.orgvoid GrContext::dumpFontCache() const { 68403e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org fFontCache->dump(); 68503e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org} 68603e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#endif 68703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org 688205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 689205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 69027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 69127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 69227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 69327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster. 69427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 695972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.orgstatic void setStrokeRectStrip(SkPoint verts[10], SkRect rect, 69681712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar width) { 69781712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com const SkScalar rad = SkScalarHalf(width); 698205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com rect.sort(); 69927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 70027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 70127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 70227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 70327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 70427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 70527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 70627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 70727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 70827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[8] = verts[0]; 70927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[9] = verts[1]; 71027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 71127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 712fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgstatic bool isIRect(const SkRect& r) { 713eafdf126d44abadf01e7d2910739e228f557df51skia.committer@gmail.com return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && 714eafdf126d44abadf01e7d2910739e228f557df51skia.committer@gmail.com SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); 715afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com} 716afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com 717205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 718fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& rect, 719df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com SkScalar strokeWidth, 72024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org const SkMatrix& combinedMatrix, 72124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect* devBoundRect, 722a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool* useVertexCoverage) { 7232eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we use a simple coverage ramp to do aa on axis-aligned rects 724fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // we check if the rect will be axis-aligned, and the rect won't land on 7252eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // integer coords. 726d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 727a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // we are keeping around the "tweak the alpha" trick because 728a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // it is our only hope for the fixed-pipe implementation. 729a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // In a shader implementation we can give a separate coverage input 730289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 731a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = false; 7322b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com if (!target->getDrawState().canTweakAlphaForCoverage()) { 733e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (target->shouldDisableCoverageAAForBlend()) { 734515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 7352eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 7361983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 737a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 7382eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com } else { 7392eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com *useVertexCoverage = true; 740a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 741205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 7428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 7438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 744205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 745205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 746205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 747df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com if (0 == strokeWidth && target->willUseHWAALines()) { 748205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 749205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 750205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7514b140b5fbedcb75d0b9587fa9d232ce54d9c7eb5robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 752df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com if (strokeWidth >= 0) { 753df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com#endif 75424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!combinedMatrix.preservesAxisAlignment()) { 755df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com return false; 756df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } 757205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7584b140b5fbedcb75d0b9587fa9d232ce54d9c7eb5robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 759df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } else { 76024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!combinedMatrix.preservesRightAngles()) { 761df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com return false; 762df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } 763205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 764df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com#endif 765205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 76624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org combinedMatrix.mapRect(devBoundRect, rect); 76728ac96e40d705f7fb08a61ac027e15de8d91823crobertphillips@google.com 768afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com if (strokeWidth < 0) { 76924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return !isIRect(*devBoundRect); 770afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com } else { 771afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com return true; 772afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com } 773205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 774205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 77524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.orgstatic inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) { 77624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return point.fX >= rect.fLeft && point.fX <= rect.fRight && 77724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org point.fY >= rect.fTop && point.fY <= rect.fBottom; 77824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org} 77924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 78027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 781fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& rect, 782d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const GrStrokeInfo* strokeInfo, 783b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix* matrix) { 784d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (NULL != strokeInfo && strokeInfo->isDashed()) { 785d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkPath path; 786d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel path.addRect(rect); 787d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel this->drawPath(paint, path, *strokeInfo); 788d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel return; 789d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel } 790d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 791eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 7925dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 7935dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 79427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 7952a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); 7962a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 797d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWidth(); 79824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkMatrix combinedMatrix = target->drawState()->getViewMatrix(); 79924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (NULL != matrix) { 80024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org combinedMatrix.preConcat(*matrix); 80124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 80224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 80324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking 80424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // cases where the RT is fully inside a stroke. 80524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (width < 0) { 80624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect rtRect; 80724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect); 80824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect clipSpaceRTRect = rtRect; 80924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org bool checkClip = false; 81024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (NULL != this->getClip()) { 81124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org checkClip = true; 81224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), 81324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkIntToScalar(this->getClip()->fOrigin.fY)); 81424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 81524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Does the clip contain the entire RT? 81624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpaceRTRect)) { 81724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkMatrix invM; 81824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!combinedMatrix.invert(&invM)) { 81924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return; 82024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 82124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Does the rect bound the RT? 82224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkPoint srcSpaceRTQuad[4]; 82324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org invM.mapRectToQuad(srcSpaceRTQuad, rtRect); 82424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) && 82524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[1]) && 82624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[2]) && 82724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[3])) { 82824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Will it blend? 82924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org GrColor clearColor; 83024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (paint.isOpaqueAndConstantColor(&clearColor)) { 83156ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com target->clear(NULL, clearColor, true); 83224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return; 83324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 83424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 83524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 83624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 83724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 83824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect devBoundRect; 839a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage; 840c7448cef098b835d6f9adf8a365fde9de076f178bsalomon@google.com bool needAA = paint.isAntiAlias() && 841bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org !target->getDrawState().getRenderTarget()->isMultisampled(); 84224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org bool doAA = needAA && apply_aa_to_rect(target, rect, width, combinedMatrix, &devBoundRect, 843289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &useVertexCoverage); 844d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 845d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec(); 846d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 847205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 848137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 849137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 850e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 851e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 852205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 8536006d0f8c4f19d19a12de20826f731f52ac822a7commit-bot@chromium.org fAARectRenderer->strokeAARect(this->getGpu(), target, rect, 8546006d0f8c4f19d19a12de20826f731f52ac822a7commit-bot@chromium.org combinedMatrix, devBoundRect, 855d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel strokeRec, useVertexCoverage); 856205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 857df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com // filled AA rect 858fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com fAARectRenderer->fillAARect(this->getGpu(), target, 85924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect, combinedMatrix, devBoundRect, 860b19cb7f36785f3ad3b1512c342fc662ab79e3fcarobertphillips@google.com useVertexCoverage); 861205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 862205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 863205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 864205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 86527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 86627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: consider making static vertex buffers for these cases. 8676438695222333981fafee9c8c09f3bf51dce3816bsalomon@google.com // Hairline could be done by just adding closing vertex to 8686438695222333981fafee9c8c09f3bf51dce3816bsalomon@google.com // unitSquareVertexBuffer() 86926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 87027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int worstCaseVertCount = 10; 8719b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com target->drawState()->setDefaultVertexAttribs(); 872b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0); 87327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 87427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 8756513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 87627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 87727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 87827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 87927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primType; 88027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertCount; 881972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint* vertex = geo.positions(); 88227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 88327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width > 0) { 88427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 10; 88547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com primType = kTriangleStrip_GrPrimitiveType; 88627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com setStrokeRectStrip(vertex, rect, width); 88727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 88827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // hairline 88927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 5; 89047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com primType = kLineStrip_GrPrimitiveType; 89127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 89227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 89327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 89427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 89527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 89627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 89727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 8988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 89927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 9008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 9012fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com avmr.set(drawState, *matrix); 90227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 90327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 90427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 90527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 906df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com // filled BW rect 907235ef3d0e253200af43bb69139df09744f5ddbefrobertphillips@google.com target->drawSimpleRect(rect, matrix); 90827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 90927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 91027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 91127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 912fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& dstRect, 913fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& localRect, 914b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix* dstMatrix, 915c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const SkMatrix* localMatrix) { 916eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 9175dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 9185dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 9196438695222333981fafee9c8c09f3bf51dce3816bsalomon@google.com 9202a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); 9212a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 922c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com target->drawRect(dstRect, dstMatrix, &localRect, localMatrix); 92327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 92427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 925429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comnamespace { 926429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 927429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gPosUVColorAttribs[] = { 928429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 929972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding }, 930972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org {kVec4ub_GrVertexAttribType, 2*sizeof(SkPoint), kColor_GrVertexAttribBinding} 931429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 932429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 933429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gPosColorAttribs[] = { 934429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 935972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding}, 936429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 937429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 938429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comstatic void set_vertex_attributes(GrDrawState* drawState, 939972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint* texCoords, 940429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com const GrColor* colors, 941429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com int* colorOffset, 942429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com int* texOffset) { 943429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *texOffset = -1; 944429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *colorOffset = -1; 945429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 946429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com if (NULL != texCoords && NULL != colors) { 947972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org *texOffset = sizeof(SkPoint); 948972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org *colorOffset = 2*sizeof(SkPoint); 949429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gPosUVColorAttribs>(3); 950429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } else if (NULL != texCoords) { 951972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org *texOffset = sizeof(SkPoint); 952429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gPosUVColorAttribs>(2); 953429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } else if (NULL != colors) { 954972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org *colorOffset = sizeof(SkPoint); 955429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gPosColorAttribs>(2); 956429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } else { 957429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gPosColorAttribs>(1); 958429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } 959429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com} 960429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 961429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 962429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 96327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 96427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 96527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 966972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint positions[], 967972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint texCoords[], 96827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 96927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 97027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 971eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 9725dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 9735a56793b2a19eaf90b67d6f24441cc475d74ef17commit-bot@chromium.org GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope 9745a56793b2a19eaf90b67d6f24441cc475d74ef17commit-bot@chromium.org 9755dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 976e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawState* drawState = target->drawState(); 97727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9782a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); 9792a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 9809b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com int colorOffset = -1, texOffset = -1; 981429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset); 9829b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 9839b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com size_t vertexSize = drawState->getVertexSize(); 984972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org if (sizeof(SkPoint) != vertexSize) { 985b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com if (!geo.set(target, vertexCount, 0)) { 9866513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 98727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 98827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 98927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* curVertex = geo.vertices(); 99027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 99127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 992972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org *((SkPoint*)curVertex) = positions[i]; 99327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9949b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com if (texOffset >= 0) { 995972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org *(SkPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; 99627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 9979b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com if (colorOffset >= 0) { 99827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 99927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 100026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 100127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 100227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 1003b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com target->setVertexSourceToArray(positions, vertexCount); 100427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 100527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1006fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // we don't currently apply offscreen AA to this path. Need improved 1007919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 1008a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com 10098295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (NULL != indices) { 1010919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 10118295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 10120406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com target->resetIndexSource(); 101327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 10148295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 10158295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 101627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 101727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 101806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 101993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1020f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.orgvoid GrContext::drawRRect(const GrPaint& paint, 10210a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org const SkRRect& rrect, 1022d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const GrStrokeInfo& strokeInfo) { 10230a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (rrect.isEmpty()) { 102419dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org return; 102519dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org } 1026f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1027d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (strokeInfo.isDashed()) { 1028d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkPath path; 1029d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel path.addRRect(rrect); 1030d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel this->drawPath(paint, path, strokeInfo); 1031d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel return; 1032d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel } 1033d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1034eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 10355dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 10365dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 1037f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 10382a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target); 10392a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 1040d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); 1041d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1042d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (!fOvalRenderer->drawRRect(target, this, paint.isAntiAlias(), rrect, strokeRec)) { 1043f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkPath path; 10440a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org path.addRRect(rrect); 1045d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); 1046f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1047f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org} 1048f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1049f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 1050f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 10510a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.orgvoid GrContext::drawDRRect(const GrPaint& paint, 10520a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org const SkRRect& outer, 10530a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org const SkRRect& inner) { 10540a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (outer.isEmpty()) { 10550a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org return; 10560a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 10570a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 10580a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org AutoRestoreEffects are; 10590a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org AutoCheckFlush acf(this); 10600a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 10610a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 10620a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target); 10630a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 10640a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (!fOvalRenderer->drawDRRect(target, this, paint.isAntiAlias(), outer, inner)) { 10650a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org SkPath path; 10660a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org path.addRRect(inner); 10670a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org path.addRRect(outer); 10680a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org path.setFillType(SkPath::kEvenOdd_FillType); 10690a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 1070d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle); 10710a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org this->internalDrawPath(target, paint.isAntiAlias(), path, fillRec); 10720a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 10730a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org} 10740a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 10750a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 10760a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 107746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.comvoid GrContext::drawOval(const GrPaint& paint, 1078fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& oval, 1079d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const GrStrokeInfo& strokeInfo) { 108019dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org if (oval.isEmpty()) { 108119dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org return; 108219dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org } 108393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1084d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (strokeInfo.isDashed()) { 1085d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkPath path; 1086d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel path.addOval(oval); 1087d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel this->drawPath(paint, path, strokeInfo); 1088d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel return; 1089d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel } 1090d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1091eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 10925dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 10935dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 10940982d35187da7e1ed6c0eba5951bbdadca8b33e7bsalomon@google.com 10952a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawOval", target); 10962a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 1097d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); 1098d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1099d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1100d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, strokeRec)) { 110181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkPath path; 110281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org path.addOval(oval); 1103d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); 110446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 1105150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 110627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 110783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com// Can 'path' be drawn as a pair of filled nested rectangles? 110883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.comstatic bool is_nested_rects(GrDrawTarget* target, 110983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com const SkPath& path, 111083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com const SkStrokeRec& stroke, 111183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkRect rects[2], 111283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com bool* useVertexCoverage) { 111383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkASSERT(stroke.isFillStyle()); 111483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 111583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (path.isInverseFillType()) { 111683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 111783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 111883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 111983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com const GrDrawState& drawState = target->getDrawState(); 112083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 112183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // TODO: this restriction could be lifted if we were willing to apply 112283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // the matrix to all the points individually rather than just to the rect 112383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 112483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 112583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 112683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 112783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com *useVertexCoverage = false; 112883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (!target->getDrawState().canTweakAlphaForCoverage()) { 1129e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (target->shouldDisableCoverageAAForBlend()) { 113083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 113183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } else { 113283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com *useVertexCoverage = true; 113383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 113483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 113583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 113683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkPath::Direction dirs[2]; 113783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (!path.isNestedRects(rects, dirs)) { 113883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 113983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 114083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 11418d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { 114283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // The two rects need to be wound opposite to each other 11438d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com return false; 114483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 114583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 11468d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com // Right now, nested rects where the margin is not the same width 11478d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com // all around do not render correctly 11488d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com const SkScalar* outer = rects[0].asScalars(); 11498d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com const SkScalar* inner = rects[1].asScalars(); 11508d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com 11518d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com SkScalar margin = SkScalarAbs(outer[0] - inner[0]); 11528d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com for (int i = 1; i < 4; ++i) { 11538d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com SkScalar temp = SkScalarAbs(outer[i] - inner[i]); 11548d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com if (!SkScalarNearlyEqual(margin, temp)) { 11558d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com return false; 11568d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com } 11578d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com } 11588d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com 11598d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com return true; 11608d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com} 116183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 1162d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdanielvoid GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrokeInfo& strokeInfo) { 116327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1164fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 116512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com if (path.isInverseFillType()) { 1166fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->drawPaint(paint); 1167fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1168fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1169fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1170fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1171d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (strokeInfo.isDashed()) { 1172e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkPoint pts[2]; 1173e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (path.isLine(pts)) { 1174e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel AutoRestoreEffects are; 1175e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel AutoCheckFlush acf(this); 1176e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 1177e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawState* drawState = target->drawState(); 1178e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 1179e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel SkMatrix origViewMatrix = drawState->getViewMatrix(); 1180e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel GrDrawState::AutoViewMatrixRestore avmr; 1181e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (avmr.setIdentity(target->drawState())) { 1182e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel if (GrDashingEffect::DrawDashLine(pts, paint, strokeInfo, fGpu, target, 1183e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel origViewMatrix)) { 1184e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel return; 1185e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 1186e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 1187e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel } 1188e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel 1189e61c411c1258a323a010558c08de3d9f8d170dcaegdaniel // Filter dashed path into new path with the dashing applied 1190d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); 1191d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkTLazy<SkPath> effectPath; 1192d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel GrStrokeInfo newStrokeInfo(strokeInfo, false); 1193d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkStrokeRec* stroke = newStrokeInfo.getStrokeRecPtr(); 1194d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, NULL, info)) { 1195d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel this->drawPath(paint, *effectPath.get(), newStrokeInfo); 1196d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel return; 1197d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel } 1198d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1199d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel this->drawPath(paint, path, newStrokeInfo); 1200d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel return; 1201d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel } 1202d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 120381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // Note that internalDrawPath may sw-rasterize the path into a scratch texture. 120481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // Scratch textures can be recycled after they are returned to the texture 120581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // cache. This presents a potential hazard for buffered drawing. However, 120681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // the writePixels that uploads to the scratch will perform a flush so we're 120781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // OK. 1208eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 12095dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 12105dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 1211e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org GrDrawState* drawState = target->drawState(); 121281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 12132a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::drawPath", target); 12142a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 1215d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); 1216d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel 1217e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisampled(); 1218e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org 1219d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { 122083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // Concave AA paths are expensive - try to avoid them for special cases 122183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com bool useVertexCoverage; 122283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkRect rects[2]; 122383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 1224d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel if (is_nested_rects(target, path, strokeRec, rects, &useVertexCoverage)) { 1225e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org SkMatrix origViewMatrix = drawState->getViewMatrix(); 1226137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 1227137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 122883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return; 122983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 123083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 123183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com fAARectRenderer->fillAANestedRects(this->getGpu(), target, 123283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com rects, 1233137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com origViewMatrix, 123483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com useVertexCoverage); 123583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return; 123683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 123783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 123883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 123993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkRect ovalRect; 124046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com bool isOval = path.isOval(&ovalRect); 124146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 12427e32851d5473d14db5c396f5877e3dfcb7b19f6dskia.committer@gmail.com if (!isOval || path.isInverseFillType() 1243d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, strokeRec)) { 1244d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); 124593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 124693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 124793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 12481b20a10f0205da2d53e0837e4ddc6b2bd3b8a462bsalomon@google.comvoid GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, 1249d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel const GrStrokeInfo& strokeInfo) { 125019dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org SkASSERT(!path.isEmpty()); 125193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 12522a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); 12532a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 12542a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org 1255d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1256d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1257d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1258d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1259e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org bool useCoverageAA = useAA && 1260e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org !target->getDrawState().getRenderTarget()->isMultisampled() && 1261e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org !target->shouldDisableCoverageAAForBlend(); 1262e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org 1263289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1264e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org GrPathRendererChain::DrawType type = 1265e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : 1266e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com GrPathRendererChain::kColor_DrawType; 126745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 1268eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com const SkPath* pathPtr = &path; 1269f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org SkTLazy<SkPath> tmpPath; 1270d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel SkTCopyOnFirstWrite<SkStrokeRec> stroke(strokeInfo.getStrokeRec()); 1271eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1272eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com // Try a 1st time without stroking the path and without allowing the SW renderer 1273e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type); 1274eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1275e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (NULL == pr) { 1276f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, this->getMatrix(), NULL)) { 1277eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com // It didn't work the 1st time, so try again with the stroked path 1278f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org if (stroke->applyToPath(tmpPath.init(), *pathPtr)) { 1279f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org pathPtr = tmpPath.get(); 1280f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org stroke.writable()->setFillStyle(); 1281e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (pathPtr->isEmpty()) { 1282e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org return; 1283e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org } 1284eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 1285eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 128619dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org 1287eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com // This time, allow SW renderer 1288e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type); 1289eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 1290eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1291e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (NULL == pr) { 1292515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 12933008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 12941983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 12953008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 12963008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 12973008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1298e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com pr->drawPath(*pathPtr, *stroke, target, useCoverageAA); 129927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 13008295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 130127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 130227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1303a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1304e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com if (NULL == fDrawBuffer) { 1305e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com return; 1306e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com } 1307e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com 1308a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1309a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1310a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 13116e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBuffer->flush(); 131253a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 13135dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org fFlushToReduceCacheSize = false; 131427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 131527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 13169c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.combool GrContext::writeTexturePixels(GrTexture* texture, 13170342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 13180342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com GrPixelConfig config, const void* buffer, size_t rowBytes, 13190342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 1320bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1321bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 13229c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if ((kUnpremul_PixelOpsFlag & flags) || !fGpu->canWriteTexturePixels(texture, config)) { 13239c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (NULL != texture->asRenderTarget()) { 13249c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return this->writeRenderTargetPixels(texture->asRenderTarget(), 13259c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com left, top, width, height, 13269c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com config, buffer, rowBytes, flags); 13279c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } else { 13289c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 13299c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } 13306f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 13319c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com 13320342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 13330342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com this->flush(); 13340342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com } 13356f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 13369c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return fGpu->writeTexturePixels(texture, left, top, width, height, 13379c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com config, buffer, rowBytes); 13386f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 13396f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 13400342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.combool GrContext::readTexturePixels(GrTexture* texture, 13410342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 13420342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com GrPixelConfig config, void* buffer, size_t rowBytes, 13430342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 1344bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1345669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1346669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 1347669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL != target) { 13480342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com return this->readRenderTargetPixels(target, 13490342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com left, top, width, height, 13500342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com config, buffer, rowBytes, 13510342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com flags); 1352669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } else { 13533f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org // TODO: make this more efficient for cases where we're reading the entire 13543f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org // texture, i.e., use GetTexImage() instead 13553f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org 13563f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org // create scratch rendertarget and read from that 13573f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org GrAutoScratchTexture ast; 13583f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org GrTextureDesc desc; 13593f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fFlags = kRenderTarget_GrTextureFlagBit; 13603f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fWidth = width; 13613f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fHeight = height; 13623f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fConfig = config; 13633f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fOrigin = kTopLeft_GrSurfaceOrigin; 13643f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org ast.set(this, desc, kExact_ScratchTexMatch); 13653f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org GrTexture* dst = ast.texture(); 13663f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org if (NULL != dst && NULL != (target = dst->asRenderTarget())) { 13673f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org this->copyTexture(texture, target, NULL); 13683f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org return this->readRenderTargetPixels(target, 13693f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org left, top, width, height, 13703f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org config, buffer, rowBytes, 13713f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org flags); 13723f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org } 1373583b18a20959c9ac360316a366f4ddd9598bdf52skia.committer@gmail.com 1374669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1375669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1376669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com} 1377669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1378a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkConfig8888.h" 1379a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 13807111d463cee893a479280c7af41757e709e33ef5reed@google.com// toggles between RGBA and BGRA 13817111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic SkColorType toggle_colortype32(SkColorType ct) { 13827111d463cee893a479280c7af41757e709e33ef5reed@google.com if (kRGBA_8888_SkColorType == ct) { 13837111d463cee893a479280c7af41757e709e33ef5reed@google.com return kBGRA_8888_SkColorType; 13847111d463cee893a479280c7af41757e709e33ef5reed@google.com } else { 13857111d463cee893a479280c7af41757e709e33ef5reed@google.com SkASSERT(kBGRA_8888_SkColorType == ct); 13867111d463cee893a479280c7af41757e709e33ef5reed@google.com return kRGBA_8888_SkColorType; 1387231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org } 1388231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org} 1389231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org 13900342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.combool GrContext::readRenderTargetPixels(GrRenderTarget* target, 13910342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 13929c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig dstConfig, void* buffer, size_t rowBytes, 13930342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 1394bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1395bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 1396fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (NULL == target) { 1397bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target = fRenderTarget.get(); 1398c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (NULL == target) { 1399c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1400c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1401c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1402669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 14036f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 14046f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 14056f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1406c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1407a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul. 1408c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1409a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll 1410a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read. 1411a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top, 14129c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com width, height, dstConfig, 1413c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 14149c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // We ignore the preferred config if it is different than our config unless it is an R/B swap. 14159c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // In that case we'll perform an R and B swap while drawing to a scratch texture of the swapped 14169c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // config. Then we will call readPixels on the scratch with the swapped config. The swaps during 14179c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from 14189c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // dstConfig. 14199c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig readConfig = dstConfig; 14209c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com bool swapRAndB = false; 14215d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org if (GrPixelConfigSwapRAndB(dstConfig) == 14225d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org fGpu->preferredReadPixelsConfig(dstConfig, target->config())) { 14239c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com readConfig = GrPixelConfigSwapRAndB(readConfig); 14249c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com swapRAndB = true; 14259c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } 1426a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 14270342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); 1428c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 14299c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (unpremul && !GrPixelConfigIs8888(dstConfig)) { 1430a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // The unpremul flag is only allowed for these two configs. 14310a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 14320a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 1433a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1434a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If the src is a texture and we would have to do conversions after read pixels, we instead 1435a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // do the conversions by drawing the src to a scratch texture. If we handle any of the 1436a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // conversions in the draw we set the corresponding bool to false so that we don't reapply it 1437a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // on the read back pixels. 1438a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrTexture* src = target->asTexture(); 1439c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com GrAutoScratchTexture ast; 1440a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (NULL != src && (swapRAndB || unpremul || flipY)) { 1441a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Make the scratch a render target because we don't have a robust readTexturePixels as of 1442a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // yet. It calls this function. 144375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 144475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit; 144575b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 144675b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 1447a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fConfig = readConfig; 14483cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org desc.fOrigin = kTopLeft_GrSurfaceOrigin; 1449c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 14509c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // When a full read back is faster than a partial we could always make the scratch exactly 1451a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // match the passed rect. However, if we see many different size rectangles we will trash 1452a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // our texture cache and pay the cost of creating and destroying many textures. So, we only 1453a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // request an exact match when the caller is reading an entire RT. 145456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 145556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 145656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 145756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 145856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 145956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 146056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com match = kExact_ScratchTexMatch; 146156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 146256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ast.set(this, desc, match); 1463c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* texture = ast.texture(); 1464a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (texture) { 1465d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com // compute a matrix to perform the draw 1466b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix textureMatrix; 14673cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1468d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com textureMatrix.postIDiv(src->width(), src->height()); 1469d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1470adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com SkAutoTUnref<const GrEffectRef> effect; 1471a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (unpremul) { 1472adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com effect.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix)); 1473adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (NULL != effect) { 14749c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com unpremul = false; // we no longer need to do this on CPU after the read back. 1475d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com } 1476a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1477a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If we failed to create a PM->UPM effect and have no other conversions to perform then 1478a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // there is no longer any point to using the scratch. 1479adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (NULL != effect || flipY || swapRAndB) { 1480adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (!effect) { 1481adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com effect.reset(GrConfigConversionEffect::Create( 1482adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com src, 1483adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com swapRAndB, 1484adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com GrConfigConversionEffect::kNone_PMConversion, 1485adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com textureMatrix)); 1486a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1487a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com swapRAndB = false; // we will handle the swap in the draw. 1488a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 148913f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // We protect the existing geometry here since it may not be 149013f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // clear to the caller that a draw operation (i.e., drawSimpleRect) 149113f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // can be invoked in this method 149213f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit); 1493a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 1494f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(effect); 1495eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com drawState->addColorEffect(effect); 1496d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1497a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com drawState->setRenderTarget(texture->asRenderTarget()); 1498fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 1499a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com fGpu->drawSimpleRect(rect, NULL); 1500a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // we want to read back from the scratch's origin 1501a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com left = 0; 1502a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com top = 0; 1503a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com target = texture->asRenderTarget(); 1504a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1505c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1506a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1507a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fGpu->readPixels(target, 1508a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com left, top, width, height, 15093cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org readConfig, buffer, rowBytes)) { 1510a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return false; 1511a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1512d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com // Perform any conversions we weren't able to perform using a scratch texture. 15133cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (unpremul || swapRAndB) { 15147111d463cee893a479280c7af41757e709e33ef5reed@google.com SkDstPixelInfo dstPI; 15157111d463cee893a479280c7af41757e709e33ef5reed@google.com if (!GrPixelConfig2ColorType(dstConfig, &dstPI.fColorType)) { 15167111d463cee893a479280c7af41757e709e33ef5reed@google.com return false; 15177111d463cee893a479280c7af41757e709e33ef5reed@google.com } 15187111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fAlphaType = kUnpremul_SkAlphaType; 15197111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fPixels = buffer; 15207111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fRowBytes = rowBytes; 1521be41d38f1c076c9e4dc595a6e1a4eb5ccdbd307bskia.committer@gmail.com 15227111d463cee893a479280c7af41757e709e33ef5reed@google.com SkSrcPixelInfo srcPI; 15237111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fColorType = swapRAndB ? toggle_colortype32(dstPI.fColorType) : dstPI.fColorType; 15247111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fAlphaType = kPremul_SkAlphaType; 15257111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fPixels = buffer; 15267111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fRowBytes = rowBytes; 1527be41d38f1c076c9e4dc595a6e1a4eb5ccdbd307bskia.committer@gmail.com 15287111d463cee893a479280c7af41757e709e33ef5reed@google.com return srcPI.convertPixelsTo(&dstPI, width, height); 1529c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1530a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return true; 153127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 153227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 153375f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.comvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 1534f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(target); 153575f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com ASSERT_OWNED_RESOURCE(target); 153675f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // In the future we may track whether there are any pending draws to this 153775f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // target. We don't today so we always perform a flush. We don't promise 153875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // this to our clients, though. 153975f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com this->flush(); 154075f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com fGpu->resolveRenderTarget(target); 154175f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com} 154275f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com 154328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid GrContext::discardRenderTarget(GrRenderTarget* target) { 154428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org SkASSERT(target); 154528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org ASSERT_OWNED_RESOURCE(target); 154628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org AutoRestoreEffects are; 154728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org AutoCheckFlush acf(this); 154828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->discard(target); 154928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 155028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 1551a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.comvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) { 1552ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1553ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1554ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1555ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1556ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 15571ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // Writes pending to the source texture are not tracked, so a flush 15581ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // is required to ensure that the copy captures the most recent contents 1559adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com // of the source texture. See similar behavior in 15601ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // GrContext::resolveRenderTarget. 15611ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com this->flush(); 15621ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com 1563873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 15648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 15658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 1566b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix sampleM; 1567ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 1568a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); 1569a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (NULL != topLeft) { 1570a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com srcRect.offset(*topLeft); 1571a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 1572a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height()); 1573a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (!srcRect.intersect(srcBounds)) { 1574a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com return; 1575a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 1576a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com sampleM.preTranslate(SkIntToScalar(srcRect.fLeft), SkIntToScalar(srcRect.fTop)); 1577eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com drawState->addColorTextureEffect(src, sampleM); 1578a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkRect dstR = SkRect::MakeWH(SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); 1579a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com fGpu->drawSimpleRect(dstR, NULL); 1580ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1581ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 15829c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.combool GrContext::writeRenderTargetPixels(GrRenderTarget* target, 15830342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 15849c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig srcConfig, 15850342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com const void* buffer, 15860342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com size_t rowBytes, 15870342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 1588bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 15896f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 1590fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (NULL == target) { 1591bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target = fRenderTarget.get(); 15926f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 15939c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 15946f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 15956f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 159627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1597a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it (e.g. glDrawPixels on 1598a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // desktop GL). 1599a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1600a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // We will always call some form of writeTexturePixels and we will pass our flags on to it. 1601a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Thus, we don't perform a flush here since that call will do it (if the kNoFlush flag isn't 1602a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // set.) 160327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 16040342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com // If the RT is also a texture and we don't have to premultiply then take the texture path. 16050342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com // We expect to be at least as fast or faster since it doesn't use an intermediate texture as 16060342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com // we do below. 1607fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 16084382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org#if !defined(SK_BUILD_FOR_MAC) 1609a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called on a texture 1610a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // attached to an FBO. The FBO still sees the old image. TODO: determine what OS versions and/or 1611a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // HW is affected. 16129c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (NULL != target->asTexture() && !(kUnpremul_PixelOpsFlag & flags) && 16139c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com fGpu->canWriteTexturePixels(target->asTexture(), srcConfig)) { 16149c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return this->writeTexturePixels(target->asTexture(), 16159c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com left, top, width, height, 16169c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com srcConfig, buffer, rowBytes, flags); 1617a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1618a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif 1619d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 16209c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // We ignore the preferred config unless it is a R/B swap of the src config. In that case 16219c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // we will upload the original src data to a scratch texture but we will spoof it as the swapped 16229c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // config. This scratch will then have R and B swapped. We correct for this by swapping again 16239c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // when drawing the scratch to the dst using a conversion effect. 16249c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com bool swapRAndB = false; 16259c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig writeConfig = srcConfig; 16265d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org if (GrPixelConfigSwapRAndB(srcConfig) == 16275d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org fGpu->preferredWritePixelsConfig(srcConfig, target->config())) { 16289c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com writeConfig = GrPixelConfigSwapRAndB(srcConfig); 16299c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com swapRAndB = true; 1630a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1631a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 163275b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 163375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 163475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 16359c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com desc.fConfig = writeConfig; 163650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture ast(this, desc); 163750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* texture = ast.texture(); 163827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL == texture) { 16399c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 164027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1641d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1642adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com SkAutoTUnref<const GrEffectRef> effect; 1643b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix textureMatrix; 1644d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com textureMatrix.setIDiv(texture->width(), texture->height()); 1645d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1646a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // allocate a tmp buffer and sw convert the pixels to premul 1647a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); 1648a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1649a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (kUnpremul_PixelOpsFlag & flags) { 16509c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (!GrPixelConfigIs8888(srcConfig)) { 16519c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 1652a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1653adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com effect.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); 16549c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // handle the unpremul step on the CPU if we couldn't create an effect to do it. 1655adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (NULL == effect) { 16567111d463cee893a479280c7af41757e709e33ef5reed@google.com SkSrcPixelInfo srcPI; 16577111d463cee893a479280c7af41757e709e33ef5reed@google.com if (!GrPixelConfig2ColorType(srcConfig, &srcPI.fColorType)) { 16587111d463cee893a479280c7af41757e709e33ef5reed@google.com return false; 16597111d463cee893a479280c7af41757e709e33ef5reed@google.com } 16607111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fAlphaType = kUnpremul_SkAlphaType; 16617111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fPixels = buffer; 16627111d463cee893a479280c7af41757e709e33ef5reed@google.com srcPI.fRowBytes = rowBytes; 16637111d463cee893a479280c7af41757e709e33ef5reed@google.com 1664231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org tmpPixels.reset(width * height); 16657111d463cee893a479280c7af41757e709e33ef5reed@google.com 16667111d463cee893a479280c7af41757e709e33ef5reed@google.com SkDstPixelInfo dstPI; 16677111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fColorType = srcPI.fColorType; 16687111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fAlphaType = kPremul_SkAlphaType; 16697111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fPixels = tmpPixels.get(); 16707111d463cee893a479280c7af41757e709e33ef5reed@google.com dstPI.fRowBytes = 4 * width; 16717111d463cee893a479280c7af41757e709e33ef5reed@google.com 16727111d463cee893a479280c7af41757e709e33ef5reed@google.com if (!srcPI.convertPixelsTo(&dstPI, width, height)) { 16737111d463cee893a479280c7af41757e709e33ef5reed@google.com return false; 16747111d463cee893a479280c7af41757e709e33ef5reed@google.com } 16757111d463cee893a479280c7af41757e709e33ef5reed@google.com 1676a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com buffer = tmpPixels.get(); 1677a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com rowBytes = 4 * width; 1678a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1679a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1680adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (NULL == effect) { 1681adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com effect.reset(GrConfigConversionEffect::Create(texture, 1682adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com swapRAndB, 1683adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com GrConfigConversionEffect::kNone_PMConversion, 1684adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com textureMatrix)); 1685a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1686a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 16879c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (!this->writeTexturePixels(texture, 16889c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com 0, 0, width, height, 16899c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com writeConfig, buffer, rowBytes, 16909c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com flags & ~kUnpremul_PixelOpsFlag)) { 16919c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 16929c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } 169327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 169413f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // writeRenderTargetPixels can be called in the midst of drawing another 16950c23faf222c24529781139495a5f4f4ab61f7cb2skia.committer@gmail.com // object (e.g., when uploading a SW path rendering to the gpu while 169613f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // drawing a rect) so preserve the current geometry. 1697137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com SkMatrix matrix; 1698137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); 1699137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit, &matrix); 17008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 1701f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(effect); 1702eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com drawState->addColorEffect(effect); 170327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 17048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 170527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1706fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org fGpu->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)), NULL); 17079c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return true; 170827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 170927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 171027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1711eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, 1712eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com BufferedDraw buffered, 17135dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoRestoreEffects* are, 17145dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush* acf) { 1715eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com // All users of this draw state should be freeing up all effects when they're done. 1716eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com // Otherwise effects that own resources may keep those resources alive indefinitely. 1717f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageStages()); 1718eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com 17191d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffered) { 17201267fbd95290f58443652ca8d947bde50b212618robertphillips@google.com fDrawBuffer->flush(); 17211d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com fLastDrawWasBuffered = kNo_BufferedDraw; 172227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1723bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org ASSERT_OWNED_RESOURCE(fRenderTarget.get()); 172407ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com if (NULL != paint) { 1725f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != are); 17265dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org SkASSERT(NULL != acf); 1727eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com are->set(fDrawState); 1728bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); 1729af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com#if GR_DEBUG_PARTIAL_COVERAGE_CHECK 1730af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com if ((paint->hasMask() || 0xff != paint->fCoverage) && 1731af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com !fGpu->canApplyCoverage()) { 1732af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 1733af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com } 1734af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com#endif 1735bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org } else { 1736137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com fDrawState->reset(fViewMatrix); 1737bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fDrawState->setRenderTarget(fRenderTarget.get()); 173807ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com } 1739bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org GrDrawTarget* target; 17401d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com if (kYes_BufferedDraw == buffered) { 17411d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com fLastDrawWasBuffered = kYes_BufferedDraw; 1742bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target = fDrawBuffer; 17431d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com } else { 1744f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(kNo_BufferedDraw == buffered); 1745bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fLastDrawWasBuffered = kNo_BufferedDraw; 1746bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target = fGpu; 174727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1748bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fDrawState->setState(GrDrawState::kClip_StateBit, NULL != fClip && 1749bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org !fClip->fClipStack->isWideOpen()); 1750bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target->setClip(fClip); 1751f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fDrawState == target->drawState()); 1752bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org return target; 175327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 175427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 175572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com/* 175672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * This method finds a path renderer that can draw the specified path on 175772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * the provided target. 1758fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Due to its expense, the software path renderer has split out so it can 175972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * can be individually allowed/disallowed via the "allowSW" boolean. 176072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com */ 17618d033a1b125886c62906d975b5cc28a382064526bsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const SkPath& path, 17625f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com const SkStrokeRec& stroke, 1763c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com const GrDrawTarget* target, 176445a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com bool allowSW, 176545a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com GrPathRendererChain::DrawType drawType, 176645a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com GrPathRendererChain::StencilSupport* stencilSupport) { 176745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 17683008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 176945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); 17703008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 177172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 177212b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, 177312b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com stroke, 177472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com target, 177545a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com drawType, 177645a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com stencilSupport); 177772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 177872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == pr && allowSW) { 177972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == fSoftwarePathRenderer) { 1780c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); 178172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 178272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com pr = fSoftwarePathRenderer; 178372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 178472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 178572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com return pr; 17863008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 17873008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 178827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 17896b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.orgbool GrContext::isConfigRenderable(GrPixelConfig config, bool withMSAA) const { 17906b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.org return fGpu->caps()->isConfigRenderable(config, withMSAA); 179199a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com} 179299a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com 1793b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.orgint GrContext::getRecommendedSampleCount(GrPixelConfig config, 1794b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org SkScalar dpi) const { 1795b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org if (!this->isConfigRenderable(config, true)) { 1796b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org return 0; 1797b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org } 1798b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org int chosenSampleCount = 0; 1799b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org if (fGpu->caps()->pathRenderingSupport()) { 1800b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org if (dpi >= 250.0f) { 1801b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org chosenSampleCount = 4; 1802b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org } else { 1803b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org chosenSampleCount = 16; 1804b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org } 1805b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org } 1806b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org return chosenSampleCount <= fGpu->caps()->maxSampleCount() ? 1807b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org chosenSampleCount : 0; 1808b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org} 1809b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org 18108fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() { 1811f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fDrawBuffer); 1812f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fDrawBufferVBAllocPool); 1813f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fDrawBufferIBAllocPool); 18148fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1815de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferVBAllocPool = 1816c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com SkNEW_ARGS(GrVertexBufferAllocPool, (fGpu, false, 181727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 1818c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)); 1819de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferIBAllocPool = 1820c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu, false, 1821de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 1822c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)); 182327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1824c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu, 18256e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBufferVBAllocPool, 18266e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBufferIBAllocPool)); 18273c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com 18286e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBuffer->setDrawState(fDrawState); 182927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 183027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 183121c10c5ff50cb8f2fd995fc9396d435d3396258bbsalomon@google.comGrDrawTarget* GrContext::getTextTarget() { 18325dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org return this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL); 183327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 183427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 183527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 183627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getQuadIndexBuffer(); 183727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 1838dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 1839a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comnamespace { 1840a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comvoid test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { 1841a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion pmToUPM; 1842a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion upmToPM; 1843a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM); 1844a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMValue = pmToUPM; 1845a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMValue = upmToPM; 1846a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1847a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1848a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1849adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.comconst GrEffectRef* GrContext::createPMToUPMEffect(GrTexture* texture, 1850adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com bool swapRAndB, 1851adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com const SkMatrix& matrix) { 1852a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fDidTestPMConversions) { 1853a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 1854d0f3f6825bd5c232da52f4dc1af69b76403b797fbsalomon@google.com fDidTestPMConversions = true; 1855a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1856a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion pmToUPM = 1857a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); 1858a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { 1859adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix); 1860a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 1861adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return NULL; 1862a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1863a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1864a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1865adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.comconst GrEffectRef* GrContext::createUPMToPMEffect(GrTexture* texture, 1866adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com bool swapRAndB, 1867adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com const SkMatrix& matrix) { 1868a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fDidTestPMConversions) { 1869a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 1870d0f3f6825bd5c232da52f4dc1af69b76403b797fbsalomon@google.com fDidTestPMConversions = true; 1871a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1872a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion upmToPM = 1873a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); 1874a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { 1875adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix); 1876a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 1877adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return NULL; 1878a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1879a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1880a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 18815c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.orgGrPath* GrContext::createPath(const SkPath& inPath, const SkStrokeRec& stroke) { 18825c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org SkASSERT(fGpu->caps()->pathRenderingSupport()); 18835c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org 188495c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org // TODO: now we add to fResourceCache. This should change to fResourceCache. 18855c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org GrResourceKey resourceKey = GrPath::ComputeKey(inPath, stroke); 188695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org GrPath* path = static_cast<GrPath*>(fResourceCache->find(resourceKey)); 18875c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org if (NULL != path && path->isEqualTo(inPath, stroke)) { 18885c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org path->ref(); 18895c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org } else { 18905c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org path = fGpu->createPath(inPath, stroke); 189195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->purgeAsNeeded(1, path->gpuMemorySize()); 189295c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->addResource(resourceKey, path); 18935c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org } 18945c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org return path; 18955c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org} 18965c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org 189795a2b0e86d361c06716874f8a56782e1551c308ecommit-bot@chromium.orgvoid GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrCacheable* resource) { 189895c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->purgeAsNeeded(1, resource->gpuMemorySize()); 189995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->addResource(resourceKey, resource); 190095a2b0e86d361c06716874f8a56782e1551c308ecommit-bot@chromium.org} 190195a2b0e86d361c06716874f8a56782e1551c308ecommit-bot@chromium.org 190295a2b0e86d361c06716874f8a56782e1551c308ecommit-bot@chromium.orgGrCacheable* GrContext::findAndRefCachedResource(const GrResourceKey& resourceKey) { 190395c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org GrCacheable* resource = fResourceCache->find(resourceKey); 190495a2b0e86d361c06716874f8a56782e1551c308ecommit-bot@chromium.org SkSafeRef(resource); 190595a2b0e86d361c06716874f8a56782e1551c308ecommit-bot@chromium.org return resource; 190695a2b0e86d361c06716874f8a56782e1551c308ecommit-bot@chromium.org} 190795a2b0e86d361c06716874f8a56782e1551c308ecommit-bot@chromium.org 1908bbcb38df4f7477aa0a38da00a0757586a0125954egdanielvoid GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { 1909bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel fGpu->addGpuTraceMarker(marker); 1910bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel if (NULL != fDrawBuffer) { 1911bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel fDrawBuffer->addGpuTraceMarker(marker); 1912bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel } 1913bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel} 1914bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel 1915bbcb38df4f7477aa0a38da00a0757586a0125954egdanielvoid GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { 1916bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel fGpu->removeGpuTraceMarker(marker); 1917bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel if (NULL != fDrawBuffer) { 1918bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel fDrawBuffer->removeGpuTraceMarker(marker); 1919bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel } 1920bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel} 1921bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel 1922c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 19235955202c805c7ef1448103cbf666972ea9d1ded1robertphillips@google.com#if GR_CACHE_STATS 19245f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.comvoid GrContext::printCacheStats() const { 192595c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org fResourceCache->printStats(); 19265f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.com} 19275f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.com#endif 1928