GrContext.cpp revision e79f320ed6c5ec9f6164ba84be1ff586532e6517
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 12aa72eab5d82d4c2aa9f6f41755a001282443b042tomhudson@google.com#include "effects/GrSingleTextureEffect.h" 13a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com#include "effects/GrConfigConversionEffect.h" 14b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com 15bfe2b9d3a290d0153b82617cd6b65a4814fe89e3jvanverth@google.com#include "GrAARectRenderer.h" 16278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrBufferAllocPool.h" 1705ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com#include "GrGpu.h" 18c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com#include "GrDrawTargetCaps.h" 1927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrIndexBuffer.h" 2027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrInOrderDrawBuffer.h" 2181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrOvalRenderer.h" 2227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h" 23d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h" 2450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#include "GrResourceCache.h" 2572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com#include "GrSoftwarePathRenderer.h" 26558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com#include "GrStencilBuffer.h" 27278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrTextStrike.h" 2882b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com#include "SkRTConf.h" 2919dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org#include "SkRRect.h" 305f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkStrokeRec.h" 318c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com#include "SkTLazy.h" 32c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com#include "SkTLS.h" 330c8d93a94099dee2dff8da6000ded9ad59676488tomhudson@google.com#include "SkTrace.h" 3427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3582b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com// It can be useful to set this to false to test whether a bug is caused by using the 361d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com// InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffer, or to make 3782b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com// debugging simpler. 38e932c98069fd6831a03ff63d331271ef0e9703d9bsalomon@google.comSK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true, 3965eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com "Defers rendering in GrContext via GrInOrderDrawBuffer."); 4082b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com 4182b0ec6ea408d866e02805fbe0519d00d2e87627bsalomon@google.com#define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw) 4227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 43515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 444b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com // change this to a 1 to see notifications when partial coverage fails 454b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 464b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#else 474b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 484b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#endif 494b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com 504e5559af8947ae7dc3df531b6d7a73323db20c3frobertphillips@google.comstatic const size_t MAX_RESOURCE_CACHE_COUNT = GR_DEFAULT_RESOURCE_CACHE_COUNT_LIMIT; 514e5559af8947ae7dc3df531b6d7a73323db20c3frobertphillips@google.comstatic const size_t MAX_RESOURCE_CACHE_BYTES = GR_DEFAULT_RESOURCE_CACHE_MB_LIMIT * 1024 * 1024; 5227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5360361493548d5259d0a8afae84274c2a3c31dcacbsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; 5427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 5527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 561d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; 571d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; 5827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 59f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) 60bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 61eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com// Glorified typedef to avoid including GrDrawState.h in GrContext.h 62eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.comclass GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {}; 63eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com 645dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.orgclass GrContext::AutoCheckFlush { 655dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.orgpublic: 665dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(NULL != context); } 675dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org 685dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org ~AutoCheckFlush() { 695dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org if (fContext->fFlushToReduceCacheSize) { 705dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org fContext->flush(); 715dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org } 725dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org } 735dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org 745dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.orgprivate: 755dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrContext* fContext; 765dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org}; 775dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org 786e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.comGrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) { 796e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com GrContext* context = SkNEW(GrContext); 806e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com if (context->init(backend, backendContext)) { 816e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return context; 826e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com } else { 836e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com context->unref(); 846e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return NULL; 8527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 8627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 8727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 886e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.comGrContext::GrContext() { 896e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawState = NULL; 906e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fGpu = NULL; 91bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fClip = NULL; 926e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fPathRendererChain = NULL; 936e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fSoftwarePathRenderer = NULL; 946e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fTextureCache = NULL; 956e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fFontCache = NULL; 966e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBuffer = NULL; 976e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBufferVBAllocPool = NULL; 986e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBufferIBAllocPool = NULL; 995dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org fFlushToReduceCacheSize = false; 1006e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fAARectRenderer = NULL; 10181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org fOvalRenderer = NULL; 102bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fViewMatrix.reset(); 10344a91dcf2542c2aa93f159ebbb5bf813ae7362c0robertphillips@google.com fMaxTextureSizeOverride = 1 << 20; 1046e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com} 1056e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1066e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.combool GrContext::init(GrBackend backend, GrBackendContext backendContext) { 107f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fGpu); 1086e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1096e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fGpu = GrGpu::Create(backend, backendContext, this); 1106e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com if (NULL == fGpu) { 1116e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return false; 1126e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com } 1136e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1146e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawState = SkNEW(GrDrawState); 1156e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fGpu->setDrawState(fDrawState); 1166e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1176e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fTextureCache = SkNEW_ARGS(GrResourceCache, 1184e5559af8947ae7dc3df531b6d7a73323db20c3frobertphillips@google.com (MAX_RESOURCE_CACHE_COUNT, 1194e5559af8947ae7dc3df531b6d7a73323db20c3frobertphillips@google.com MAX_RESOURCE_CACHE_BYTES)); 1201836d337a85b82689287231091823f404d8cab43commit-bot@chromium.org fTextureCache->setOverbudgetCallback(OverbudgetCB, this); 1211836d337a85b82689287231091823f404d8cab43commit-bot@chromium.org 1226e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); 1236e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1246e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fLastDrawWasBuffered = kNo_BufferedDraw; 1256e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1266e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fAARectRenderer = SkNEW(GrAARectRenderer); 12781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org fOvalRenderer = SkNEW(GrOvalRenderer); 1286e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1296e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDidTestPMConversions = false; 1306e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1316e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com this->setupDrawBuffer(); 1326e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 1336e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com return true; 134c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 135c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 13627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() { 137733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com if (NULL == fGpu) { 138733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com return; 139733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com } 140733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com 1418fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 1425acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 143950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com for (int i = 0; i < fCleanUpData.count(); ++i) { 144950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); 145950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com } 146950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com 1475acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // Since the gpu can hold scratch textures, give it a chance to let go 1485acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // of them before freeing the texture cache 1495acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com fGpu->purgeResources(); 1505acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 15127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fTextureCache; 152eb9b3e164e55b8d15e1c25bfb1332917453cbc3arobertphillips@google.com fTextureCache = NULL; 15327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fFontCache; 15427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBuffer; 15527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBufferVBAllocPool; 156de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com delete fDrawBufferIBAllocPool; 1573008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 158f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->unref(); 15981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org fOvalRenderer->unref(); 160f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 161205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->unref(); 162a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeUnref(fPathRendererChain); 163a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeUnref(fSoftwarePathRenderer); 16410e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->unref(); 16527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 16627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1678fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::contextLost() { 1686e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com this->contextDestroyed(); 16953a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com this->setupDrawBuffer(); 17053a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com} 17153a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com 17253a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.comvoid GrContext::contextDestroyed() { 173205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // abandon first to so destructors 174205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // don't try to free the resources in the API. 175205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->abandonResources(); 176205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1773008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources that 1783008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // are now unusable 179a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fPathRendererChain); 180a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fSoftwarePathRenderer); 1813008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1828fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBuffer; 1838fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 184205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1858fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferVBAllocPool; 1868fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 187205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1888fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferIBAllocPool; 1898fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 1908fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 191f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->reset(); 192ef284a84f503adfd08ee52b5aee142c548698ea4commit-bot@chromium.org fOvalRenderer->reset(); 193205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 194a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com fTextureCache->purgeAllUnlocked(); 1955c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org 1968fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 1978fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1988fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1998fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2000a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.comvoid GrContext::resetContext(uint32_t state) { 2010a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com fGpu->markContextDirty(state); 2028fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 2038fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2048fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() { 2058fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 206fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 207ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com fGpu->purgeResources(); 208ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com 209f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->reset(); 210ef284a84f503adfd08ee52b5aee142c548698ea4commit-bot@chromium.org fOvalRenderer->reset(); 211f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 212a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com fTextureCache->purgeAllUnlocked(); 2138fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 2143008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources 215a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fPathRendererChain); 216a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org SkSafeSetNull(fSoftwarePathRenderer); 21727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 21827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 21905e70247c31ae927074ef27ea9893634a8dda543twiz@google.comsize_t GrContext::getGpuTextureCacheBytes() const { 22005e70247c31ae927074ef27ea9893634a8dda543twiz@google.com return fTextureCache->getCachedResourceBytes(); 22105e70247c31ae927074ef27ea9893634a8dda543twiz@google.com} 22205e70247c31ae927074ef27ea9893634a8dda543twiz@google.com 223fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 224fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 22595ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.comGrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc, 22695ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrCacheID& cacheID, 22795ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrTextureParams* params) { 2280797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 2299fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com GrResource* resource = fTextureCache->find(resourceKey); 23095ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com SkSafeRef(resource); 2311f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return static_cast<GrTexture*>(resource); 232558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 233558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 23475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.combool GrContext::isTextureInCache(const GrTextureDesc& desc, 2350797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const GrCacheID& cacheID, 236b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com const GrTextureParams* params) const { 2370797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 238fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com return fTextureCache->hasKey(resourceKey); 239fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com} 240fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com 2419fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.comvoid GrContext::addStencilBuffer(GrStencilBuffer* sb) { 242bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sb); 24346a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com 24446a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(sb->width(), 24546a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com sb->height(), 24646a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com sb->numSamples()); 247209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com fTextureCache->addResource(resourceKey, sb); 248558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 249558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 2509fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 251558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt) { 25246a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width, 25346a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com height, 25446a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com sampleCnt); 2559fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com GrResource* resource = fTextureCache->find(resourceKey); 2561f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return static_cast<GrStencilBuffer*>(resource); 257558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 258558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 25927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic void stretchImage(void* dst, 26027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstW, 26127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstH, 26227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* src, 26327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcW, 26427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcH, 2658b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t bpp) { 26627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dx = (srcW << 16) / dstW; 26727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dy = (srcH << 16) / dstH; 26827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 26927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed y = dy >> 1; 27027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2718b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t dstXLimit = dstW*bpp; 27227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int j = 0; j < dstH; ++j) { 27327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed x = dx >> 1; 27427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 27527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* dstRow = (uint8_t*)dst + j*dstW*bpp; 2768b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com for (size_t i = 0; i < dstXLimit; i += bpp) { 27727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com memcpy((uint8_t*) dstRow + i, 27827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com (uint8_t*) srcRow + (x>>16)*bpp, 27927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bpp); 28027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com x += dx; 28127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 28227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com y += dy; 28327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 28427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 28527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 286429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comnamespace { 287429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 288429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com// position + local coordinate 289429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gVertexAttribs[] = { 290429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 291429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding} 292429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 293429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 294429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 295429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 296fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com// The desired texture is NPOT and tiled but that isn't supported by 2973319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com// the current hardware. Resize the texture to be a POT 2983319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.comGrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, 2990797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const GrCacheID& cacheID, 3003319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com void* srcData, 3013319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com size_t rowBytes, 302b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com bool filter) { 30395ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, cacheID, NULL)); 3041f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com if (NULL == clampedTexture) { 30595ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com clampedTexture.reset(this->createTexture(NULL, desc, cacheID, srcData, rowBytes)); 3069fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com 3071f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com if (NULL == clampedTexture) { 3083319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com return NULL; 3093319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3103319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3110d25eefd7a25afe859cb2d4cf733a3cf07f12139robertphillips@google.com 3123319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrTextureDesc rtDesc = desc; 3133319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com rtDesc.fFlags = rtDesc.fFlags | 3143319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com kRenderTarget_GrTextureFlagBit | 3153319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com kNoStencil_GrTextureFlagBit; 3165898dce287b0d1ec535a9cfc1c5870a9cdcf5d1bcommit-bot@chromium.org rtDesc.fWidth = GrNextPow2(desc.fWidth); 3175898dce287b0d1ec535a9cfc1c5870a9cdcf5d1bcommit-bot@chromium.org rtDesc.fHeight = GrNextPow2(desc.fHeight); 3183319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3193319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 3203319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3213319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com if (NULL != texture) { 3223319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 3233319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrDrawState* drawState = fGpu->drawState(); 3243319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com drawState->setRenderTarget(texture->asRenderTarget()); 3253319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3263319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // if filtering is not desired then we want to ensure all 3273319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // texels in the resampled image are copies of texels from 3283319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // the original. 329b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTextureParams::kBilerp_FilterMode : 330b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com GrTextureParams::kNone_FilterMode); 331eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params); 3323319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 333429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs)); 334054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com 335b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0); 3363319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3373319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com if (arg.succeeded()) { 3383319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com GrPoint* verts = (GrPoint*) arg.vertices(); 33995ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(GrPoint)); 34095ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(GrPoint)); 34195ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 3423319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3433319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } else { 3443319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // TODO: Our CPU stretch doesn't filter. But we create separate 34508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com // stretched textures when the texture params is either filtered or 3463319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // not. Either implement filtered stretch blit on CPU or just create 3473319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // one when FBO case fails. 3483319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3493319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com rtDesc.fFlags = kNone_GrTextureFlags; 3503319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com // no longer need to clamp at min RT size. 3513319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com rtDesc.fWidth = GrNextPow2(desc.fWidth); 3523319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com rtDesc.fHeight = GrNextPow2(desc.fHeight); 3538b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t bpp = GrBytesPerPixel(desc.fConfig); 35408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com SkAutoSMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHeight); 3553319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 35608283afc265f1153834256fc1012519813ba6b73bsalomon@google.com srcData, desc.fWidth, desc.fHeight, bpp); 3573319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3583319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com size_t stretchedRowBytes = rtDesc.fWidth * bpp; 3593319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 36065eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com SkDEBUGCODE(GrTexture* texture = )fGpu->createTexture(rtDesc, stretchedPixels.get(), 36165eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com stretchedRowBytes); 362f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != texture); 3633319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3643319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3653319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com return texture; 3663319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com} 3673319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 36895ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.comGrTexture* GrContext::createTexture(const GrTextureParams* params, 36995ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrTextureDesc& desc, 37095ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com const GrCacheID& cacheID, 37195ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com void* srcData, 37250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org size_t rowBytes, 37350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org GrResourceKey* cacheKey) { 3740797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com SK_TRACE_EVENT0("GrContext::createTexture"); 37527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3760797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 377a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com 37895ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com GrTexture* texture; 379a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com if (GrTexture::NeedsResizing(resourceKey)) { 38095ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com texture = this->createResizedTexture(desc, cacheID, 38195ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com srcData, rowBytes, 382b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com GrTexture::NeedsBilerp(resourceKey)); 38327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 38495ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com texture= fGpu->createTexture(desc, srcData, rowBytes); 3853319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com } 3863319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3873319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com if (NULL != texture) { 3881622a6d950a4a1deb13048210bdb78d952375f05robertphillips@google.com // Adding a resource could put us overbudget. Try to free up the 3891622a6d950a4a1deb13048210bdb78d952375f05robertphillips@google.com // necessary space before adding it. 3901622a6d950a4a1deb13048210bdb78d952375f05robertphillips@google.com fTextureCache->purgeAsNeeded(1, texture->sizeInBytes()); 391209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com fTextureCache->addResource(resourceKey, texture); 39250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 39350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org if (NULL != cacheKey) { 39450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org *cacheKey = resourceKey; 39550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org } 39627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 3973319f33470abc50a6f3da3a565d917050f9b2f53robertphillips@google.com 3981f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return texture; 39927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 40027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 4011f3c73825b8a1752abc6b74fbce978a430de6473skia.committer@gmail.comstatic GrTexture* create_scratch_texture(GrGpu* gpu, 4021f3c73825b8a1752abc6b74fbce978a430de6473skia.committer@gmail.com GrResourceCache* textureCache, 403e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com const GrTextureDesc& desc) { 404e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com GrTexture* texture = gpu->createTexture(desc, NULL, 0); 405e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com if (NULL != texture) { 406e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com GrResourceKey key = GrTexture::ComputeScratchKey(texture->desc()); 407e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // Adding a resource could put us overbudget. Try to free up the 408e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // necessary space before adding it. 409e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com textureCache->purgeAsNeeded(1, texture->sizeInBytes()); 410e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // Make the resource exclusive so future 'find' calls don't return it 411e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com textureCache->addResource(key, texture, GrResourceCache::kHide_OwnershipFlag); 412e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com } 413e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com return texture; 414e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com} 415e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 41695ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.comGrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match) { 41775b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com 418f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT((inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || 419e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com !(inDesc.fFlags & kNoStencil_GrTextureFlagBit)); 420e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 421e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // Renderable A8 targets are not universally supported (e.g., not on ANGLE) 4228aaac8da36bb88ab13c62e84ee6ac9ebc5cb8466bsalomon@google.com SkASSERT(this->isConfigRenderable(kAlpha_8_GrPixelConfig, inDesc.fSampleCnt > 0) || 423e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || 424e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com (inDesc.fConfig != kAlpha_8_GrPixelConfig)); 425e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 4262d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com if (!fGpu->caps()->reuseScratchTextures() && 4272d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit)) { 4282d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com // If we're never recycling this texture we can always make it the right size 429e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com return create_scratch_texture(fGpu, fTextureCache, inDesc); 430e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com } 431e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 432e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com GrTextureDesc desc = inDesc; 4332afb8ec738fc50ea6e4500545c3cacbf346ed187rileya@google.com 4340797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com if (kApprox_ScratchTexMatch == match) { 43550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // bin by pow2 with a reasonable min 43640db6dc98d13e4632cdeaab1577a5e09fd2ad18fbsalomon@google.com static const int MIN_SIZE = 16; 43750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 43850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 43950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 440b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 4411f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com GrResource* resource = NULL; 442b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origWidth = desc.fWidth; 443b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origHeight = desc.fHeight; 444b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 445b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com do { 4460797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrResourceKey key = GrTexture::ComputeScratchKey(desc); 447209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com // Ensure we have exclusive access to the texture so future 'find' calls don't return it 448209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag); 44995ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com if (NULL != resource) { 45095ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com resource->ref(); 45195ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com break; 45295ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com } 45395ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com if (kExact_ScratchTexMatch == match) { 454b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 455b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 45640db6dc98d13e4632cdeaab1577a5e09fd2ad18fbsalomon@google.com // We had a cache miss and we are in approx mode, relax the fit of the flags. 45795ed55adc6b8f0cee063c2cf2e14782773b0087fbsalomon@google.com 458fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // We no longer try to reuse textures that were previously used as render targets in 4592afb8ec738fc50ea6e4500545c3cacbf346ed187rileya@google.com // situations where no RT is needed; doing otherwise can confuse the video driver and 4602afb8ec738fc50ea6e4500545c3cacbf346ed187rileya@google.com // cause significant performance problems in some cases. 4612afb8ec738fc50ea6e4500545c3cacbf346ed187rileya@google.com if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 462b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 463b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else { 464b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 465b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 466fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 467b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } while (true); 468b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 4691f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com if (NULL == resource) { 470b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 471b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 472b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight = origHeight; 473e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com resource = create_scratch_texture(fGpu, fTextureCache, desc); 474b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 475b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 4761f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com return static_cast<GrTexture*>(resource); 477b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com} 478b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 47915c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.comvoid GrContext::addExistingTextureToCache(GrTexture* texture) { 48015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 48115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com if (NULL == texture) { 48215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com return; 48315c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com } 48415c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 485521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com // This texture should already have a cache entry since it was once 486521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com // attached 487f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != texture->getCacheEntry()); 488521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com 489521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com // Conceptually, the cache entry is going to assume responsibility 4909ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // for the creation ref. Assert refcnt == 1. 491f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(texture->unique()); 492521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com 4932d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) { 4949ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // Since this texture came from an AutoScratchTexture it should 4959ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // still be in the exclusive pile. Recycle it. 4969ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com fTextureCache->makeNonExclusive(texture->getCacheEntry()); 497e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com this->purgeCache(); 4989ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } else if (texture->getDeferredRefCount() <= 0) { 499e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // When we aren't reusing textures we know this scratch texture 500e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com // will never be reused and would be just wasting time in the cache 5019ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com fTextureCache->makeNonExclusive(texture->getCacheEntry()); 502e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com fTextureCache->deleteResource(texture->getCacheEntry()); 5039ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } else { 5049ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // In this case (fDeferredRefCount > 0) but the cache is the only 5059ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // one holding a real ref. Mark the object so when the deferred 5069ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // ref count goes to 0 the texture will be deleted (remember 5079ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // in this code path scratch textures aren't getting reused). 5089ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com texture->setNeedsDeferredUnref(); 509e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com } 51015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com} 51115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 512a9b0623eac4a473517c15418dbdc1e331ee752d2robertphillips@google.com 5139fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.comvoid GrContext::unlockScratchTexture(GrTexture* texture) { 5141f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com ASSERT_OWNED_RESOURCE(texture); 515f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != texture->getCacheEntry()); 5161f47f4f7325971dd53991e2bb02da94fa7c6d962robertphillips@google.com 51750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // If this is a scratch texture we detached it from the cache 51850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // while it was locked (to avoid two callers simultaneously getting 51950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // the same texture). 5200797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com if (texture->getCacheEntry()->key().isScratch()) { 5212d2e5c4e2425a1cb64d31d7d10832f4a3a9137a4robertphillips@google.com if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) { 5229ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com fTextureCache->makeNonExclusive(texture->getCacheEntry()); 5239ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com this->purgeCache(); 5249ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } else if (texture->unique() && texture->getDeferredRefCount() <= 0) { 525b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com // Only the cache now knows about this texture. Since we're never 526b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com // reusing scratch textures (in this code path) it would just be 5279ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // wasting time sitting in the cache. 5289ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com fTextureCache->makeNonExclusive(texture->getCacheEntry()); 5299ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com fTextureCache->deleteResource(texture->getCacheEntry()); 5309ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } else { 5319ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // In this case (fRefCnt > 1 || defRefCnt > 0) but we don't really 532b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com // want to readd it to the cache (since it will never be reused). 5339ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // Instead, give up the cache's ref and leave the decision up to 5349ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // addExistingTextureToCache once its ref count reaches 0. For 5359ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // this to work we need to leave it in the exclusive list. 5369ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit); 5379ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com // Give up the cache's ref to the texture 5389ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com texture->unref(); 5399ef0426e7c126f6ad6ba833d4543b92a197c95afrobertphillips@google.com } 540fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 54150a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.com} 54250a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.com 54350a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.comvoid GrContext::purgeCache() { 544eb9b3e164e55b8d15e1c25bfb1332917453cbc3arobertphillips@google.com if (NULL != fTextureCache) { 545eb9b3e164e55b8d15e1c25bfb1332917453cbc3arobertphillips@google.com fTextureCache->purgeAsNeeded(); 546eb9b3e164e55b8d15e1c25bfb1332917453cbc3arobertphillips@google.com } 54715c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com} 54815c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 549cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.orgbool GrContext::OverbudgetCB(void* data) { 550f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != data); 551cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 552cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org GrContext* context = reinterpret_cast<GrContext*>(data); 553cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 554cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org // Flush the InOrderDrawBuffer to possibly free up some textures 5555dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org context->fFlushToReduceCacheSize = true; 556cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 557cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org return true; 558cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org} 559cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 560cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 56175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn, 56227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcData, 56327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t rowBytes) { 56475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc descCopy = descIn; 56575b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com return fGpu->createTexture(descCopy, srcData, rowBytes); 56627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 56727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 56807fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.comvoid GrContext::getTextureCacheLimits(int* maxTextures, 56907fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com size_t* maxTextureBytes) const { 57007fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com fTextureCache->getLimits(maxTextures, maxTextureBytes); 57127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 57227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 57307fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.comvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 57407fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com fTextureCache->setLimits(maxTextures, maxTextureBytes); 57527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 57627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 577919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const { 57844a91dcf2542c2aa93f159ebbb5bf813ae7362c0robertphillips@google.com return GrMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); 579919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 580919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 581919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 582bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com return fGpu->caps()->maxRenderTargetSize(); 58327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 58427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5858a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.comint GrContext::getMaxSampleCount() const { 586bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com return fGpu->caps()->maxSampleCount(); 5878a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com} 5888a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com 58927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 59027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 59116e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.comGrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) { 59216e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com return fGpu->wrapBackendTexture(desc); 593e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 594e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 59516e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.comGrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { 59616e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com return fGpu->wrapBackendRenderTarget(desc); 597e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 598e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 5995877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 6005877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com 601b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, 6021f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com int width, int height) const { 603c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com const GrDrawTargetCaps* caps = fGpu->caps(); 604bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com if (!caps->eightBitPaletteSupport()) { 60527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 60627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 60727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 60827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 60927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 61027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!isPow2) { 611b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com bool tiled = NULL != params && params->isTiled(); 612bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com if (tiled && !caps->npotTextureTileSupport()) { 61327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 61427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 61527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 61627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return true; 61727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 61827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 61927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 62027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 62127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 622fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgvoid GrContext::clear(const SkIRect* rect, 62307ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com const GrColor color, 62456ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com bool canIgnoreRect, 625c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com GrRenderTarget* target) { 626eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 6275dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 62818bb41e9563748fbde07c1540da9314cbb7d1dc8skia.committer@gmail.com this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->clear(rect, color, 62956ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com canIgnoreRect, target); 63027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 63127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 6325dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.comvoid GrContext::drawPaint(const GrPaint& origPaint) { 63327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 63427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // don't overflow fixed-point implementations 635fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect r; 636d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com r.setLTRB(0, 0, 63781712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkIntToScalar(getRenderTarget()->width()), 63881712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkIntToScalar(getRenderTarget()->height())); 639b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix inverse; 6405dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkTCopyOnFirstWrite<GrPaint> paint(origPaint); 641fea85ac3e31842f80493e2df8a93a28f21cd815frobertphillips@google.com AutoMatrix am; 6428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6434f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 6444f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // map the four corners and bound them with a new rect. This will not 6454f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // produce a correct result for some perspective matrices. 6468c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!this->getMatrix().hasPerspective()) { 647bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org if (!fViewMatrix.invert(&inverse)) { 648e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrPrintf("Could not invert matrix\n"); 6498c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6508c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 65127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com inverse.mapRect(&r); 65227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 6533cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com if (!am.setIdentity(this, paint.writable())) { 6543cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com GrPrintf("Could not invert matrix\n"); 6553cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com return; 6568c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 65727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 6584f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // by definition this fills the entire clip, no need for AA 6595dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com if (paint->isAntiAlias()) { 6605dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com paint.writable()->setAntiAlias(false); 6614f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com } 6625dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com this->drawRect(*paint, r); 66327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 66427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 66503e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#ifdef SK_DEVELOPER 66603e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.orgvoid GrContext::dumpFontCache() const { 66703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org fFontCache->dump(); 66803e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org} 66903e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#endif 67003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org 671205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 672205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 67327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 67427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 67527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 67627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster. 67727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 678fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgstatic void setStrokeRectStrip(GrPoint verts[10], SkRect rect, 67981712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar width) { 68081712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com const SkScalar rad = SkScalarHalf(width); 681205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com rect.sort(); 68227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 68327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 68427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 68527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 68627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 68727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 68827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 68927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 69027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 69127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[8] = verts[0]; 69227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[9] = verts[1]; 69327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 69427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 695fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgstatic bool isIRect(const SkRect& r) { 696eafdf126d44abadf01e7d2910739e228f557df51skia.committer@gmail.com return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && 697eafdf126d44abadf01e7d2910739e228f557df51skia.committer@gmail.com SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); 698afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com} 699afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com 700205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 701fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& rect, 702df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com SkScalar strokeWidth, 70324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org const SkMatrix& combinedMatrix, 70424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect* devBoundRect, 705a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool* useVertexCoverage) { 7062eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we use a simple coverage ramp to do aa on axis-aligned rects 707fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // we check if the rect will be axis-aligned, and the rect won't land on 7082eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // integer coords. 709d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 710a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // we are keeping around the "tweak the alpha" trick because 711a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // it is our only hope for the fixed-pipe implementation. 712a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // In a shader implementation we can give a separate coverage input 713289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 714a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = false; 7152b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com if (!target->getDrawState().canTweakAlphaForCoverage()) { 716e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (target->shouldDisableCoverageAAForBlend()) { 717515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 7182eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 7191983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 720a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 7212eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com } else { 7222eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com *useVertexCoverage = true; 723a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 724205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 7268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 727205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 728205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 729205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 730df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com if (0 == strokeWidth && target->willUseHWAALines()) { 731205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 732205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 733205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7344b140b5fbedcb75d0b9587fa9d232ce54d9c7eb5robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 735df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com if (strokeWidth >= 0) { 736df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com#endif 73724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!combinedMatrix.preservesAxisAlignment()) { 738df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com return false; 739df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } 740205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7414b140b5fbedcb75d0b9587fa9d232ce54d9c7eb5robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 742df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } else { 74324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!combinedMatrix.preservesRightAngles()) { 744df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com return false; 745df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com } 746205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 747df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com#endif 748205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 74924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org combinedMatrix.mapRect(devBoundRect, rect); 75028ac96e40d705f7fb08a61ac027e15de8d91823crobertphillips@google.com 751afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com if (strokeWidth < 0) { 75224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return !isIRect(*devBoundRect); 753afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com } else { 754afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com return true; 755afd1cba5237eba5394ee011106eede9f6c8074c8robertphillips@google.com } 756205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 757205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 75824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.orgstatic inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) { 75924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return point.fX >= rect.fLeft && point.fX <= rect.fRight && 76024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org point.fY >= rect.fTop && point.fY <= rect.fBottom; 76124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org} 76224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 76327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 764fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& rect, 7656006d0f8c4f19d19a12de20826f731f52ac822a7commit-bot@chromium.org const SkStrokeRec* stroke, 766b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix* matrix) { 767278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRect"); 76827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 769eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 7705dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 7715dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 77227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 7736006d0f8c4f19d19a12de20826f731f52ac822a7commit-bot@chromium.org SkScalar width = stroke == NULL ? -1 : stroke->getWidth(); 77424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkMatrix combinedMatrix = target->drawState()->getViewMatrix(); 77524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (NULL != matrix) { 77624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org combinedMatrix.preConcat(*matrix); 77724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 77824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 77924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking 78024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // cases where the RT is fully inside a stroke. 78124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (width < 0) { 78224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect rtRect; 78324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect); 78424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect clipSpaceRTRect = rtRect; 78524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org bool checkClip = false; 78624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (NULL != this->getClip()) { 78724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org checkClip = true; 78824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), 78924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkIntToScalar(this->getClip()->fOrigin.fY)); 79024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 79124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Does the clip contain the entire RT? 79224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpaceRTRect)) { 79324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkMatrix invM; 79424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (!combinedMatrix.invert(&invM)) { 79524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return; 79624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 79724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Does the rect bound the RT? 79824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkPoint srcSpaceRTQuad[4]; 79924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org invM.mapRectToQuad(srcSpaceRTQuad, rtRect); 80024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) && 80124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[1]) && 80224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[2]) && 80324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[3])) { 80424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org // Will it blend? 80524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org GrColor clearColor; 80624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org if (paint.isOpaqueAndConstantColor(&clearColor)) { 80756ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com target->clear(NULL, clearColor, true); 80824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org return; 80924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 81024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 81124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 81224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org } 81324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org 81424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org SkRect devBoundRect; 815a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage; 816c7448cef098b835d6f9adf8a365fde9de076f178bsalomon@google.com bool needAA = paint.isAntiAlias() && 817bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org !target->getDrawState().getRenderTarget()->isMultisampled(); 81824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org bool doAA = needAA && apply_aa_to_rect(target, rect, width, combinedMatrix, &devBoundRect, 819289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &useVertexCoverage); 820205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 821137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 822137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 823e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 824e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 825205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 8266006d0f8c4f19d19a12de20826f731f52ac822a7commit-bot@chromium.org fAARectRenderer->strokeAARect(this->getGpu(), target, rect, 8276006d0f8c4f19d19a12de20826f731f52ac822a7commit-bot@chromium.org combinedMatrix, devBoundRect, 8286006d0f8c4f19d19a12de20826f731f52ac822a7commit-bot@chromium.org stroke, useVertexCoverage); 829205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 830df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com // filled AA rect 831fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com fAARectRenderer->fillAARect(this->getGpu(), target, 83224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org rect, combinedMatrix, devBoundRect, 833b19cb7f36785f3ad3b1512c342fc662ab79e3fcarobertphillips@google.com useVertexCoverage); 834205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 835205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 836205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 837205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 83827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 83927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: consider making static vertex buffers for these cases. 8406438695222333981fafee9c8c09f3bf51dce3816bsalomon@google.com // Hairline could be done by just adding closing vertex to 8416438695222333981fafee9c8c09f3bf51dce3816bsalomon@google.com // unitSquareVertexBuffer() 84226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 84327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int worstCaseVertCount = 10; 8449b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com target->drawState()->setDefaultVertexAttribs(); 845b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0); 84627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 84727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 8486513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 84927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 85027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 85127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 85227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primType; 85327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertCount; 85427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* vertex = geo.positions(); 85527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 85627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width > 0) { 85727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 10; 85847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com primType = kTriangleStrip_GrPrimitiveType; 85927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com setStrokeRectStrip(vertex, rect, width); 86027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 86127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // hairline 86227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 5; 86347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com primType = kLineStrip_GrPrimitiveType; 86427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 86527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 86627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 86727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 86827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 86927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 87027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 8718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 87227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 8738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8742fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com avmr.set(drawState, *matrix); 87527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 87627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 87727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 87827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 879df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com // filled BW rect 880235ef3d0e253200af43bb69139df09744f5ddbefrobertphillips@google.com target->drawSimpleRect(rect, matrix); 88127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 88227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 88327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 88427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 885fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& dstRect, 886fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& localRect, 887b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix* dstMatrix, 888c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const SkMatrix* localMatrix) { 889278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRectToRect"); 890eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 8915dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 8925dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 8936438695222333981fafee9c8c09f3bf51dce3816bsalomon@google.com 894c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com target->drawRect(dstRect, dstMatrix, &localRect, localMatrix); 89527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 89627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 897429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comnamespace { 898429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 899429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gPosUVColorAttribs[] = { 900429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 901429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding }, 902c9f3b38f67893b22c3e02a6a934bc676e36c5cfcrmistry@google.com {kVec4ub_GrVertexAttribType, 2*sizeof(GrPoint), kColor_GrVertexAttribBinding} 903429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 904429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 905429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gPosColorAttribs[] = { 906429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 907429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding}, 908429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 909429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 910429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comstatic void set_vertex_attributes(GrDrawState* drawState, 911429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com const GrPoint* texCoords, 912429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com const GrColor* colors, 913429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com int* colorOffset, 914429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com int* texOffset) { 915429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *texOffset = -1; 916429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *colorOffset = -1; 917429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 918429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com if (NULL != texCoords && NULL != colors) { 919429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *texOffset = sizeof(GrPoint); 920429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *colorOffset = 2*sizeof(GrPoint); 921429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gPosUVColorAttribs>(3); 922429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } else if (NULL != texCoords) { 923429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *texOffset = sizeof(GrPoint); 924429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gPosUVColorAttribs>(2); 925429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } else if (NULL != colors) { 926429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com *colorOffset = sizeof(GrPoint); 927429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gPosColorAttribs>(2); 928429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } else { 929429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com drawState->setVertexAttribs<gPosColorAttribs>(1); 930429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com } 931429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com} 932429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 933429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}; 934429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com 93527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 93627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 93727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 93827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint positions[], 93927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint texCoords[], 94027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 94127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 94227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 943278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawVertices"); 94427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 945eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 9465dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 9475a56793b2a19eaf90b67d6f24441cc475d74ef17commit-bot@chromium.org GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope 9485a56793b2a19eaf90b67d6f24441cc475d74ef17commit-bot@chromium.org 9495dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 95027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9519b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com GrDrawState* drawState = target->drawState(); 9529b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 9539b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com int colorOffset = -1, texOffset = -1; 954429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset); 9559b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 9569b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com size_t vertexSize = drawState->getVertexSize(); 95727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (sizeof(GrPoint) != vertexSize) { 958b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com if (!geo.set(target, vertexCount, 0)) { 9596513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 96027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 96127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 96227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* curVertex = geo.vertices(); 96327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 96427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 96527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *((GrPoint*)curVertex) = positions[i]; 96627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9679b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com if (texOffset >= 0) { 9683976825a21532e254311b90b4a9046e25717e335jvanverth@google.com *(GrPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; 96927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 9709b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com if (colorOffset >= 0) { 97127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 97227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 97326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 97427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 97527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 976b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com target->setVertexSourceToArray(positions, vertexCount); 97727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 97827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 979fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // we don't currently apply offscreen AA to this path. Need improved 980919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 981a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com 9828295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (NULL != indices) { 983919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 9848295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 9850406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com target->resetIndexSource(); 98627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 9878295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 9888295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 98927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 99027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 99106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 99293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 993f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.orgvoid GrContext::drawRRect(const GrPaint& paint, 994f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org const SkRRect& rect, 995f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org const SkStrokeRec& stroke) { 99619dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org if (rect.isEmpty()) { 99719dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org return; 99819dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org } 999f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1000eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 10015dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 10025dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 1003f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1004e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (!fOvalRenderer->drawSimpleRRect(target, this, paint.isAntiAlias(), rect, stroke)) { 1005f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkPath path; 1006f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org path.addRRect(rect); 1007e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); 1008f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1009f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org} 1010f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1011f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 1012f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 101346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.comvoid GrContext::drawOval(const GrPaint& paint, 1014fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& oval, 101546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com const SkStrokeRec& stroke) { 101619dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org if (oval.isEmpty()) { 101719dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org return; 101819dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org } 101993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1020eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 10215dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 10225dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 10230982d35187da7e1ed6c0eba5951bbdadca8b33e7bsalomon@google.com 1024e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke)) { 102581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkPath path; 102681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org path.addOval(oval); 1027e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); 102846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 1029150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 103027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 103183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com// Can 'path' be drawn as a pair of filled nested rectangles? 103283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.comstatic bool is_nested_rects(GrDrawTarget* target, 103383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com const SkPath& path, 103483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com const SkStrokeRec& stroke, 103583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkRect rects[2], 103683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com bool* useVertexCoverage) { 103783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkASSERT(stroke.isFillStyle()); 103883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 103983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (path.isInverseFillType()) { 104083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 104183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 104283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 104383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com const GrDrawState& drawState = target->getDrawState(); 104483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 104583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // TODO: this restriction could be lifted if we were willing to apply 104683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // the matrix to all the points individually rather than just to the rect 104783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 104883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 104983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 105083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 105183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com *useVertexCoverage = false; 105283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (!target->getDrawState().canTweakAlphaForCoverage()) { 1053e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (target->shouldDisableCoverageAAForBlend()) { 105483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 105583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } else { 105683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com *useVertexCoverage = true; 105783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 105883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 105983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 106083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkPath::Direction dirs[2]; 106183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (!path.isNestedRects(rects, dirs)) { 106283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return false; 106383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 106483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 10658d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { 106683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // The two rects need to be wound opposite to each other 10678d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com return false; 106883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 106983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 10708d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com // Right now, nested rects where the margin is not the same width 10718d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com // all around do not render correctly 10728d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com const SkScalar* outer = rects[0].asScalars(); 10738d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com const SkScalar* inner = rects[1].asScalars(); 10748d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com 10758d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com SkScalar margin = SkScalarAbs(outer[0] - inner[0]); 10768d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com for (int i = 1; i < 4; ++i) { 10778d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com SkScalar temp = SkScalarAbs(outer[i] - inner[i]); 10788d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com if (!SkScalarNearlyEqual(margin, temp)) { 10798d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com return false; 10808d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com } 10818d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com } 10828d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com 10838d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com return true; 10848d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com} 108583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 10865f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comvoid GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { 108727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1088fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 108912b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com if (path.isInverseFillType()) { 1090fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->drawPaint(paint); 1091fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1092fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1093fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1094fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 109581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // Note that internalDrawPath may sw-rasterize the path into a scratch texture. 109681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // Scratch textures can be recycled after they are returned to the texture 109781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // cache. This presents a potential hazard for buffered drawing. However, 109881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // the writePixels that uploads to the scratch will perform a flush so we're 109981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // OK. 1100eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com AutoRestoreEffects are; 11015dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush acf(this); 11025dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 1103e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org GrDrawState* drawState = target->drawState(); 110481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 1105e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisampled(); 1106e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org 1107e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (useCoverageAA && stroke.getWidth() < 0 && !path.isConvex()) { 110883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com // Concave AA paths are expensive - try to avoid them for special cases 110983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com bool useVertexCoverage; 111083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com SkRect rects[2]; 111183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 111283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { 1113e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org SkMatrix origViewMatrix = drawState->getViewMatrix(); 1114137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 1115137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 111683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return; 111783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 111883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 111983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com fAARectRenderer->fillAANestedRects(this->getGpu(), target, 112083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com rects, 1121137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com origViewMatrix, 112283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com useVertexCoverage); 112383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com return; 112483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 112583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com } 112683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com 112793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkRect ovalRect; 112846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com bool isOval = path.isOval(&ovalRect); 112946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 11307e32851d5473d14db5c396f5877e3dfcb7b19f6dskia.committer@gmail.com if (!isOval || path.isInverseFillType() 1131e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, stroke)) { 1132e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); 113393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 113493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 113593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 11361b20a10f0205da2d53e0837e4ddc6b2bd3b8a462bsalomon@google.comvoid GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, 1137f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org const SkStrokeRec& origStroke) { 113819dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org SkASSERT(!path.isEmpty()); 113993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1140d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1141d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1142d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1143d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1144e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org bool useCoverageAA = useAA && 1145e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org !target->getDrawState().getRenderTarget()->isMultisampled() && 1146e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org !target->shouldDisableCoverageAAForBlend(); 1147e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org 1148289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1149e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org GrPathRendererChain::DrawType type = 1150e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : 1151e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com GrPathRendererChain::kColor_DrawType; 115245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 1153eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com const SkPath* pathPtr = &path; 1154f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org SkTLazy<SkPath> tmpPath; 1155f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); 1156eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1157eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com // Try a 1st time without stroking the path and without allowing the SW renderer 1158e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type); 1159eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1160e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (NULL == pr) { 1161f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, this->getMatrix(), NULL)) { 1162eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com // It didn't work the 1st time, so try again with the stroked path 1163f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org if (stroke->applyToPath(tmpPath.init(), *pathPtr)) { 1164f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org pathPtr = tmpPath.get(); 1165f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org stroke.writable()->setFillStyle(); 1166e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (pathPtr->isEmpty()) { 1167e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org return; 1168e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org } 1169eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 1170eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 117119dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org 1172eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com // This time, allow SW renderer 1173e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type); 1174eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com } 1175eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com 1176e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com if (NULL == pr) { 1177515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 11783008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 11791983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 11803008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 11813008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 11823008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1183e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com pr->drawPath(*pathPtr, *stroke, target, useCoverageAA); 118427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 11858295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 118627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 118727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1188a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1189e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com if (NULL == fDrawBuffer) { 1190e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com return; 1191e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com } 1192e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com 1193a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1194a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1195a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 11966e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBuffer->flush(); 119753a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 11985dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org fFlushToReduceCacheSize = false; 119927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 120027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 12019c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.combool GrContext::writeTexturePixels(GrTexture* texture, 12020342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 12030342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com GrPixelConfig config, const void* buffer, size_t rowBytes, 12040342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 12056f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 1206bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1207bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 12089c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if ((kUnpremul_PixelOpsFlag & flags) || !fGpu->canWriteTexturePixels(texture, config)) { 12099c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (NULL != texture->asRenderTarget()) { 12109c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return this->writeRenderTargetPixels(texture->asRenderTarget(), 12119c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com left, top, width, height, 12129c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com config, buffer, rowBytes, flags); 12139c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } else { 12149c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 12159c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } 12166f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 12179c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com 12180342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 12190342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com this->flush(); 12200342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com } 12216f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 12229c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return fGpu->writeTexturePixels(texture, left, top, width, height, 12239c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com config, buffer, rowBytes); 12246f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 12256f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 12260342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.combool GrContext::readTexturePixels(GrTexture* texture, 12270342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 12280342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com GrPixelConfig config, void* buffer, size_t rowBytes, 12290342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 1230278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readTexturePixels"); 1231bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1232669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1233669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 1234669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL != target) { 12350342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com return this->readRenderTargetPixels(target, 12360342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com left, top, width, height, 12370342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com config, buffer, rowBytes, 12380342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com flags); 1239669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } else { 12403f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org // TODO: make this more efficient for cases where we're reading the entire 12413f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org // texture, i.e., use GetTexImage() instead 12423f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org 12433f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org // create scratch rendertarget and read from that 12443f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org GrAutoScratchTexture ast; 12453f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org GrTextureDesc desc; 12463f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fFlags = kRenderTarget_GrTextureFlagBit; 12473f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fWidth = width; 12483f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fHeight = height; 12493f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fConfig = config; 12503f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org desc.fOrigin = kTopLeft_GrSurfaceOrigin; 12513f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org ast.set(this, desc, kExact_ScratchTexMatch); 12523f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org GrTexture* dst = ast.texture(); 12533f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org if (NULL != dst && NULL != (target = dst->asRenderTarget())) { 12543f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org this->copyTexture(texture, target, NULL); 12553f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org return this->readRenderTargetPixels(target, 12563f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org left, top, width, height, 12573f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org config, buffer, rowBytes, 12583f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org flags); 12593f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org } 1260583b18a20959c9ac360316a366f4ddd9598bdf52skia.committer@gmail.com 1261669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1262669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1263669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com} 1264669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1265a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkConfig8888.h" 1266a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1267a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.comnamespace { 1268a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com/** 1269a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 1270a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * formats are representable as Config8888 and so the function returns false 1271a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * if the GrPixelConfig has no equivalent Config8888. 1272a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com */ 1273a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.combool grconfig_to_config8888(GrPixelConfig config, 12740342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com bool unpremul, 1275a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888* config8888) { 1276a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com switch (config) { 12770342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com case kRGBA_8888_GrPixelConfig: 12780342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com if (unpremul) { 12790342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 12800342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com } else { 12810342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com *config8888 = SkCanvas::kRGBA_Premul_Config8888; 12820342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com } 1283a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 12840342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com case kBGRA_8888_GrPixelConfig: 12850342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com if (unpremul) { 12860342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 12870342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com } else { 12880342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com *config8888 = SkCanvas::kBGRA_Premul_Config8888; 12890342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com } 1290a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1291a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com default: 1292a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1293a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1294a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1295a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1296a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com// It returns a configuration with where the byte position of the R & B components are swapped in 1297a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com// relation to the input config. This should only be called with the result of 1298a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com// grconfig_to_config8888 as it will fail for other configs. 1299a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comSkCanvas::Config8888 swap_config8888_red_and_blue(SkCanvas::Config8888 config8888) { 1300a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com switch (config8888) { 1301a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case SkCanvas::kBGRA_Premul_Config8888: 1302a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return SkCanvas::kRGBA_Premul_Config8888; 1303a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case SkCanvas::kBGRA_Unpremul_Config8888: 1304a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return SkCanvas::kRGBA_Unpremul_Config8888; 1305a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case SkCanvas::kRGBA_Premul_Config8888: 1306a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return SkCanvas::kBGRA_Premul_Config8888; 1307a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com case SkCanvas::kRGBA_Unpremul_Config8888: 1308a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return SkCanvas::kBGRA_Unpremul_Config8888; 1309a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com default: 1310a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrCrash("Unexpected input"); 1311a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return SkCanvas::kBGRA_Unpremul_Config8888;; 1312a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1313a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1314a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1315a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 13160342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.combool GrContext::readRenderTargetPixels(GrRenderTarget* target, 13170342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 13189c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig dstConfig, void* buffer, size_t rowBytes, 13190342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 1320278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 1321bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1322bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 1323fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (NULL == target) { 1324bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target = fRenderTarget.get(); 1325c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (NULL == target) { 1326c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1327c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1328c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1329669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 13306f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 13316f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 13326f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1333c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1334a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul. 1335c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1336a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll 1337a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read. 1338a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top, 13399c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com width, height, dstConfig, 1340c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 13419c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // We ignore the preferred config if it is different than our config unless it is an R/B swap. 13429c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // In that case we'll perform an R and B swap while drawing to a scratch texture of the swapped 13439c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // config. Then we will call readPixels on the scratch with the swapped config. The swaps during 13449c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from 13459c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // dstConfig. 13469c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig readConfig = dstConfig; 13479c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com bool swapRAndB = false; 13485d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org if (GrPixelConfigSwapRAndB(dstConfig) == 13495d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org fGpu->preferredReadPixelsConfig(dstConfig, target->config())) { 13509c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com readConfig = GrPixelConfigSwapRAndB(readConfig); 13519c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com swapRAndB = true; 13529c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } 1353a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 13540342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); 1355c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 13569c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (unpremul && !GrPixelConfigIs8888(dstConfig)) { 1357a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // The unpremul flag is only allowed for these two configs. 13580a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 13590a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 1360a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1361a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If the src is a texture and we would have to do conversions after read pixels, we instead 1362a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // do the conversions by drawing the src to a scratch texture. If we handle any of the 1363a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // conversions in the draw we set the corresponding bool to false so that we don't reapply it 1364a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // on the read back pixels. 1365a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrTexture* src = target->asTexture(); 1366c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com GrAutoScratchTexture ast; 1367a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (NULL != src && (swapRAndB || unpremul || flipY)) { 1368a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Make the scratch a render target because we don't have a robust readTexturePixels as of 1369a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // yet. It calls this function. 137075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 137175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit; 137275b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 137375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 1374a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com desc.fConfig = readConfig; 13753cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org desc.fOrigin = kTopLeft_GrSurfaceOrigin; 1376c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 13779c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // When a full read back is faster than a partial we could always make the scratch exactly 1378a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // match the passed rect. However, if we see many different size rectangles we will trash 1379a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // our texture cache and pay the cost of creating and destroying many textures. So, we only 1380a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // request an exact match when the caller is reading an entire RT. 138156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 138256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 138356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 138456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 138556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 138656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 138756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com match = kExact_ScratchTexMatch; 138856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 138956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ast.set(this, desc, match); 1390c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* texture = ast.texture(); 1391a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (texture) { 1392d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com // compute a matrix to perform the draw 1393b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix textureMatrix; 13943cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1395d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com textureMatrix.postIDiv(src->width(), src->height()); 1396d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1397adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com SkAutoTUnref<const GrEffectRef> effect; 1398a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (unpremul) { 1399adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com effect.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix)); 1400adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (NULL != effect) { 14019c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com unpremul = false; // we no longer need to do this on CPU after the read back. 1402d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com } 1403a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1404a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // If we failed to create a PM->UPM effect and have no other conversions to perform then 1405a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // there is no longer any point to using the scratch. 1406adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (NULL != effect || flipY || swapRAndB) { 1407adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (!effect) { 1408adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com effect.reset(GrConfigConversionEffect::Create( 1409adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com src, 1410adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com swapRAndB, 1411adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com GrConfigConversionEffect::kNone_PMConversion, 1412adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com textureMatrix)); 1413a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1414a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com swapRAndB = false; // we will handle the swap in the draw. 1415a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 141613f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // We protect the existing geometry here since it may not be 141713f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // clear to the caller that a draw operation (i.e., drawSimpleRect) 141813f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // can be invoked in this method 141913f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit); 1420a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 1421f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(effect); 1422eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com drawState->addColorEffect(effect); 1423d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1424a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com drawState->setRenderTarget(texture->asRenderTarget()); 1425fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 1426a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com fGpu->drawSimpleRect(rect, NULL); 1427a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // we want to read back from the scratch's origin 1428a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com left = 0; 1429a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com top = 0; 1430a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com target = texture->asRenderTarget(); 1431a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1432c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1433a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1434a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fGpu->readPixels(target, 1435a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com left, top, width, height, 14363cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org readConfig, buffer, rowBytes)) { 1437a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return false; 1438a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1439d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com // Perform any conversions we weren't able to perform using a scratch texture. 14403cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (unpremul || swapRAndB) { 1441ccaa002dd81a6a8bd5acb7a2fa69a2437873c1fdbsalomon@google.com // These are initialized to suppress a warning 1442ccaa002dd81a6a8bd5acb7a2fa69a2437873c1fdbsalomon@google.com SkCanvas::Config8888 srcC8888 = SkCanvas::kNative_Premul_Config8888; 1443ccaa002dd81a6a8bd5acb7a2fa69a2437873c1fdbsalomon@google.com SkCanvas::Config8888 dstC8888 = SkCanvas::kNative_Premul_Config8888; 1444ccaa002dd81a6a8bd5acb7a2fa69a2437873c1fdbsalomon@google.com 14459c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com SkDEBUGCODE(bool c8888IsValid =) grconfig_to_config8888(dstConfig, false, &srcC8888); 14469c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com grconfig_to_config8888(dstConfig, unpremul, &dstC8888); 1447ccaa002dd81a6a8bd5acb7a2fa69a2437873c1fdbsalomon@google.com 1448a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (swapRAndB) { 1449f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(c8888IsValid); // we should only do r/b swap on 8888 configs 1450a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com srcC8888 = swap_config8888_red_and_blue(srcC8888); 14510342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com } 1452f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(c8888IsValid); 14533cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org uint32_t* b32 = reinterpret_cast<uint32_t*>(buffer); 14543cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org SkConvertConfig8888Pixels(b32, rowBytes, dstC8888, 14553cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org b32, rowBytes, srcC8888, 14563cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org width, height); 1457c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1458a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com return true; 145927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 146027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 146175f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.comvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 1462f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(target); 146375f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com ASSERT_OWNED_RESOURCE(target); 146475f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // In the future we may track whether there are any pending draws to this 146575f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // target. We don't today so we always perform a flush. We don't promise 146675f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // this to our clients, though. 146775f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com this->flush(); 146875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com fGpu->resolveRenderTarget(target); 146975f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com} 147075f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com 1471a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.comvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) { 1472ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1473ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1474ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1475ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1476ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 14771ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // Writes pending to the source texture are not tracked, so a flush 14781ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // is required to ensure that the copy captures the most recent contents 1479adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com // of the source texture. See similar behavior in 14801ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // GrContext::resolveRenderTarget. 14811ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com this->flush(); 14821ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com 1483873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 14848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 14858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 1486b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix sampleM; 1487ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 1488a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); 1489a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (NULL != topLeft) { 1490a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com srcRect.offset(*topLeft); 1491a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 1492a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height()); 1493a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com if (!srcRect.intersect(srcBounds)) { 1494a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com return; 1495a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com } 1496a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com sampleM.preTranslate(SkIntToScalar(srcRect.fLeft), SkIntToScalar(srcRect.fTop)); 1497eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com drawState->addColorTextureEffect(src, sampleM); 1498a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com SkRect dstR = SkRect::MakeWH(SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); 1499a2a31928470dfb642880f6ab2e4d34b1c7f5d476scroggo@google.com fGpu->drawSimpleRect(dstR, NULL); 1500ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1501ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 15029c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.combool GrContext::writeRenderTargetPixels(GrRenderTarget* target, 15030342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com int left, int top, int width, int height, 15049c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig srcConfig, 15050342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com const void* buffer, 15060342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com size_t rowBytes, 15070342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com uint32_t flags) { 15086f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 1509bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 15106f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 1511fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (NULL == target) { 1512bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target = fRenderTarget.get(); 15136f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 15149c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 15156f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 15166f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 151727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1518a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it (e.g. glDrawPixels on 1519a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // desktop GL). 1520a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1521a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // We will always call some form of writeTexturePixels and we will pass our flags on to it. 1522a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // Thus, we don't perform a flush here since that call will do it (if the kNoFlush flag isn't 1523a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // set.) 152427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 15250342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com // If the RT is also a texture and we don't have to premultiply then take the texture path. 15260342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com // We expect to be at least as fast or faster since it doesn't use an intermediate texture as 15270342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com // we do below. 1528fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 15294382330a15e13b9ef54010606eb758c0c66e1868commit-bot@chromium.org#if !defined(SK_BUILD_FOR_MAC) 1530a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called on a texture 1531a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // attached to an FBO. The FBO still sees the old image. TODO: determine what OS versions and/or 1532a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // HW is affected. 15339c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (NULL != target->asTexture() && !(kUnpremul_PixelOpsFlag & flags) && 15349c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com fGpu->canWriteTexturePixels(target->asTexture(), srcConfig)) { 15359c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return this->writeTexturePixels(target->asTexture(), 15369c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com left, top, width, height, 15379c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com srcConfig, buffer, rowBytes, flags); 1538a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1539a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif 1540d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 15419c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // We ignore the preferred config unless it is a R/B swap of the src config. In that case 15429c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // we will upload the original src data to a scratch texture but we will spoof it as the swapped 15439c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // config. This scratch will then have R and B swapped. We correct for this by swapping again 15449c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // when drawing the scratch to the dst using a conversion effect. 15459c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com bool swapRAndB = false; 15469c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com GrPixelConfig writeConfig = srcConfig; 15475d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org if (GrPixelConfigSwapRAndB(srcConfig) == 15485d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org fGpu->preferredWritePixelsConfig(srcConfig, target->config())) { 15499c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com writeConfig = GrPixelConfigSwapRAndB(srcConfig); 15509c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com swapRAndB = true; 1551a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1552a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 155375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 155475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 155575b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 15569c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com desc.fConfig = writeConfig; 155750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture ast(this, desc); 155850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* texture = ast.texture(); 155927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL == texture) { 15609c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 156127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1562d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1563adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com SkAutoTUnref<const GrEffectRef> effect; 1564b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com SkMatrix textureMatrix; 1565d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com textureMatrix.setIDiv(texture->width(), texture->height()); 1566d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com 1567a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com // allocate a tmp buffer and sw convert the pixels to premul 1568a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); 1569a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1570a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (kUnpremul_PixelOpsFlag & flags) { 15719c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (!GrPixelConfigIs8888(srcConfig)) { 15729c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 1573a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1574adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com effect.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); 15759c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com // handle the unpremul step on the CPU if we couldn't create an effect to do it. 1576adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (NULL == effect) { 1577a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 15781acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org SkDEBUGCODE(bool success = ) 15799c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com grconfig_to_config8888(srcConfig, true, &srcConfig8888); 1580f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(success); 15811acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org SkDEBUGCODE(success = ) 15829c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com grconfig_to_config8888(srcConfig, false, &dstConfig8888); 1583f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(success); 1584a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 1585a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com tmpPixels.reset(width * height); 1586a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 1587a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com src, rowBytes, srcConfig8888, 1588a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com width, height); 1589a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com buffer = tmpPixels.get(); 1590a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com rowBytes = 4 * width; 1591a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1592a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1593adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com if (NULL == effect) { 1594adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com effect.reset(GrConfigConversionEffect::Create(texture, 1595adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com swapRAndB, 1596adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com GrConfigConversionEffect::kNone_PMConversion, 1597adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com textureMatrix)); 1598a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1599a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 16009c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com if (!this->writeTexturePixels(texture, 16019c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com 0, 0, width, height, 16029c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com writeConfig, buffer, rowBytes, 16039c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com flags & ~kUnpremul_PixelOpsFlag)) { 16049c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return false; 16059c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com } 160627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 160713f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // writeRenderTargetPixels can be called in the midst of drawing another 16080c23faf222c24529781139495a5f4f4ab61f7cb2skia.committer@gmail.com // object (e.g., when uploading a SW path rendering to the gpu while 160913f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com // drawing a rect) so preserve the current geometry. 1610137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com SkMatrix matrix; 1611137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); 1612137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit, &matrix); 16138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 1614f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(effect); 1615eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com drawState->addColorEffect(effect); 161627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 16178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 161827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1619fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org fGpu->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)), NULL); 16209c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com return true; 162127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 162227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 162327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1624eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, 1625eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com BufferedDraw buffered, 16265dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoRestoreEffects* are, 16275dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org AutoCheckFlush* acf) { 1628eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com // All users of this draw state should be freeing up all effects when they're done. 1629eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com // Otherwise effects that own resources may keep those resources alive indefinitely. 1630f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageStages()); 1631eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com 16321d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffered) { 16331267fbd95290f58443652ca8d947bde50b212618robertphillips@google.com fDrawBuffer->flush(); 16341d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com fLastDrawWasBuffered = kNo_BufferedDraw; 163527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1636bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org ASSERT_OWNED_RESOURCE(fRenderTarget.get()); 163707ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com if (NULL != paint) { 1638f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL != are); 16395dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org SkASSERT(NULL != acf); 1640eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com are->set(fDrawState); 1641bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); 1642af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com#if GR_DEBUG_PARTIAL_COVERAGE_CHECK 1643af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com if ((paint->hasMask() || 0xff != paint->fCoverage) && 1644af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com !fGpu->canApplyCoverage()) { 1645af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 1646af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com } 1647af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com#endif 1648bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org } else { 1649137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com fDrawState->reset(fViewMatrix); 1650bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fDrawState->setRenderTarget(fRenderTarget.get()); 165107ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com } 1652bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org GrDrawTarget* target; 16531d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com if (kYes_BufferedDraw == buffered) { 16541d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com fLastDrawWasBuffered = kYes_BufferedDraw; 1655bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target = fDrawBuffer; 16561d4edd38f6b62d1cc54cb7bc6f3c6ce10ccb1471bsalomon@google.com } else { 1657f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(kNo_BufferedDraw == buffered); 1658bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fLastDrawWasBuffered = kNo_BufferedDraw; 1659bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target = fGpu; 166027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1661bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org fDrawState->setState(GrDrawState::kClip_StateBit, NULL != fClip && 1662bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org !fClip->fClipStack->isWideOpen()); 1663bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org target->setClip(fClip); 1664f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(fDrawState == target->drawState()); 1665bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org return target; 166627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 166727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 166872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com/* 166972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * This method finds a path renderer that can draw the specified path on 167072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * the provided target. 1671fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Due to its expense, the software path renderer has split out so it can 167272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * can be individually allowed/disallowed via the "allowSW" boolean. 167372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com */ 16748d033a1b125886c62906d975b5cc28a382064526bsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const SkPath& path, 16755f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com const SkStrokeRec& stroke, 1676c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com const GrDrawTarget* target, 167745a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com bool allowSW, 167845a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com GrPathRendererChain::DrawType drawType, 167945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com GrPathRendererChain::StencilSupport* stencilSupport) { 168045a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com 16813008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 168245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); 16833008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 168472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 168512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, 168612b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com stroke, 168772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com target, 168845a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com drawType, 168945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com stencilSupport); 169072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 169172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == pr && allowSW) { 169272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == fSoftwarePathRenderer) { 1693c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); 169472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 169572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com pr = fSoftwarePathRenderer; 169672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 169772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 169872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com return pr; 16993008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 17003008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 170127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 17026b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.orgbool GrContext::isConfigRenderable(GrPixelConfig config, bool withMSAA) const { 17036b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.org return fGpu->caps()->isConfigRenderable(config, withMSAA); 170499a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com} 170599a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com 17068fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() { 1707f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fDrawBuffer); 1708f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fDrawBufferVBAllocPool); 1709f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(NULL == fDrawBufferIBAllocPool); 17108fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1711de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferVBAllocPool = 1712c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com SkNEW_ARGS(GrVertexBufferAllocPool, (fGpu, false, 171327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 1714c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)); 1715de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferIBAllocPool = 1716c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu, false, 1717de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 1718c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)); 171927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1720c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu, 17216e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBufferVBAllocPool, 17226e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBufferIBAllocPool)); 17233c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com 17246e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDrawBuffer->setDrawState(fDrawState); 172527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 172627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 172721c10c5ff50cb8f2fd995fc9396d435d3396258bbsalomon@google.comGrDrawTarget* GrContext::getTextTarget() { 17285dbb149fda134941e5d168790127caf294d322e2commit-bot@chromium.org return this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL); 172927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 173027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 173127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 173227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getQuadIndexBuffer(); 173327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 1734dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 1735a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comnamespace { 1736a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comvoid test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { 1737a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion pmToUPM; 1738a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion upmToPM; 1739a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM); 1740a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *pmToUPMValue = pmToUPM; 1741a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com *upmToPMValue = upmToPM; 1742a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1743a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1744a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1745adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.comconst GrEffectRef* GrContext::createPMToUPMEffect(GrTexture* texture, 1746adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com bool swapRAndB, 1747adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com const SkMatrix& matrix) { 1748a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fDidTestPMConversions) { 1749a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 1750d0f3f6825bd5c232da52f4dc1af69b76403b797fbsalomon@google.com fDidTestPMConversions = true; 1751a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1752a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion pmToUPM = 1753a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); 1754a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { 1755adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix); 1756a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 1757adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return NULL; 1758a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1759a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1760a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 1761adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.comconst GrEffectRef* GrContext::createUPMToPMEffect(GrTexture* texture, 1762adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com bool swapRAndB, 1763adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com const SkMatrix& matrix) { 1764a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (!fDidTestPMConversions) { 1765a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 1766d0f3f6825bd5c232da52f4dc1af69b76403b797fbsalomon@google.com fDidTestPMConversions = true; 1767a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1768a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com GrConfigConversionEffect::PMConversion upmToPM = 1769a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); 1770a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { 1771adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix); 1772a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } else { 1773adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com return NULL; 1774a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com } 1775a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com} 1776a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com 17775c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.orgGrPath* GrContext::createPath(const SkPath& inPath, const SkStrokeRec& stroke) { 17785c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org SkASSERT(fGpu->caps()->pathRenderingSupport()); 17795c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org 17805c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org // TODO: now we add to fTextureCache. This should change to fResourceCache. 17815c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org GrResourceKey resourceKey = GrPath::ComputeKey(inPath, stroke); 17825c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org GrPath* path = static_cast<GrPath*>(fTextureCache->find(resourceKey)); 17835c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org if (NULL != path && path->isEqualTo(inPath, stroke)) { 17845c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org path->ref(); 17855c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org } else { 17865c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org path = fGpu->createPath(inPath, stroke); 17875c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org fTextureCache->purgeAsNeeded(1, path->sizeInBytes()); 17885c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org fTextureCache->addResource(resourceKey, path); 17895c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org } 17905c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org return path; 17915c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org} 17925c8ee2539b9316b22416a991a1f560ef5cec7957commit-bot@chromium.org 1793c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 17945955202c805c7ef1448103cbf666972ea9d1ded1robertphillips@google.com#if GR_CACHE_STATS 17955f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.comvoid GrContext::printCacheStats() const { 17965f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.com fTextureCache->printStats(); 17975f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.com} 17985f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.com#endif 1799