13f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 23f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/* 33f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Copyright 2011 Google Inc. 43f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * 53f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 63f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * found in the LICENSE file. 73f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com */ 83f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 93f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 10e4339c1d8b3bdff80969624b9955e11fb6fcf0cbbsalomon@google.com#include "GrContext.h" 11e4339c1d8b3bdff80969624b9955e11fb6fcf0cbbsalomon@google.com 12848d120d9470989a611e6c1d96646d8fa0bdd3f0tomhudson@google.com#include "effects/GrSingleTextureEffect.h" 13f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com#include "effects/GrConfigConversionEffect.h" 14ffd9ba72809740cef9d8457a88a946eae3bbb7bdbsalomon@google.com 15d36b83c81d31e1cd58c737e3f7d9d1aeb18526e3jvanverth@google.com#include "GrAARectRenderer.h" 163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrBufferAllocPool.h" 173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrGpu.h" 18516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.com#include "GrDrawTargetCaps.h" 193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrIndexBuffer.h" 203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrInOrderDrawBuffer.h" 2151d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org#include "GrOvalRenderer.h" 223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrPathRenderer.h" 233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrPathUtils.h" 243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrResourceCache.h" 25a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com#include "GrSoftwarePathRenderer.h" 263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrStencilBuffer.h" 273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrTextStrike.h" 2849d843a911c5ad373354bbe871a75a2d1cacebbbbsalomon@google.com#include "SkRTConf.h" 294d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org#include "SkRRect.h" 305c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com#include "SkStrokeRec.h" 313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "SkTLazy.h" 324e98b5f7be8218d4a93b21df06a83c74b0942b24bsalomon@google.com#include "SkTLS.h" 333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "SkTrace.h" 343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 3549d843a911c5ad373354bbe871a75a2d1cacebbbbsalomon@google.com// It can be useful to set this to false to test whether a bug is caused by using the 3673631cc5a64283b9ed285b40739abe9b9a039b2absalomon@google.com// InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffer, or to make 3749d843a911c5ad373354bbe871a75a2d1cacebbbbsalomon@google.com// debugging simpler. 38d36543342d0894e354fe82caa73542bb417bcf1cbsalomon@google.comSK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true, 39de883c44a7b53cf40b12fab49cd521dcbe18b285jvanverth@google.com "Defers rendering in GrContext via GrInOrderDrawBuffer."); 4049d843a911c5ad373354bbe871a75a2d1cacebbbbsalomon@google.com 4149d843a911c5ad373354bbe871a75a2d1cacebbbbsalomon@google.com#define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw) 423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 430fde04d1de4773e5168a56dbd455b77e1424434acommit-bot@chromium.org#ifdef SK_DEBUG 44b79952d44b66f4275c23dda56cb0c4188569a90areed@google.com // change this to a 1 to see notifications when partial coverage fails 45b79952d44b66f4275c23dda56cb0c4188569a90areed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 46b79952d44b66f4275c23dda56cb0c4188569a90areed@google.com#else 47b79952d44b66f4275c23dda56cb0c4188569a90areed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 48b79952d44b66f4275c23dda56cb0c4188569a90areed@google.com#endif 49b79952d44b66f4275c23dda56cb0c4188569a90areed@google.com 50428b26ff1d2e1d8a4b13e690ba693d105fb9377drobertphillips@google.comstatic const size_t MAX_RESOURCE_CACHE_COUNT = GR_DEFAULT_RESOURCE_CACHE_COUNT_LIMIT; 51428b26ff1d2e1d8a4b13e690ba693d105fb9377drobertphillips@google.comstatic const size_t MAX_RESOURCE_CACHE_BYTES = GR_DEFAULT_RESOURCE_CACHE_MB_LIMIT * 1024 * 1024; 523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 538c569f424e2f35dae25eaaf8f4d7bc1fb24a3893bsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; 543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 5673631cc5a64283b9ed285b40739abe9b9a039b2absalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; 5773631cc5a64283b9ed285b40739abe9b9a039b2absalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; 583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 59a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) 60b5ed4edffdba739303dbe834644333b948ecbff9bsalomon@google.com 61860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com// Glorified typedef to avoid including GrDrawState.h in GrContext.h 62860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.comclass GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {}; 63860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com 6421c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.orgclass GrContext::AutoCheckFlush { 6521c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.orgpublic: 6621c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(NULL != context); } 6721c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org 6821c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org ~AutoCheckFlush() { 6921c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org if (fContext->fFlushToReduceCacheSize) { 7021c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org fContext->flush(); 7121c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org } 7221c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org } 7321c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org 7421c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.orgprivate: 7521c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org GrContext* fContext; 7621c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org}; 7721c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org 780ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.comGrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) { 790ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com GrContext* context = SkNEW(GrContext); 800ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com if (context->init(backend, backendContext)) { 810ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com return context; 820ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com } else { 830ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com context->unref(); 840ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com return NULL; 853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 880ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.comGrContext::GrContext() { 890ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawState = NULL; 900ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fGpu = NULL; 91e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org fClip = NULL; 920ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fPathRendererChain = NULL; 930ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fSoftwarePathRenderer = NULL; 940ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fTextureCache = NULL; 950ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fFontCache = NULL; 960ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawBuffer = NULL; 970ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawBufferVBAllocPool = NULL; 980ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawBufferIBAllocPool = NULL; 9921c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org fFlushToReduceCacheSize = false; 1000ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fAARectRenderer = NULL; 10151d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org fOvalRenderer = NULL; 102e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org fViewMatrix.reset(); 103b79edfc18351e566f1b395ccb2b9f25bd35bb930robertphillips@google.com fMaxTextureSizeOverride = 1 << 20; 1040ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com} 1050ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1060ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.combool GrContext::init(GrBackend backend, GrBackendContext backendContext) { 107a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL == fGpu); 1080ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1090ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fGpu = GrGpu::Create(backend, backendContext, this); 1100ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com if (NULL == fGpu) { 1110ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com return false; 1120ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com } 1130ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1140ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawState = SkNEW(GrDrawState); 1150ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fGpu->setDrawState(fDrawState); 1160ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1170ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fTextureCache = SkNEW_ARGS(GrResourceCache, 118428b26ff1d2e1d8a4b13e690ba693d105fb9377drobertphillips@google.com (MAX_RESOURCE_CACHE_COUNT, 119428b26ff1d2e1d8a4b13e690ba693d105fb9377drobertphillips@google.com MAX_RESOURCE_CACHE_BYTES)); 12048f8f0474fb7f31a97f9b9fc153af8809ac0d40acommit-bot@chromium.org fTextureCache->setOverbudgetCallback(OverbudgetCB, this); 12148f8f0474fb7f31a97f9b9fc153af8809ac0d40acommit-bot@chromium.org 1220ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); 1230ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1240ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fLastDrawWasBuffered = kNo_BufferedDraw; 1250ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1260ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fAARectRenderer = SkNEW(GrAARectRenderer); 12751d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org fOvalRenderer = SkNEW(GrOvalRenderer); 1280ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1290ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDidTestPMConversions = false; 1300ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1310ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com this->setupDrawBuffer(); 1320ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com 1330ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com return true; 1344e98b5f7be8218d4a93b21df06a83c74b0942b24bsalomon@google.com} 1354e98b5f7be8218d4a93b21df06a83c74b0942b24bsalomon@google.com 1363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrContext::~GrContext() { 137a7dffabef59ae609e5d98c032265700a681cb06ebsalomon@google.com if (NULL == fGpu) { 138a7dffabef59ae609e5d98c032265700a681cb06ebsalomon@google.com return; 139a7dffabef59ae609e5d98c032265700a681cb06ebsalomon@google.com } 140a7dffabef59ae609e5d98c032265700a681cb06ebsalomon@google.com 1413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com this->flush(); 1427ee019c963ed4a2c9eb3d1c8490ba1ee246e0b1arobertphillips@google.com 14389fe2dcf4b11483850e0da098dc87b0cdc80a9b8robertphillips@google.com for (int i = 0; i < fCleanUpData.count(); ++i) { 14489fe2dcf4b11483850e0da098dc87b0cdc80a9b8robertphillips@google.com (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); 14589fe2dcf4b11483850e0da098dc87b0cdc80a9b8robertphillips@google.com } 14689fe2dcf4b11483850e0da098dc87b0cdc80a9b8robertphillips@google.com 1477ee019c963ed4a2c9eb3d1c8490ba1ee246e0b1arobertphillips@google.com // Since the gpu can hold scratch textures, give it a chance to let go 1487ee019c963ed4a2c9eb3d1c8490ba1ee246e0b1arobertphillips@google.com // of them before freeing the texture cache 1497ee019c963ed4a2c9eb3d1c8490ba1ee246e0b1arobertphillips@google.com fGpu->purgeResources(); 1507ee019c963ed4a2c9eb3d1c8490ba1ee246e0b1arobertphillips@google.com 1513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com delete fTextureCache; 1527b5b4274da2fcb1e8c56a99e2ae86703f3326fb5robertphillips@google.com fTextureCache = NULL; 1533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com delete fFontCache; 1543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com delete fDrawBuffer; 1553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com delete fDrawBufferVBAllocPool; 1563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com delete fDrawBufferIBAllocPool; 1573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 158fa8749437c07050c8478087ef4eb09069586bf7frobertphillips@google.com fAARectRenderer->unref(); 15951d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org fOvalRenderer->unref(); 160fa8749437c07050c8478087ef4eb09069586bf7frobertphillips@google.com 1613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fGpu->unref(); 1626afd4a39f8b15b1534c5c716e5de05bcac501b32commit-bot@chromium.org SkSafeUnref(fPathRendererChain); 1636afd4a39f8b15b1534c5c716e5de05bcac501b32commit-bot@chromium.org SkSafeUnref(fSoftwarePathRenderer); 1643649448163f693ebcb2cd8308d27e6ba215272eabsalomon@google.com fDrawState->unref(); 1653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 1663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrContext::contextLost() { 1680ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com this->contextDestroyed(); 1693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com this->setupDrawBuffer(); 1703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 1713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrContext::contextDestroyed() { 1733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // abandon first to so destructors 1743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // don't try to free the resources in the API. 1753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fGpu->abandonResources(); 1763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // a path renderer may be holding onto resources that 1783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // are now unusable 1796afd4a39f8b15b1534c5c716e5de05bcac501b32commit-bot@chromium.org SkSafeSetNull(fPathRendererChain); 1806afd4a39f8b15b1534c5c716e5de05bcac501b32commit-bot@chromium.org SkSafeSetNull(fSoftwarePathRenderer); 1813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com delete fDrawBuffer; 1833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fDrawBuffer = NULL; 1843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com delete fDrawBufferVBAllocPool; 1863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fDrawBufferVBAllocPool = NULL; 1873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com delete fDrawBufferIBAllocPool; 1893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fDrawBufferIBAllocPool = NULL; 1903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 191fa8749437c07050c8478087ef4eb09069586bf7frobertphillips@google.com fAARectRenderer->reset(); 1922487c826e35dd8dfa470913722ea15f73f8fd99fcommit-bot@chromium.org fOvalRenderer->reset(); 1933f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 194f511bc83831d0b7aad6b8b2709593ea305213183bsalomon@google.com fTextureCache->purgeAllUnlocked(); 19509af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org 1963f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fFontCache->freeAll(); 1973f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fGpu->markContextDirty(); 1983f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 1993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 200a955749f8bf09cf65154ca8d57a86444ffed85a5bsalomon@google.comvoid GrContext::resetContext(uint32_t state) { 201a955749f8bf09cf65154ca8d57a86444ffed85a5bsalomon@google.com fGpu->markContextDirty(state); 2023f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2033f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2043f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrContext::freeGpuResources() { 2053f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com this->flush(); 206935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 2072a46d231cee3d3ae87a6090da78b9971078fc9c7robertphillips@google.com fGpu->purgeResources(); 2082a46d231cee3d3ae87a6090da78b9971078fc9c7robertphillips@google.com 209fa8749437c07050c8478087ef4eb09069586bf7frobertphillips@google.com fAARectRenderer->reset(); 2102487c826e35dd8dfa470913722ea15f73f8fd99fcommit-bot@chromium.org fOvalRenderer->reset(); 211fa8749437c07050c8478087ef4eb09069586bf7frobertphillips@google.com 212f511bc83831d0b7aad6b8b2709593ea305213183bsalomon@google.com fTextureCache->purgeAllUnlocked(); 2133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fFontCache->freeAll(); 2143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // a path renderer may be holding onto resources 2156afd4a39f8b15b1534c5c716e5de05bcac501b32commit-bot@chromium.org SkSafeSetNull(fPathRendererChain); 2166afd4a39f8b15b1534c5c716e5de05bcac501b32commit-bot@chromium.org SkSafeSetNull(fSoftwarePathRenderer); 2173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 219a38bcb2cd6c018011060ee5dbe9f0a273c709a23twiz@google.comsize_t GrContext::getGpuTextureCacheBytes() const { 220a38bcb2cd6c018011060ee5dbe9f0a273c709a23twiz@google.com return fTextureCache->getCachedResourceBytes(); 221a38bcb2cd6c018011060ee5dbe9f0a273c709a23twiz@google.com} 222a38bcb2cd6c018011060ee5dbe9f0a273c709a23twiz@google.com 2233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 2243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2258f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.comGrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc, 2268f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com const GrCacheID& cacheID, 2278f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com const GrTextureParams* params) { 22898cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 2299addc0ab3020b8d09fae95afe618bb084c1ee7d6robertphillips@google.com GrResource* resource = fTextureCache->find(resourceKey); 2308f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com SkSafeRef(resource); 23107f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com return static_cast<GrTexture*>(resource); 2323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 234c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.combool GrContext::isTextureInCache(const GrTextureDesc& desc, 23598cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com const GrCacheID& cacheID, 23620c50f7c5feda26ad659838c4f3824c47aa36903bsalomon@google.com const GrTextureParams* params) const { 23798cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 238ebdf5650f83c18e13d0188e21c4f7cda9dfda11absalomon@google.com return fTextureCache->hasKey(resourceKey); 239ebdf5650f83c18e13d0188e21c4f7cda9dfda11absalomon@google.com} 240ebdf5650f83c18e13d0188e21c4f7cda9dfda11absalomon@google.com 2419addc0ab3020b8d09fae95afe618bb084c1ee7d6robertphillips@google.comvoid GrContext::addStencilBuffer(GrStencilBuffer* sb) { 242b5ed4edffdba739303dbe834644333b948ecbff9bsalomon@google.com ASSERT_OWNED_RESOURCE(sb); 24308e41f3f301dfbbe911c67cd773dba7de0478068robertphillips@google.com 24408e41f3f301dfbbe911c67cd773dba7de0478068robertphillips@google.com GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(sb->width(), 24508e41f3f301dfbbe911c67cd773dba7de0478068robertphillips@google.com sb->height(), 24608e41f3f301dfbbe911c67cd773dba7de0478068robertphillips@google.com sb->numSamples()); 24781aa09ceb2fec637188cac56251e25eb1024b46arobertphillips@google.com fTextureCache->addResource(resourceKey, sb); 2483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2509addc0ab3020b8d09fae95afe618bb084c1ee7d6robertphillips@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 2513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int sampleCnt) { 25208e41f3f301dfbbe911c67cd773dba7de0478068robertphillips@google.com GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width, 25308e41f3f301dfbbe911c67cd773dba7de0478068robertphillips@google.com height, 25408e41f3f301dfbbe911c67cd773dba7de0478068robertphillips@google.com sampleCnt); 2559addc0ab3020b8d09fae95afe618bb084c1ee7d6robertphillips@google.com GrResource* resource = fTextureCache->find(resourceKey); 25607f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com return static_cast<GrStencilBuffer*>(resource); 2573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comstatic void stretchImage(void* dst, 2603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int dstW, 2613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int dstH, 2623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com void* src, 2633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int srcW, 2643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int srcH, 26532b94f845a845a8e150ba2d83f45c2bcd192eb22robertphillips@google.com size_t bpp) { 2663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrFixed dx = (srcW << 16) / dstW; 2673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrFixed dy = (srcH << 16) / dstH; 2683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 2693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrFixed y = dy >> 1; 2703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 27132b94f845a845a8e150ba2d83f45c2bcd192eb22robertphillips@google.com size_t dstXLimit = dstW*bpp; 2723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com for (int j = 0; j < dstH; ++j) { 2733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrFixed x = dx >> 1; 2743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 2753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com void* dstRow = (uint8_t*)dst + j*dstW*bpp; 27632b94f845a845a8e150ba2d83f45c2bcd192eb22robertphillips@google.com for (size_t i = 0; i < dstXLimit; i += bpp) { 2773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com memcpy((uint8_t*) dstRow + i, 2783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com (uint8_t*) srcRow + (x>>16)*bpp, 2793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bpp); 2803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com x += dx; 2813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com y += dy; 2833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 2843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 2853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 286a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comnamespace { 287a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 288a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com// position + local coordinate 289a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comextern const GrVertexAttrib gVertexAttribs[] = { 290a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 291a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding} 292a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com}; 293a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 294a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com}; 295a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 296935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com// The desired texture is NPOT and tiled but that isn't supported by 2978abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com// the current hardware. Resize the texture to be a POT 2988abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.comGrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, 29998cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com const GrCacheID& cacheID, 3008abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com void* srcData, 3018abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com size_t rowBytes, 30229ba4805e88962ad40e3ca79c9a768e073f52badhumper@google.com bool filter) { 3038f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, cacheID, NULL)); 30407f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com if (NULL == clampedTexture) { 3058f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com clampedTexture.reset(this->createTexture(NULL, desc, cacheID, srcData, rowBytes)); 3069addc0ab3020b8d09fae95afe618bb084c1ee7d6robertphillips@google.com 30707f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com if (NULL == clampedTexture) { 3088abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com return NULL; 3098abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com } 3108abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com } 311b09364450fc79733f5d1629b84ef7c712a8eac55robertphillips@google.com 3128abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com GrTextureDesc rtDesc = desc; 3138abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com rtDesc.fFlags = rtDesc.fFlags | 3148abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com kRenderTarget_GrTextureFlagBit | 3158abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com kNoStencil_GrTextureFlagBit; 31604a9a1ce033abe61974016992c2f73441c1c73eecommit-bot@chromium.org rtDesc.fWidth = GrNextPow2(desc.fWidth); 31704a9a1ce033abe61974016992c2f73441c1c73eecommit-bot@chromium.org rtDesc.fHeight = GrNextPow2(desc.fHeight); 3188abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3198abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 3208abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3218abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com if (NULL != texture) { 3228abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 3238abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com GrDrawState* drawState = fGpu->drawState(); 3248abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com drawState->setRenderTarget(texture->asRenderTarget()); 3258abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3268abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com // if filtering is not desired then we want to ensure all 3278abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com // texels in the resampled image are copies of texels from 3288abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com // the original. 32929ba4805e88962ad40e3ca79c9a768e073f52badhumper@google.com GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTextureParams::kBilerp_FilterMode : 33029ba4805e88962ad40e3ca79c9a768e073f52badhumper@google.com GrTextureParams::kNone_FilterMode); 331860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params); 3328abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 333a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs)); 3342419b53383d572e3f3b7adcbcb2574a569bce0dcjvanverth@google.com 3359d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0); 3368abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3378abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com if (arg.succeeded()) { 3388abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com GrPoint* verts = (GrPoint*) arg.vertices(); 3398f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(GrPoint)); 3408f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(GrPoint)); 3418f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 3428abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com } 3438abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com } else { 3448abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com // TODO: Our CPU stretch doesn't filter. But we create separate 3457879945fc341357322f2a19d9a927ff2e6bae4d9bsalomon@google.com // stretched textures when the texture params is either filtered or 3468abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com // not. Either implement filtered stretch blit on CPU or just create 3478abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com // one when FBO case fails. 3488abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3498abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com rtDesc.fFlags = kNone_GrTextureFlags; 3508abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com // no longer need to clamp at min RT size. 3518abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com rtDesc.fWidth = GrNextPow2(desc.fWidth); 3528abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com rtDesc.fHeight = GrNextPow2(desc.fHeight); 35332b94f845a845a8e150ba2d83f45c2bcd192eb22robertphillips@google.com size_t bpp = GrBytesPerPixel(desc.fConfig); 3547879945fc341357322f2a19d9a927ff2e6bae4d9bsalomon@google.com SkAutoSMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHeight); 3558abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 3567879945fc341357322f2a19d9a927ff2e6bae4d9bsalomon@google.com srcData, desc.fWidth, desc.fHeight, bpp); 3578abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3588abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com size_t stretchedRowBytes = rtDesc.fWidth * bpp; 3598abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 360de883c44a7b53cf40b12fab49cd521dcbe18b285jvanverth@google.com SkDEBUGCODE(GrTexture* texture = )fGpu->createTexture(rtDesc, stretchedPixels.get(), 361de883c44a7b53cf40b12fab49cd521dcbe18b285jvanverth@google.com stretchedRowBytes); 362a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL != texture); 3638abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com } 3648abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3658abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com return texture; 3668abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com} 3678abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3688f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.comGrTexture* GrContext::createTexture(const GrTextureParams* params, 3698f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com const GrTextureDesc& desc, 3708f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com const GrCacheID& cacheID, 3718f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com void* srcData, 3723639a16a353da76b52943e8c1dd9e0dd5edda69dcommit-bot@chromium.org size_t rowBytes, 3733639a16a353da76b52943e8c1dd9e0dd5edda69dcommit-bot@chromium.org GrResourceKey* cacheKey) { 37498cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com SK_TRACE_EVENT0("GrContext::createTexture"); 3753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 37698cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 3776dbbd6c68e3ef02908261880d8dbf52580bfaad9robertphillips@google.com 3788f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com GrTexture* texture; 3796dbbd6c68e3ef02908261880d8dbf52580bfaad9robertphillips@google.com if (GrTexture::NeedsResizing(resourceKey)) { 3808f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com texture = this->createResizedTexture(desc, cacheID, 3818f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com srcData, rowBytes, 38229ba4805e88962ad40e3ca79c9a768e073f52badhumper@google.com GrTexture::NeedsBilerp(resourceKey)); 3833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 3848f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com texture= fGpu->createTexture(desc, srcData, rowBytes); 3858abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com } 3868abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 3878abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com if (NULL != texture) { 388407ee05903b17cc662265a6b7a4ad478655b1794robertphillips@google.com // Adding a resource could put us overbudget. Try to free up the 389407ee05903b17cc662265a6b7a4ad478655b1794robertphillips@google.com // necessary space before adding it. 390407ee05903b17cc662265a6b7a4ad478655b1794robertphillips@google.com fTextureCache->purgeAsNeeded(1, texture->sizeInBytes()); 39181aa09ceb2fec637188cac56251e25eb1024b46arobertphillips@google.com fTextureCache->addResource(resourceKey, texture); 3923639a16a353da76b52943e8c1dd9e0dd5edda69dcommit-bot@chromium.org 3933639a16a353da76b52943e8c1dd9e0dd5edda69dcommit-bot@chromium.org if (NULL != cacheKey) { 3943639a16a353da76b52943e8c1dd9e0dd5edda69dcommit-bot@chromium.org *cacheKey = resourceKey; 3953639a16a353da76b52943e8c1dd9e0dd5edda69dcommit-bot@chromium.org } 3963f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 3978abd697592cf7249d2ff55f8aefd2a463091ee19robertphillips@google.com 39807f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com return texture; 3993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4003f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4019b2fb91aa9e7228ab8ea0f59e18152fa1cf22fd5skia.committer@gmail.comstatic GrTexture* create_scratch_texture(GrGpu* gpu, 4029b2fb91aa9e7228ab8ea0f59e18152fa1cf22fd5skia.committer@gmail.com GrResourceCache* textureCache, 403db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com const GrTextureDesc& desc) { 404db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com GrTexture* texture = gpu->createTexture(desc, NULL, 0); 405db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com if (NULL != texture) { 406db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com GrResourceKey key = GrTexture::ComputeScratchKey(texture->desc()); 407db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com // Adding a resource could put us overbudget. Try to free up the 408db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com // necessary space before adding it. 409db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com textureCache->purgeAsNeeded(1, texture->sizeInBytes()); 410db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com // Make the resource exclusive so future 'find' calls don't return it 411db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com textureCache->addResource(key, texture, GrResourceCache::kHide_OwnershipFlag); 412db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com } 413db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com return texture; 414db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com} 415db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com 4168f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.comGrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match) { 417c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com 418a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT((inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || 419db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com !(inDesc.fFlags & kNoStencil_GrTextureFlagBit)); 420db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com 421db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com // Renderable A8 targets are not universally supported (e.g., not on ANGLE) 4221c76f7905778dd7f91bac8fe147b9def90547d53bsalomon@google.com SkASSERT(this->isConfigRenderable(kAlpha_8_GrPixelConfig, inDesc.fSampleCnt > 0) || 423db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || 424db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com (inDesc.fConfig != kAlpha_8_GrPixelConfig)); 425db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com 426d91c9eac7cc13869ffa5e93b9862d1d5ccb6587arobertphillips@google.com if (!fGpu->caps()->reuseScratchTextures() && 427d91c9eac7cc13869ffa5e93b9862d1d5ccb6587arobertphillips@google.com !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit)) { 428d91c9eac7cc13869ffa5e93b9862d1d5ccb6587arobertphillips@google.com // If we're never recycling this texture we can always make it the right size 429db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com return create_scratch_texture(fGpu, fTextureCache, inDesc); 430db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com } 431db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com 432db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com GrTextureDesc desc = inDesc; 4337996019411e2831fd8ecba9695bf87c999825776rileya@google.com 43498cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com if (kApprox_ScratchTexMatch == match) { 4353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // bin by pow2 with a reasonable min 436eaf5cf160f64dcb4f0fef8c5bfd9396909b1659absalomon@google.com static const int MIN_SIZE = 16; 4373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 4383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 4393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 4403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 44107f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com GrResource* resource = NULL; 4423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int origWidth = desc.fWidth; 4433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int origHeight = desc.fHeight; 4443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 4453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com do { 44698cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com GrResourceKey key = GrTexture::ComputeScratchKey(desc); 44781aa09ceb2fec637188cac56251e25eb1024b46arobertphillips@google.com // Ensure we have exclusive access to the texture so future 'find' calls don't return it 44881aa09ceb2fec637188cac56251e25eb1024b46arobertphillips@google.com resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag); 4498f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com if (NULL != resource) { 4508f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com resource->ref(); 4518f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com break; 4528f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com } 4538f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com if (kExact_ScratchTexMatch == match) { 4543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com break; 4553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 456eaf5cf160f64dcb4f0fef8c5bfd9396909b1659absalomon@google.com // We had a cache miss and we are in approx mode, relax the fit of the flags. 4578f5dc5a363c2e9548f3b48325a1579a5da92e21absalomon@google.com 458935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com // We no longer try to reuse textures that were previously used as render targets in 4597996019411e2831fd8ecba9695bf87c999825776rileya@google.com // situations where no RT is needed; doing otherwise can confuse the video driver and 4607996019411e2831fd8ecba9695bf87c999825776rileya@google.com // cause significant performance problems in some cases. 4617996019411e2831fd8ecba9695bf87c999825776rileya@google.com if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 4623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 4633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 4643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com break; 4653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 466935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 4673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } while (true); 4683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 46907f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com if (NULL == resource) { 4703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com desc.fFlags = inDesc.fFlags; 4713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com desc.fWidth = origWidth; 4723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com desc.fHeight = origHeight; 473db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com resource = create_scratch_texture(fGpu, fTextureCache, desc); 4743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 4753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 47607f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com return static_cast<GrTexture*>(resource); 4773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 4783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 479afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.comvoid GrContext::addExistingTextureToCache(GrTexture* texture) { 480afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com 481afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com if (NULL == texture) { 482afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com return; 483afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com } 484afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com 485267329d2f29d01bf364f3ffc340cade95b5e4a75robertphillips@google.com // This texture should already have a cache entry since it was once 486267329d2f29d01bf364f3ffc340cade95b5e4a75robertphillips@google.com // attached 487a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL != texture->getCacheEntry()); 488267329d2f29d01bf364f3ffc340cade95b5e4a75robertphillips@google.com 489267329d2f29d01bf364f3ffc340cade95b5e4a75robertphillips@google.com // Conceptually, the cache entry is going to assume responsibility 4904db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // for the creation ref. Assert refcnt == 1. 491a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(texture->unique()); 492267329d2f29d01bf364f3ffc340cade95b5e4a75robertphillips@google.com 493d91c9eac7cc13869ffa5e93b9862d1d5ccb6587arobertphillips@google.com if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) { 4944db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // Since this texture came from an AutoScratchTexture it should 4954db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // still be in the exclusive pile. Recycle it. 4964db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com fTextureCache->makeNonExclusive(texture->getCacheEntry()); 497db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com this->purgeCache(); 4984db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com } else if (texture->getDeferredRefCount() <= 0) { 499db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com // When we aren't reusing textures we know this scratch texture 500db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com // will never be reused and would be just wasting time in the cache 5014db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com fTextureCache->makeNonExclusive(texture->getCacheEntry()); 502db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com fTextureCache->deleteResource(texture->getCacheEntry()); 5034db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com } else { 5044db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // In this case (fDeferredRefCount > 0) but the cache is the only 5054db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // one holding a real ref. Mark the object so when the deferred 5064db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // ref count goes to 0 the texture will be deleted (remember 5074db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // in this code path scratch textures aren't getting reused). 5084db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com texture->setNeedsDeferredUnref(); 509db15c207e361418b4a7ff1aaba06d86d5a8bfdb6robertphillips@google.com } 510afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com} 511afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com 51286b18b1e3c79ba16461d92c16b8480064ee9e085robertphillips@google.com 5139addc0ab3020b8d09fae95afe618bb084c1ee7d6robertphillips@google.comvoid GrContext::unlockScratchTexture(GrTexture* texture) { 51407f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com ASSERT_OWNED_RESOURCE(texture); 515a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL != texture->getCacheEntry()); 51607f394de342c79543c2b4f5c5bf18e86ac6e49b0robertphillips@google.com 5173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // If this is a scratch texture we detached it from the cache 5183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // while it was locked (to avoid two callers simultaneously getting 5193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // the same texture). 52098cf2a50d40d9f9b05ba0ea217d9898af474c856bsalomon@google.com if (texture->getCacheEntry()->key().isScratch()) { 521d91c9eac7cc13869ffa5e93b9862d1d5ccb6587arobertphillips@google.com if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) { 5224db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com fTextureCache->makeNonExclusive(texture->getCacheEntry()); 5234db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com this->purgeCache(); 5244db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com } else if (texture->unique() && texture->getDeferredRefCount() <= 0) { 525431d4b7c59fc3346e603618f6608a445ecdd2482skia.committer@gmail.com // Only the cache now knows about this texture. Since we're never 526431d4b7c59fc3346e603618f6608a445ecdd2482skia.committer@gmail.com // reusing scratch textures (in this code path) it would just be 5274db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // wasting time sitting in the cache. 5284db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com fTextureCache->makeNonExclusive(texture->getCacheEntry()); 5294db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com fTextureCache->deleteResource(texture->getCacheEntry()); 5304db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com } else { 5314db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // In this case (fRefCnt > 1 || defRefCnt > 0) but we don't really 532431d4b7c59fc3346e603618f6608a445ecdd2482skia.committer@gmail.com // want to readd it to the cache (since it will never be reused). 5334db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // Instead, give up the cache's ref and leave the decision up to 5344db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // addExistingTextureToCache once its ref count reaches 0. For 5354db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // this to work we need to leave it in the exclusive list. 5364db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit); 5374db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com // Give up the cache's ref to the texture 5384db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com texture->unref(); 5394db4c5c364a5793f471d2ca15f337f800780e9b4robertphillips@google.com } 5403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 54178eddb84d871e855a878775c1dd0aaf0222bf5eerobertphillips@google.com} 54278eddb84d871e855a878775c1dd0aaf0222bf5eerobertphillips@google.com 54378eddb84d871e855a878775c1dd0aaf0222bf5eerobertphillips@google.comvoid GrContext::purgeCache() { 5447b5b4274da2fcb1e8c56a99e2ae86703f3326fb5robertphillips@google.com if (NULL != fTextureCache) { 5457b5b4274da2fcb1e8c56a99e2ae86703f3326fb5robertphillips@google.com fTextureCache->purgeAsNeeded(); 5467b5b4274da2fcb1e8c56a99e2ae86703f3326fb5robertphillips@google.com } 547afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com} 548afbadf69c0c56d784da42ff7f48759af501d4e59robertphillips@google.com 549dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.orgbool GrContext::OverbudgetCB(void* data) { 550a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL != data); 551dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org 552dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org GrContext* context = reinterpret_cast<GrContext*>(data); 553dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org 554dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org // Flush the InOrderDrawBuffer to possibly free up some textures 55521c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org context->fFlushToReduceCacheSize = true; 556dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org 557dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org return true; 558dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org} 559dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org 560dffc62e413056e2ef063fc94c5c74b1bff486d2dcommit-bot@chromium.org 561c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn, 5623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com void* srcData, 5633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com size_t rowBytes) { 564c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com GrTextureDesc descCopy = descIn; 565c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com return fGpu->createTexture(descCopy, srcData, rowBytes); 5663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 5673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 5689605bac01542206efc8aaf608076a3570f7bfd14bsalomon@google.comvoid GrContext::getTextureCacheLimits(int* maxTextures, 5699605bac01542206efc8aaf608076a3570f7bfd14bsalomon@google.com size_t* maxTextureBytes) const { 5709605bac01542206efc8aaf608076a3570f7bfd14bsalomon@google.com fTextureCache->getLimits(maxTextures, maxTextureBytes); 5713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 5723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 5739605bac01542206efc8aaf608076a3570f7bfd14bsalomon@google.comvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 5749605bac01542206efc8aaf608076a3570f7bfd14bsalomon@google.com fTextureCache->setLimits(maxTextures, maxTextureBytes); 5753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 5763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 5773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comint GrContext::getMaxTextureSize() const { 578b79edfc18351e566f1b395ccb2b9f25bd35bb930robertphillips@google.com return GrMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); 5793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 5803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 5813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 58259831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com return fGpu->caps()->maxRenderTargetSize(); 5833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 5843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 5853c02eaffc61fc15c1d15d8b7ff947a7276c2fcfabsalomon@google.comint GrContext::getMaxSampleCount() const { 58659831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com return fGpu->caps()->maxSampleCount(); 5873c02eaffc61fc15c1d15d8b7ff947a7276c2fcfabsalomon@google.com} 5883c02eaffc61fc15c1d15d8b7ff947a7276c2fcfabsalomon@google.com 5893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 5903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 591cff60e9fc895438fae7733789ef0cd02327ca38dbsalomon@google.comGrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) { 592cff60e9fc895438fae7733789ef0cd02327ca38dbsalomon@google.com return fGpu->wrapBackendTexture(desc); 593015266273f0c3be52f93983d714cb3cd35756b8bbsalomon@google.com} 594015266273f0c3be52f93983d714cb3cd35756b8bbsalomon@google.com 595cff60e9fc895438fae7733789ef0cd02327ca38dbsalomon@google.comGrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { 596cff60e9fc895438fae7733789ef0cd02327ca38dbsalomon@google.com return fGpu->wrapBackendRenderTarget(desc); 597015266273f0c3be52f93983d714cb3cd35756b8bbsalomon@google.com} 598015266273f0c3be52f93983d714cb3cd35756b8bbsalomon@google.com 5993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 6003f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 60120c50f7c5feda26ad659838c4f3824c47aa36903bsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, 6023f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int width, int height) const { 603516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.com const GrDrawTargetCaps* caps = fGpu->caps(); 60459831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com if (!caps->eightBitPaletteSupport()) { 6053f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 6063f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 6073f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 6083f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 6093f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 6103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (!isPow2) { 61120c50f7c5feda26ad659838c4f3824c47aa36903bsalomon@google.com bool tiled = NULL != params && params->isTiled(); 61259831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com if (tiled && !caps->npotTextureTileSupport()) { 6133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 6143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 6153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 6163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return true; 6173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 6183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 6193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 6203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 6213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 622a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.orgvoid GrContext::clear(const SkIRect* rect, 6233bf3da2c23cf17d4711ec6ccb6e9965ae74e7b1dbsalomon@google.com const GrColor color, 624163b5b016e779d13fa2a4aba29c79acd9387c949robertphillips@google.com bool canIgnoreRect, 6251f218673ae464de98d775cfcb4bfd31f8949848brobertphillips@google.com GrRenderTarget* target) { 626860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com AutoRestoreEffects are; 62721c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush acf(this); 6286235b57cdb313411e9e42cbea6c25a858d308455skia.committer@gmail.com this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf)->clear(rect, color, 629163b5b016e779d13fa2a4aba29c79acd9387c949robertphillips@google.com canIgnoreRect, target); 6303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 6313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 632d87737fd8acef6b668aabb5d406bbd63f417ffbbbsalomon@google.comvoid GrContext::drawPaint(const GrPaint& origPaint) { 6333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 6343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // don't overflow fixed-point implementations 635a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org SkRect r; 6363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com r.setLTRB(0, 0, 6373a729be1ae6a0bdfb6a8745f1859e8cb7f23baddbsalomon@google.com SkIntToScalar(getRenderTarget()->width()), 6383a729be1ae6a0bdfb6a8745f1859e8cb7f23baddbsalomon@google.com SkIntToScalar(getRenderTarget()->height())); 639a4e2f5beb2d73243c15ab871f013d2ba29e8fea3bsalomon@google.com SkMatrix inverse; 640d87737fd8acef6b668aabb5d406bbd63f417ffbbbsalomon@google.com SkTCopyOnFirstWrite<GrPaint> paint(origPaint); 6410257ff4808205746950a32a65e03a35e31c987b6robertphillips@google.com AutoMatrix am; 642c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com 6433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 6443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // map the four corners and bound them with a new rect. This will not 6453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // produce a correct result for some perspective matrices. 6463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (!this->getMatrix().hasPerspective()) { 647e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org if (!fViewMatrix.invert(&inverse)) { 6487cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com GrPrintf("Could not invert matrix\n"); 6493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return; 6503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 6513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com inverse.mapRect(&r); 6523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 6534a8cc154cd99f8c03d606d62685a21a9264272a0bsalomon@google.com if (!am.setIdentity(this, paint.writable())) { 6544a8cc154cd99f8c03d606d62685a21a9264272a0bsalomon@google.com GrPrintf("Could not invert matrix\n"); 6554a8cc154cd99f8c03d606d62685a21a9264272a0bsalomon@google.com return; 6563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 6573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 6583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // by definition this fills the entire clip, no need for AA 659d87737fd8acef6b668aabb5d406bbd63f417ffbbbsalomon@google.com if (paint->isAntiAlias()) { 660d87737fd8acef6b668aabb5d406bbd63f417ffbbbsalomon@google.com paint.writable()->setAntiAlias(false); 6613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 662d87737fd8acef6b668aabb5d406bbd63f417ffbbbsalomon@google.com this->drawRect(*paint, r); 6633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 6643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 665f241537f949536383a3eadfc8c14b9a682f64f8ccommit-bot@chromium.org#ifdef SK_DEVELOPER 666f241537f949536383a3eadfc8c14b9a682f64f8ccommit-bot@chromium.orgvoid GrContext::dumpFontCache() const { 667f241537f949536383a3eadfc8c14b9a682f64f8ccommit-bot@chromium.org fFontCache->dump(); 668f241537f949536383a3eadfc8c14b9a682f64f8ccommit-bot@chromium.org} 669f241537f949536383a3eadfc8c14b9a682f64f8ccommit-bot@chromium.org#endif 670f241537f949536383a3eadfc8c14b9a682f64f8ccommit-bot@chromium.org 6713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 6723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 6733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 6743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 6753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 6763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com would be faster. 6773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com */ 678a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.orgstatic void setStrokeRectStrip(GrPoint verts[10], SkRect rect, 6793a729be1ae6a0bdfb6a8745f1859e8cb7f23baddbsalomon@google.com SkScalar width) { 6803a729be1ae6a0bdfb6a8745f1859e8cb7f23baddbsalomon@google.com const SkScalar rad = SkScalarHalf(width); 6813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com rect.sort(); 6823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 6833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 6843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 6853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 6863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 6873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 6883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 6893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 6903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 6913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[8] = verts[0]; 6923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com verts[9] = verts[1]; 6933f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 6943f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 695a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.orgstatic bool isIRect(const SkRect& r) { 6964cdd0d47e79464d82e0c49bffd7635eab633e552skia.committer@gmail.com return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && 6974cdd0d47e79464d82e0c49bffd7635eab633e552skia.committer@gmail.com SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); 6980d4d39654e55999edb3ef20aa4acbe681045d8e5robertphillips@google.com} 6990d4d39654e55999edb3ef20aa4acbe681045d8e5robertphillips@google.com 7003f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 701a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkRect& rect, 7025b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com SkScalar strokeWidth, 7034bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org const SkMatrix& combinedMatrix, 7044bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org SkRect* devBoundRect, 7053f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bool* useVertexCoverage) { 706561a891178a2db336b6bc2e53be8c82ed9e0fdffbsalomon@google.com // we use a simple coverage ramp to do aa on axis-aligned rects 707935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com // we check if the rect will be axis-aligned, and the rect won't land on 708561a891178a2db336b6bc2e53be8c82ed9e0fdffbsalomon@google.com // integer coords. 7093f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 7103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // we are keeping around the "tweak the alpha" trick because 7113f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // it is our only hope for the fixed-pipe implementation. 7123f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // In a shader implementation we can give a separate coverage input 713f9ba6e3339b8414de3674c55d86267212b99b07fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 7143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *useVertexCoverage = false; 715f1a7c7962e72d83a3bf733d2c39571b513b2df32bsalomon@google.com if (!target->getDrawState().canTweakAlphaForCoverage()) { 716f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org if (target->shouldDisableCoverageAAForBlend()) { 7170fde04d1de4773e5168a56dbd455b77e1424434acommit-bot@chromium.org#ifdef SK_DEBUG 718561a891178a2db336b6bc2e53be8c82ed9e0fdffbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 7193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif 7203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 721561a891178a2db336b6bc2e53be8c82ed9e0fdffbsalomon@google.com } else { 722561a891178a2db336b6bc2e53be8c82ed9e0fdffbsalomon@google.com *useVertexCoverage = true; 7233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 7243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 725c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 726c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 7273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 7283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 7293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 7305b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com if (0 == strokeWidth && target->willUseHWAALines()) { 7313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 7323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 7333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 7347867a44b8777a4ce72ab65bdbb0a07bb1a9a7204robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 7355b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com if (strokeWidth >= 0) { 7365b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com#endif 7374bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (!combinedMatrix.preservesAxisAlignment()) { 7385b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com return false; 7395b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com } 7403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 7417867a44b8777a4ce72ab65bdbb0a07bb1a9a7204robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 7425b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com } else { 7434bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (!combinedMatrix.preservesRightAngles()) { 7445b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com return false; 7455b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com } 7463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 7475b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com#endif 7483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 7494bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org combinedMatrix.mapRect(devBoundRect, rect); 7500afcae3e5dc0d8ce456272af0ebf9556e8d4165brobertphillips@google.com 7510d4d39654e55999edb3ef20aa4acbe681045d8e5robertphillips@google.com if (strokeWidth < 0) { 7524bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org return !isIRect(*devBoundRect); 7530d4d39654e55999edb3ef20aa4acbe681045d8e5robertphillips@google.com } else { 7540d4d39654e55999edb3ef20aa4acbe681045d8e5robertphillips@google.com return true; 7550d4d39654e55999edb3ef20aa4acbe681045d8e5robertphillips@google.com } 7563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 7573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 7584bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.orgstatic inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) { 7594bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org return point.fX >= rect.fLeft && point.fX <= rect.fRight && 7604bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org point.fY >= rect.fTop && point.fY <= rect.fBottom; 7614bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org} 7624bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org 7633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 764a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkRect& rect, 7656042c856257ef0bb332f4fa0e7e640660f2183d2commit-bot@chromium.org const SkStrokeRec* stroke, 766a4e2f5beb2d73243c15ab871f013d2ba29e8fea3bsalomon@google.com const SkMatrix* matrix) { 7673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com SK_TRACE_EVENT0("GrContext::drawRect"); 7683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 769860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com AutoRestoreEffects are; 77021c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush acf(this); 77121c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 7723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 7736042c856257ef0bb332f4fa0e7e640660f2183d2commit-bot@chromium.org SkScalar width = stroke == NULL ? -1 : stroke->getWidth(); 7744bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org SkMatrix combinedMatrix = target->drawState()->getViewMatrix(); 7754bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (NULL != matrix) { 7764bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org combinedMatrix.preConcat(*matrix); 7774bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org } 7784bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org 7794bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking 7804bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org // cases where the RT is fully inside a stroke. 7814bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (width < 0) { 7824bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org SkRect rtRect; 7834bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect); 7844bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org SkRect clipSpaceRTRect = rtRect; 7854bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org bool checkClip = false; 7864bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (NULL != this->getClip()) { 7874bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org checkClip = true; 7884bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), 7894bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org SkIntToScalar(this->getClip()->fOrigin.fY)); 7904bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org } 7914bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org // Does the clip contain the entire RT? 7924bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpaceRTRect)) { 7934bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org SkMatrix invM; 7944bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (!combinedMatrix.invert(&invM)) { 7954bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org return; 7964bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org } 7974bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org // Does the rect bound the RT? 7984bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org SkPoint srcSpaceRTQuad[4]; 7994bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org invM.mapRectToQuad(srcSpaceRTQuad, rtRect); 8004bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) && 8014bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[1]) && 8024bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[2]) && 8034bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org rect_contains_inclusive(rect, srcSpaceRTQuad[3])) { 8044bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org // Will it blend? 8054bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org GrColor clearColor; 8064bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org if (paint.isOpaqueAndConstantColor(&clearColor)) { 807163b5b016e779d13fa2a4aba29c79acd9387c949robertphillips@google.com target->clear(NULL, clearColor, true); 8084bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org return; 8094bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org } 8104bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org } 8114bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org } 8124bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org } 8134bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org 8144bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org SkRect devBoundRect; 8153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com bool useVertexCoverage; 8163b8881bd5fb598fafb295c6a5562115873960f5ebsalomon@google.com bool needAA = paint.isAntiAlias() && 817e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org !target->getDrawState().getRenderTarget()->isMultisampled(); 8184bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org bool doAA = needAA && apply_aa_to_rect(target, rect, width, combinedMatrix, &devBoundRect, 819f9ba6e3339b8414de3674c55d86267212b99b07fbsalomon@google.com &useVertexCoverage); 8203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (doAA) { 821fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 822fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 8237cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com return; 8247cb60d6f6638f4f9866af50615b3972fb99f812fbsalomon@google.com } 8253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (width >= 0) { 8266042c856257ef0bb332f4fa0e7e640660f2183d2commit-bot@chromium.org fAARectRenderer->strokeAARect(this->getGpu(), target, rect, 8276042c856257ef0bb332f4fa0e7e640660f2183d2commit-bot@chromium.org combinedMatrix, devBoundRect, 8286042c856257ef0bb332f4fa0e7e640660f2183d2commit-bot@chromium.org stroke, useVertexCoverage); 8293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 8305b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com // filled AA rect 831935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com fAARectRenderer->fillAARect(this->getGpu(), target, 8324bdbb2f0f10b9631e80a19b2b15fa4131cf4d1d9commit-bot@chromium.org rect, combinedMatrix, devBoundRect, 833b94d10665366901ae9fda0c98d75ffbbd71ff8c4robertphillips@google.com useVertexCoverage); 8343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 8353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return; 8363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 8373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 8383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (width >= 0) { 8393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // TODO: consider making static vertex buffers for these cases. 8409b2fd0c3f52229a5618434a4236b96ec4c73dd98bsalomon@google.com // Hairline could be done by just adding closing vertex to 8419b2fd0c3f52229a5618434a4236b96ec4c73dd98bsalomon@google.com // unitSquareVertexBuffer() 8423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 8433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com static const int worstCaseVertCount = 10; 844768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com target->drawState()->setDefaultVertexAttribs(); 8459d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0); 8463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 8473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (!geo.succeeded()) { 8483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 8493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return; 8503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 8513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 8523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrPrimitiveType primType; 8533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int vertCount; 8543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrPoint* vertex = geo.positions(); 8553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 8563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (width > 0) { 8573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com vertCount = 10; 8587de94cd88f290887d0c09549902c9f3890265ff2bsalomon@google.com primType = kTriangleStrip_GrPrimitiveType; 8593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com setStrokeRectStrip(vertex, rect, width); 8603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 8613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // hairline 8623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com vertCount = 5; 8637de94cd88f290887d0c09549902c9f3890265ff2bsalomon@google.com primType = kLineStrip_GrPrimitiveType; 8643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 8653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 8663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 8673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 8683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 8693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 8703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 871c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 8723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != matrix) { 873c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com GrDrawState* drawState = target->drawState(); 87441dcb390a0e517a6f2807b13335def36a0f47802bsalomon@google.com avmr.set(drawState, *matrix); 8753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 8763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 8773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 8783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 8795b0f4b63c1ecef4655e1cef93a2972c8b0743d08robertphillips@google.com // filled BW rect 880ff8ff3003b745ab3d0d9a85a74f45ea007eac838robertphillips@google.com target->drawSimpleRect(rect, matrix); 8813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 8823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 8833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 8843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 885a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkRect& dstRect, 886a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkRect& localRect, 887a4e2f5beb2d73243c15ab871f013d2ba29e8fea3bsalomon@google.com const SkMatrix* dstMatrix, 8888bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com const SkMatrix* localMatrix) { 8893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com SK_TRACE_EVENT0("GrContext::drawRectToRect"); 890860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com AutoRestoreEffects are; 89121c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush acf(this); 89221c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 8939b2fd0c3f52229a5618434a4236b96ec4c73dd98bsalomon@google.com 8948bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com target->drawRect(dstRect, dstMatrix, &localRect, localMatrix); 8953f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 8963f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 897a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comnamespace { 898a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 899a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comextern const GrVertexAttrib gPosUVColorAttribs[] = { 900a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 901a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding }, 90221ecaf9cc8f36e12ec282d88482d03dfb2271703rmistry@google.com {kVec4ub_GrVertexAttribType, 2*sizeof(GrPoint), kColor_GrVertexAttribBinding} 903a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com}; 904a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 905a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comextern const GrVertexAttrib gPosColorAttribs[] = { 906a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 907a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding}, 908a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com}; 909a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 910a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comstatic void set_vertex_attributes(GrDrawState* drawState, 911a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com const GrPoint* texCoords, 912a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com const GrColor* colors, 913a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com int* colorOffset, 914a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com int* texOffset) { 915a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com *texOffset = -1; 916a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com *colorOffset = -1; 917a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 918a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com if (NULL != texCoords && NULL != colors) { 919a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com *texOffset = sizeof(GrPoint); 920a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com *colorOffset = 2*sizeof(GrPoint); 921a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com drawState->setVertexAttribs<gPosUVColorAttribs>(3); 922a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com } else if (NULL != texCoords) { 923a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com *texOffset = sizeof(GrPoint); 924a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com drawState->setVertexAttribs<gPosUVColorAttribs>(2); 925a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com } else if (NULL != colors) { 926a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com *colorOffset = sizeof(GrPoint); 927a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com drawState->setVertexAttribs<gPosColorAttribs>(2); 928a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com } else { 929a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com drawState->setVertexAttribs<gPosColorAttribs>(1); 930a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com } 931a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com} 932a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 933a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com}; 934a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com 9353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 9363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrPrimitiveType primitiveType, 9373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int vertexCount, 9383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrPoint positions[], 9393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrPoint texCoords[], 9403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const GrColor colors[], 9413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com const uint16_t indices[], 9423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com int indexCount) { 9433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com SK_TRACE_EVENT0("GrContext::drawVertices"); 9443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 9453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo; 9463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 947860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com AutoRestoreEffects are; 94821c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush acf(this); 94921c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 9503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 951768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com GrDrawState* drawState = target->drawState(); 952768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com 953768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com int colorOffset = -1, texOffset = -1; 954a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset); 955768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com 956768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com size_t vertexSize = drawState->getVertexSize(); 9573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (sizeof(GrPoint) != vertexSize) { 9589d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com if (!geo.set(target, vertexCount, 0)) { 9593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 9603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return; 9613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 9623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com void* curVertex = geo.vertices(); 9633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 9643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 9653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *((GrPoint*)curVertex) = positions[i]; 9663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 967768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com if (texOffset >= 0) { 968992c29694bbefcf9c987ff1e130551b98801a317jvanverth@google.com *(GrPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; 9693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 970768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com if (colorOffset >= 0) { 9713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 9723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 9733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 9743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 9753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 9769d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com target->setVertexSourceToArray(positions, vertexCount); 9773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 9783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 979935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com // we don't currently apply offscreen AA to this path. Need improved 9803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 9813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 9823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != indices) { 9833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 9843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 985bfed24f7c476f19f4ca358e41901ff3a35872d99bsalomon@google.com target->resetIndexSource(); 9863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 9873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 9883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 9893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 9903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 9913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 9923a51c469906cd04bafd5cabc2bb75edb8e0693febsalomon@google.com 9939f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.orgvoid GrContext::drawRRect(const GrPaint& paint, 9949f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org const SkRRect& rect, 9959f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org const SkStrokeRec& stroke) { 9964d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org if (rect.isEmpty()) { 9974d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org return; 9984d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org } 9999f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org 1000860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com AutoRestoreEffects are; 100121c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush acf(this); 100221c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 10039f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org 1004f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org if (!fOvalRenderer->drawSimpleRRect(target, this, paint.isAntiAlias(), rect, stroke)) { 10059f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org SkPath path; 10069f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org path.addRRect(rect); 1007f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); 10089f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org } 10099f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org} 10109f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org 10119f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 10129f91c15105a642b1e729f8d1ebeac4dc986eb622commit-bot@chromium.org 1013a5914600241e14e421c8eba91e36bc9a22d5d5b8jvanverth@google.comvoid GrContext::drawOval(const GrPaint& paint, 1014a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkRect& oval, 1015a5914600241e14e421c8eba91e36bc9a22d5d5b8jvanverth@google.com const SkStrokeRec& stroke) { 10164d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org if (oval.isEmpty()) { 10174d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org return; 10184d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org } 10193a51c469906cd04bafd5cabc2bb75edb8e0693febsalomon@google.com 1020860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com AutoRestoreEffects are; 102121c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush acf(this); 102221c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 1023a4129bb45afb50fc8aad9b2d6c9da7b89430941ebsalomon@google.com 1024f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke)) { 102551d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org SkPath path; 102651d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org path.addOval(oval); 1027f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); 1028a5914600241e14e421c8eba91e36bc9a22d5d5b8jvanverth@google.com } 102980ce7eb86bc75cc887c99b4792c17d564d782cb6bsalomon@google.com} 10303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1031b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com// Can 'path' be drawn as a pair of filled nested rectangles? 1032b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.comstatic bool is_nested_rects(GrDrawTarget* target, 1033b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com const SkPath& path, 1034b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com const SkStrokeRec& stroke, 1035b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com SkRect rects[2], 1036b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com bool* useVertexCoverage) { 1037b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com SkASSERT(stroke.isFillStyle()); 1038b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 1039b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com if (path.isInverseFillType()) { 1040b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com return false; 1041b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1042b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 1043b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com const GrDrawState& drawState = target->getDrawState(); 1044b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 1045b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com // TODO: this restriction could be lifted if we were willing to apply 1046b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com // the matrix to all the points individually rather than just to the rect 1047b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 1048b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com return false; 1049b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1050b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 1051b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com *useVertexCoverage = false; 1052b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com if (!target->getDrawState().canTweakAlphaForCoverage()) { 1053f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org if (target->shouldDisableCoverageAAForBlend()) { 1054b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com return false; 1055b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } else { 1056b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com *useVertexCoverage = true; 1057b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1058b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1059b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 1060b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com SkPath::Direction dirs[2]; 1061b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com if (!path.isNestedRects(rects, dirs)) { 1062b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com return false; 1063b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1064b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 10650b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { 1066b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com // The two rects need to be wound opposite to each other 10670b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com return false; 1068b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1069b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 10700b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com // Right now, nested rects where the margin is not the same width 10710b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com // all around do not render correctly 10720b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com const SkScalar* outer = rects[0].asScalars(); 10730b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com const SkScalar* inner = rects[1].asScalars(); 10740b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com 10750b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com SkScalar margin = SkScalarAbs(outer[0] - inner[0]); 10760b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com for (int i = 1; i < 4; ++i) { 10770b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com SkScalar temp = SkScalarAbs(outer[i] - inner[i]); 10780b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com if (!SkScalarNearlyEqual(margin, temp)) { 10790b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com return false; 10800b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com } 10810b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com } 10820b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com 10830b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com return true; 10840b92f4e09beacedc4ad101865bed4aabd0f6e88crobertphillips@google.com} 1085b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 10865c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.comvoid GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { 10873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 10883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (path.isEmpty()) { 1089290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com if (path.isInverseFillType()) { 10903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com this->drawPaint(paint); 10913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 10923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return; 10933f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 10943f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 109551d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org // Note that internalDrawPath may sw-rasterize the path into a scratch texture. 109651d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org // Scratch textures can be recycled after they are returned to the texture 109751d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org // cache. This presents a potential hazard for buffered drawing. However, 109851d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org // the writePixels that uploads to the scratch will perform a flush so we're 109951d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org // OK. 1100860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com AutoRestoreEffects are; 110121c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush acf(this); 110221c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf); 1103f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org GrDrawState* drawState = target->drawState(); 110451d94f5635c0744ef6aa4514f0055a88753acfeacommit-bot@chromium.org 1105f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisampled(); 1106f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org 1107f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org if (useCoverageAA && stroke.getWidth() < 0 && !path.isConvex()) { 1108b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com // Concave AA paths are expensive - try to avoid them for special cases 1109b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com bool useVertexCoverage; 1110b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com SkRect rects[2]; 1111b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 1112b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { 1113f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org SkMatrix origViewMatrix = drawState->getViewMatrix(); 1114fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 1115fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com if (!avmr.setIdentity(target->drawState())) { 1116b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com return; 1117b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1118b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 1119b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com fAARectRenderer->fillAANestedRects(this->getGpu(), target, 1120b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com rects, 1121fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com origViewMatrix, 1122b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com useVertexCoverage); 1123b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com return; 1124b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1125b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com } 1126b94fd8fd9094c017ee27e38d8bee059b2f4f0eacrobertphillips@google.com 11273a51c469906cd04bafd5cabc2bb75edb8e0693febsalomon@google.com SkRect ovalRect; 1128a5914600241e14e421c8eba91e36bc9a22d5d5b8jvanverth@google.com bool isOval = path.isOval(&ovalRect); 1129a5914600241e14e421c8eba91e36bc9a22d5d5b8jvanverth@google.com 1130bdc4f21162d69b02261815c20fbc2362f4b24829skia.committer@gmail.com if (!isOval || path.isInverseFillType() 1131f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, stroke)) { 1132f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); 11333a51c469906cd04bafd5cabc2bb75edb8e0693febsalomon@google.com } 11343a51c469906cd04bafd5cabc2bb75edb8e0693febsalomon@google.com} 11353a51c469906cd04bafd5cabc2bb75edb8e0693febsalomon@google.com 11361ec620110f61e46277065ccf1e0bebb87c96a9ffbsalomon@google.comvoid GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, 11371ec620110f61e46277065ccf1e0bebb87c96a9ffbsalomon@google.com const SkStrokeRec& stroke) { 11384d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org SkASSERT(!path.isEmpty()); 11393a51c469906cd04bafd5cabc2bb75edb8e0693febsalomon@google.com 11403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 11413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 11423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 11433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1144f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org bool useCoverageAA = useAA && 1145f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org !target->getDrawState().getRenderTarget()->isMultisampled() && 1146f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org !target->shouldDisableCoverageAAForBlend(); 1147f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org 1148f9ba6e3339b8414de3674c55d86267212b99b07fbsalomon@google.com 1149f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org GrPathRendererChain::DrawType type = 1150f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : 1151f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org GrPathRendererChain::kColor_DrawType; 11520afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com 11531ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com const SkPath* pathPtr = &path; 11541ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com SkPath tmpPath; 11551ec620110f61e46277065ccf1e0bebb87c96a9ffbsalomon@google.com SkStrokeRec strokeRec(stroke); 11561ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com 11571ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com // Try a 1st time without stroking the path and without allowing the SW renderer 11581ec620110f61e46277065ccf1e0bebb87c96a9ffbsalomon@google.com GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, false, type); 11591ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com 11601ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com if (NULL == pr) { 1161f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(strokeRec, this->getMatrix(), NULL)) { 11621ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com // It didn't work the 1st time, so try again with the stroked path 11631ec620110f61e46277065ccf1e0bebb87c96a9ffbsalomon@google.com if (strokeRec.applyToPath(&tmpPath, *pathPtr)) { 11641ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com pathPtr = &tmpPath; 11651ec620110f61e46277065ccf1e0bebb87c96a9ffbsalomon@google.com strokeRec.setFillStyle(); 1166f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org if (pathPtr->isEmpty()) { 1167f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org return; 1168f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org } 11691ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com } 11701ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com } 11714d077f56281afad5309f6b9ff951bb9d0b9f6f72commit-bot@chromium.org 11721ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com // This time, allow SW renderer 11731ec620110f61e46277065ccf1e0bebb87c96a9ffbsalomon@google.com pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type); 11741ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com } 11751ed3d2c87e4cae9bb65b859cbecb35bbd24a6440robertphillips@google.com 11763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL == pr) { 11770fde04d1de4773e5168a56dbd455b77e1424434acommit-bot@chromium.org#ifdef SK_DEBUG 11783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 11793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif 11803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return; 11813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 11823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1183f19fb364a079dea27c6f99e5bb3d18cc0e86aa54commit-bot@chromium.org pr->drawPath(*pathPtr, strokeRec, target, useCoverageAA); 11843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 11853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 11863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 11873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 11883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 11894e5840c041872ee72c11707978edc9e1506b5d6erobertphillips@google.com if (NULL == fDrawBuffer) { 11904e5840c041872ee72c11707978edc9e1506b5d6erobertphillips@google.com return; 11914e5840c041872ee72c11707978edc9e1506b5d6erobertphillips@google.com } 11924e5840c041872ee72c11707978edc9e1506b5d6erobertphillips@google.com 11933f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 11943f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fDrawBuffer->reset(); 11953f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 11960ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawBuffer->flush(); 11973f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 119821c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org fFlushToReduceCacheSize = false; 11993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 12003f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1201281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.combool GrContext::writeTexturePixels(GrTexture* texture, 12024407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com int left, int top, int width, int height, 12034407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com GrPixelConfig config, const void* buffer, size_t rowBytes, 12044407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com uint32_t flags) { 120577e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 1206b5ed4edffdba739303dbe834644333b948ecbff9bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1207b5ed4edffdba739303dbe834644333b948ecbff9bsalomon@google.com 1208281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com if ((kUnpremul_PixelOpsFlag & flags) || !fGpu->canWriteTexturePixels(texture, config)) { 1209281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com if (NULL != texture->asRenderTarget()) { 1210281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return this->writeRenderTargetPixels(texture->asRenderTarget(), 1211281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com left, top, width, height, 1212281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com config, buffer, rowBytes, flags); 1213281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com } else { 1214281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return false; 1215281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com } 121677e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com } 1217281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com 12184407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 12194407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com this->flush(); 12204407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com } 122177e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com 1222281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return fGpu->writeTexturePixels(texture, left, top, width, height, 1223281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com config, buffer, rowBytes); 122477e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com} 122577e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com 12264407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.combool GrContext::readTexturePixels(GrTexture* texture, 12274407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com int left, int top, int width, int height, 12284407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com GrPixelConfig config, void* buffer, size_t rowBytes, 12294407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com uint32_t flags) { 12303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com SK_TRACE_EVENT0("GrContext::readTexturePixels"); 1231b5ed4edffdba739303dbe834644333b948ecbff9bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 12323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 12333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 12343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL != target) { 12354407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com return this->readRenderTargetPixels(target, 12364407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com left, top, width, height, 12374407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com config, buffer, rowBytes, 12384407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com flags); 12393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } else { 1240cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org // TODO: make this more efficient for cases where we're reading the entire 1241cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org // texture, i.e., use GetTexImage() instead 1242cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org 1243cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org // create scratch rendertarget and read from that 1244cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org GrAutoScratchTexture ast; 1245cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org GrTextureDesc desc; 1246cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org desc.fFlags = kRenderTarget_GrTextureFlagBit; 1247cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org desc.fWidth = width; 1248cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org desc.fHeight = height; 1249cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org desc.fConfig = config; 1250cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org desc.fOrigin = kTopLeft_GrSurfaceOrigin; 1251cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org ast.set(this, desc, kExact_ScratchTexMatch); 1252cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org GrTexture* dst = ast.texture(); 1253cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org if (NULL != dst && NULL != (target = dst->asRenderTarget())) { 1254cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org this->copyTexture(texture, target, NULL); 1255cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org return this->readRenderTargetPixels(target, 1256cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org left, top, width, height, 1257cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org config, buffer, rowBytes, 1258cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org flags); 1259cc3cec6384303adf017c40ab1bc169e56fd5fd12commit-bot@chromium.org } 12603b7e9c77d71bd36b87cb847a3df1df05abfcbf26skia.committer@gmail.com 12613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return false; 12623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 12633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 12643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 126503f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com#include "SkConfig8888.h" 126603f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com 126703f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.comnamespace { 126803f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com/** 126903f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 127003f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com * formats are representable as Config8888 and so the function returns false 127103f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com * if the GrPixelConfig has no equivalent Config8888. 127203f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com */ 127303f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.combool grconfig_to_config8888(GrPixelConfig config, 12744407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com bool unpremul, 127503f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com SkCanvas::Config8888* config8888) { 127603f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com switch (config) { 12774407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com case kRGBA_8888_GrPixelConfig: 12784407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com if (unpremul) { 12794407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 12804407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com } else { 12814407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com *config8888 = SkCanvas::kRGBA_Premul_Config8888; 12824407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com } 128303f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com return true; 12844407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com case kBGRA_8888_GrPixelConfig: 12854407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com if (unpremul) { 12864407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 12874407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com } else { 12884407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com *config8888 = SkCanvas::kBGRA_Premul_Config8888; 12894407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com } 129003f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com return true; 129103f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com default: 129203f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com return false; 129303f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com } 129403f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com} 1295f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 1296f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com// It returns a configuration with where the byte position of the R & B components are swapped in 1297f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com// relation to the input config. This should only be called with the result of 1298f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com// grconfig_to_config8888 as it will fail for other configs. 1299f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.comSkCanvas::Config8888 swap_config8888_red_and_blue(SkCanvas::Config8888 config8888) { 1300f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com switch (config8888) { 1301f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com case SkCanvas::kBGRA_Premul_Config8888: 1302f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com return SkCanvas::kRGBA_Premul_Config8888; 1303f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com case SkCanvas::kBGRA_Unpremul_Config8888: 1304f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com return SkCanvas::kRGBA_Unpremul_Config8888; 1305f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com case SkCanvas::kRGBA_Premul_Config8888: 1306f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com return SkCanvas::kBGRA_Premul_Config8888; 1307f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com case SkCanvas::kRGBA_Unpremul_Config8888: 1308f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com return SkCanvas::kBGRA_Unpremul_Config8888; 1309f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com default: 1310f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com GrCrash("Unexpected input"); 1311f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com return SkCanvas::kBGRA_Unpremul_Config8888;; 1312f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1313f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com} 131403f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com} 131503f90e2fd488ab168a1bf336fd15fd85c051d7edbsalomon@google.com 13164407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.combool GrContext::readRenderTargetPixels(GrRenderTarget* target, 13174407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com int left, int top, int width, int height, 1318281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com GrPixelConfig dstConfig, void* buffer, size_t rowBytes, 13194407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com uint32_t flags) { 13203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 1321b5ed4edffdba739303dbe834644333b948ecbff9bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1322b5ed4edffdba739303dbe834644333b948ecbff9bsalomon@google.com 1323935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com if (NULL == target) { 1324e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org target = fRenderTarget.get(); 132500e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com if (NULL == target) { 132600e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com return false; 132700e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com } 132800e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com } 13293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 133077e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 133177e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com this->flush(); 133277e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com } 133300e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com 1334f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul. 133500e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com 1336f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll 1337f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read. 1338f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top, 1339281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com width, height, dstConfig, 134000e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com rowBytes); 1341281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // We ignore the preferred config if it is different than our config unless it is an R/B swap. 1342281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // In that case we'll perform an R and B swap while drawing to a scratch texture of the swapped 1343281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // config. Then we will call readPixels on the scratch with the swapped config. The swaps during 1344281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from 1345281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // dstConfig. 1346281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com GrPixelConfig readConfig = dstConfig; 1347281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com bool swapRAndB = false; 134804ac20b5a0e769102205e2110008ae434c114d22commit-bot@chromium.org if (GrPixelConfigSwapRAndB(dstConfig) == 134904ac20b5a0e769102205e2110008ae434c114d22commit-bot@chromium.org fGpu->preferredReadPixelsConfig(dstConfig, target->config())) { 1350281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com readConfig = GrPixelConfigSwapRAndB(readConfig); 1351281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com swapRAndB = true; 1352281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com } 1353f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 13544407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); 135500e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com 1356281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com if (unpremul && !GrPixelConfigIs8888(dstConfig)) { 1357f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // The unpremul flag is only allowed for these two configs. 1358a82039ac3862b7c487426f6adbb6c78d919bca30bsalomon@google.com return false; 1359a82039ac3862b7c487426f6adbb6c78d919bca30bsalomon@google.com } 1360f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 1361f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // If the src is a texture and we would have to do conversions after read pixels, we instead 1362f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // do the conversions by drawing the src to a scratch texture. If we handle any of the 1363f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // conversions in the draw we set the corresponding bool to false so that we don't reapply it 1364f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // on the read back pixels. 1365f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com GrTexture* src = target->asTexture(); 1366380636dc314147f30124ce172750c0ebab0a1c60bsalomon@google.com GrAutoScratchTexture ast; 1367f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (NULL != src && (swapRAndB || unpremul || flipY)) { 1368f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // Make the scratch a render target because we don't have a robust readTexturePixels as of 1369f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // yet. It calls this function. 1370c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com GrTextureDesc desc; 1371c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit; 1372c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com desc.fWidth = width; 1373c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com desc.fHeight = height; 1374f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com desc.fConfig = readConfig; 1375e86e1ce3df0f3ded2567eabd487d53ad4e6d6692senorblanco@chromium.org desc.fOrigin = kTopLeft_GrSurfaceOrigin; 1376380636dc314147f30124ce172750c0ebab0a1c60bsalomon@google.com 1377281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // When a full read back is faster than a partial we could always make the scratch exactly 1378f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // match the passed rect. However, if we see many different size rectangles we will trash 1379f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // our texture cache and pay the cost of creating and destroying many textures. So, we only 1380f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // request an exact match when the caller is reading an entire RT. 13819646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 13829646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com if (0 == left && 13839646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com 0 == top && 13849646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com target->width() == width && 13859646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com target->height() == height && 13869646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 13879646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com match = kExact_ScratchTexMatch; 13889646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com } 13899646b3b9d9c12a545bbee07a9a9e516f09e4aa49bsalomon@google.com ast.set(this, desc, match); 139000e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com GrTexture* texture = ast.texture(); 1391f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (texture) { 1392d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com // compute a matrix to perform the draw 1393a4e2f5beb2d73243c15ab871f013d2ba29e8fea3bsalomon@google.com SkMatrix textureMatrix; 1394e86e1ce3df0f3ded2567eabd487d53ad4e6d6692senorblanco@chromium.org textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1395d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com textureMatrix.postIDiv(src->width(), src->height()); 1396d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 13974783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com SkAutoTUnref<const GrEffectRef> effect; 1398f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (unpremul) { 13994783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com effect.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix)); 14004783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com if (NULL != effect) { 1401281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com unpremul = false; // we no longer need to do this on CPU after the read back. 1402d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com } 1403f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1404f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // If we failed to create a PM->UPM effect and have no other conversions to perform then 1405f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // there is no longer any point to using the scratch. 14064783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com if (NULL != effect || flipY || swapRAndB) { 14074783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com if (!effect) { 14084783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com effect.reset(GrConfigConversionEffect::Create( 14094783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com src, 14104783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com swapRAndB, 14114783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com GrConfigConversionEffect::kNone_PMConversion, 14124783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com textureMatrix)); 1413f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1414f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com swapRAndB = false; // we will handle the swap in the draw. 1415f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 1416ccc9cf9a1f76a236d9e30725646933afa0b72e57robertphillips@google.com // We protect the existing geometry here since it may not be 1417ccc9cf9a1f76a236d9e30725646933afa0b72e57robertphillips@google.com // clear to the caller that a draw operation (i.e., drawSimpleRect) 1418ccc9cf9a1f76a236d9e30725646933afa0b72e57robertphillips@google.com // can be invoked in this method 1419ccc9cf9a1f76a236d9e30725646933afa0b72e57robertphillips@google.com GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit); 1420f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 1421a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(effect); 1422860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com drawState->addColorEffect(effect); 1423d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 1424f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com drawState->setRenderTarget(texture->asRenderTarget()); 1425a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 1426f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com fGpu->drawSimpleRect(rect, NULL); 1427f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // we want to read back from the scratch's origin 1428f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com left = 0; 1429f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com top = 0; 1430f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com target = texture->asRenderTarget(); 1431f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 143200e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com } 1433f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1434f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (!fGpu->readPixels(target, 1435f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com left, top, width, height, 1436e86e1ce3df0f3ded2567eabd487d53ad4e6d6692senorblanco@chromium.org readConfig, buffer, rowBytes)) { 1437f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com return false; 1438f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1439d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com // Perform any conversions we weren't able to perform using a scratch texture. 1440e86e1ce3df0f3ded2567eabd487d53ad4e6d6692senorblanco@chromium.org if (unpremul || swapRAndB) { 1441fe0f2d69580071c2e42c475b86fb69aa0293b41ebsalomon@google.com // These are initialized to suppress a warning 1442fe0f2d69580071c2e42c475b86fb69aa0293b41ebsalomon@google.com SkCanvas::Config8888 srcC8888 = SkCanvas::kNative_Premul_Config8888; 1443fe0f2d69580071c2e42c475b86fb69aa0293b41ebsalomon@google.com SkCanvas::Config8888 dstC8888 = SkCanvas::kNative_Premul_Config8888; 1444fe0f2d69580071c2e42c475b86fb69aa0293b41ebsalomon@google.com 1445281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com SkDEBUGCODE(bool c8888IsValid =) grconfig_to_config8888(dstConfig, false, &srcC8888); 1446281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com grconfig_to_config8888(dstConfig, unpremul, &dstC8888); 1447fe0f2d69580071c2e42c475b86fb69aa0293b41ebsalomon@google.com 1448f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (swapRAndB) { 1449a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(c8888IsValid); // we should only do r/b swap on 8888 configs 1450f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com srcC8888 = swap_config8888_red_and_blue(srcC8888); 14514407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com } 1452a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(c8888IsValid); 1453e86e1ce3df0f3ded2567eabd487d53ad4e6d6692senorblanco@chromium.org uint32_t* b32 = reinterpret_cast<uint32_t*>(buffer); 1454e86e1ce3df0f3ded2567eabd487d53ad4e6d6692senorblanco@chromium.org SkConvertConfig8888Pixels(b32, rowBytes, dstC8888, 1455e86e1ce3df0f3ded2567eabd487d53ad4e6d6692senorblanco@chromium.org b32, rowBytes, srcC8888, 1456e86e1ce3df0f3ded2567eabd487d53ad4e6d6692senorblanco@chromium.org width, height); 145700e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com } 1458f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com return true; 14593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 14603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1461cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.comvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 1462a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(target); 1463cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1464cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.com // In the future we may track whether there are any pending draws to this 1465cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.com // target. We don't today so we always perform a flush. We don't promise 1466cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.com // this to our clients, though. 1467cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.com this->flush(); 1468cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.com fGpu->resolveRenderTarget(target); 1469cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.com} 1470cbada79e9157c827682b6ea170861d283d2de3a3bsalomon@google.com 14716ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.comvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) { 1472425387cbecc5dc8b806ee66732fb4e4d474116e1senorblanco@chromium.org if (NULL == src || NULL == dst) { 1473425387cbecc5dc8b806ee66732fb4e4d474116e1senorblanco@chromium.org return; 1474425387cbecc5dc8b806ee66732fb4e4d474116e1senorblanco@chromium.org } 1475425387cbecc5dc8b806ee66732fb4e4d474116e1senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1476425387cbecc5dc8b806ee66732fb4e4d474116e1senorblanco@chromium.org 14774857d495bac8680248d0696d3daad8aee79c8b68twiz@google.com // Writes pending to the source texture are not tracked, so a flush 14784857d495bac8680248d0696d3daad8aee79c8b68twiz@google.com // is required to ensure that the copy captures the most recent contents 14794783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com // of the source texture. See similar behavior in 14804857d495bac8680248d0696d3daad8aee79c8b68twiz@google.com // GrContext::resolveRenderTarget. 14814857d495bac8680248d0696d3daad8aee79c8b68twiz@google.com this->flush(); 14824857d495bac8680248d0696d3daad8aee79c8b68twiz@google.com 1483bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 1484c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 1485c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com drawState->setRenderTarget(dst); 1486a4e2f5beb2d73243c15ab871f013d2ba29e8fea3bsalomon@google.com SkMatrix sampleM; 1487425387cbecc5dc8b806ee66732fb4e4d474116e1senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 14886ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); 14896ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com if (NULL != topLeft) { 14906ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com srcRect.offset(*topLeft); 14916ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com } 14926ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height()); 14936ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com if (!srcRect.intersect(srcBounds)) { 14946ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com return; 14956ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com } 14966ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com sampleM.preTranslate(SkIntToScalar(srcRect.fLeft), SkIntToScalar(srcRect.fTop)); 1497860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com drawState->addColorTextureEffect(src, sampleM); 14986ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com SkRect dstR = SkRect::MakeWH(SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); 14996ba1045c1aaf5ffb2a955c4f91f77adce4425548scroggo@google.com fGpu->drawSimpleRect(dstR, NULL); 1500425387cbecc5dc8b806ee66732fb4e4d474116e1senorblanco@chromium.org} 1501425387cbecc5dc8b806ee66732fb4e4d474116e1senorblanco@chromium.org 1502281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.combool GrContext::writeRenderTargetPixels(GrRenderTarget* target, 15034407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com int left, int top, int width, int height, 1504281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com GrPixelConfig srcConfig, 15054407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com const void* buffer, 15064407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com size_t rowBytes, 15074407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com uint32_t flags) { 150877e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 1509b5ed4edffdba739303dbe834644333b948ecbff9bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 151077e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com 1511935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com if (NULL == target) { 1512e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org target = fRenderTarget.get(); 151377e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com if (NULL == target) { 1514281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return false; 151577e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com } 151677e39423f949e61a899e1bbe64b79b0fa8120d96bsalomon@google.com } 15173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1518f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it (e.g. glDrawPixels on 1519f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // desktop GL). 1520f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 1521f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // We will always call some form of writeTexturePixels and we will pass our flags on to it. 1522f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // Thus, we don't perform a flush here since that call will do it (if the kNoFlush flag isn't 1523f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // set.) 15243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 15254407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com // If the RT is also a texture and we don't have to premultiply then take the texture path. 15264407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com // We expect to be at least as fast or faster since it doesn't use an intermediate texture as 15274407645c3f0847754148a2ddc321825a39b8b5bfbsalomon@google.com // we do below. 1528935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 1529a3b4d7b4b4acecdbd4a07d41ce99cea5b07691fbcommit-bot@chromium.org#if !defined(SK_BUILD_FOR_MAC) 1530f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called on a texture 1531f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // attached to an FBO. The FBO still sees the old image. TODO: determine what OS versions and/or 1532f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // HW is affected. 1533281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com if (NULL != target->asTexture() && !(kUnpremul_PixelOpsFlag & flags) && 1534281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com fGpu->canWriteTexturePixels(target->asTexture(), srcConfig)) { 1535281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return this->writeTexturePixels(target->asTexture(), 1536281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com left, top, width, height, 1537281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com srcConfig, buffer, rowBytes, flags); 1538b93d4d5201d643f98709fdaa3efdcb28f475dd6ebsalomon@google.com } 1539b93d4d5201d643f98709fdaa3efdcb28f475dd6ebsalomon@google.com#endif 1540d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 1541281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // We ignore the preferred config unless it is a R/B swap of the src config. In that case 1542281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // we will upload the original src data to a scratch texture but we will spoof it as the swapped 1543281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // config. This scratch will then have R and B swapped. We correct for this by swapping again 1544281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // when drawing the scratch to the dst using a conversion effect. 1545281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com bool swapRAndB = false; 1546281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com GrPixelConfig writeConfig = srcConfig; 154704ac20b5a0e769102205e2110008ae434c114d22commit-bot@chromium.org if (GrPixelConfigSwapRAndB(srcConfig) == 154804ac20b5a0e769102205e2110008ae434c114d22commit-bot@chromium.org fGpu->preferredWritePixelsConfig(srcConfig, target->config())) { 1549281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com writeConfig = GrPixelConfigSwapRAndB(srcConfig); 1550281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com swapRAndB = true; 1551b93d4d5201d643f98709fdaa3efdcb28f475dd6ebsalomon@google.com } 1552b93d4d5201d643f98709fdaa3efdcb28f475dd6ebsalomon@google.com 1553c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com GrTextureDesc desc; 1554c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com desc.fWidth = width; 1555c937ae9bcbf6bdb6fe7f6b4cdb518a684fb5f1barobertphillips@google.com desc.fHeight = height; 1556281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com desc.fConfig = writeConfig; 15573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrAutoScratchTexture ast(this, desc); 15583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com GrTexture* texture = ast.texture(); 15593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL == texture) { 1560281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return false; 15613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1562d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 15634783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com SkAutoTUnref<const GrEffectRef> effect; 1564a4e2f5beb2d73243c15ab871f013d2ba29e8fea3bsalomon@google.com SkMatrix textureMatrix; 1565d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com textureMatrix.setIDiv(texture->width(), texture->height()); 1566d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 1567f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com // allocate a tmp buffer and sw convert the pixels to premul 1568f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); 1569f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 1570f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (kUnpremul_PixelOpsFlag & flags) { 1571281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com if (!GrPixelConfigIs8888(srcConfig)) { 1572281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return false; 1573f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 15744783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com effect.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); 1575281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com // handle the unpremul step on the CPU if we couldn't create an effect to do it. 15764783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com if (NULL == effect) { 1577f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1578cd647ba2f3a71acb66c01e906520a5bec126069ccommit-bot@chromium.org SkDEBUGCODE(bool success = ) 1579281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com grconfig_to_config8888(srcConfig, true, &srcConfig8888); 1580a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(success); 1581cd647ba2f3a71acb66c01e906520a5bec126069ccommit-bot@chromium.org SkDEBUGCODE(success = ) 1582281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com grconfig_to_config8888(srcConfig, false, &dstConfig8888); 1583a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(success); 1584f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 1585f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com tmpPixels.reset(width * height); 1586f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 1587f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com src, rowBytes, srcConfig8888, 1588f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com width, height); 1589f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com buffer = tmpPixels.get(); 1590f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com rowBytes = 4 * width; 1591f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1592f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 15934783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com if (NULL == effect) { 15944783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com effect.reset(GrConfigConversionEffect::Create(texture, 15954783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com swapRAndB, 15964783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com GrConfigConversionEffect::kNone_PMConversion, 15974783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com textureMatrix)); 1598f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1599f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 1600281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com if (!this->writeTexturePixels(texture, 1601281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com 0, 0, width, height, 1602281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com writeConfig, buffer, rowBytes, 1603281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com flags & ~kUnpremul_PixelOpsFlag)) { 1604281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return false; 1605281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com } 16063f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1607ccc9cf9a1f76a236d9e30725646933afa0b72e57robertphillips@google.com // writeRenderTargetPixels can be called in the midst of drawing another 1608f35b0ddb7e95937c441c95d5d36f64a38fa83f7fskia.committer@gmail.com // object (e.g., when uploading a SW path rendering to the gpu while 1609ccc9cf9a1f76a236d9e30725646933afa0b72e57robertphillips@google.com // drawing a rect) so preserve the current geometry. 1610fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com SkMatrix matrix; 1611fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); 1612fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit, &matrix); 1613c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 1614a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(effect); 1615860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com drawState->addColorEffect(effect); 16163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1617c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com drawState->setRenderTarget(target); 16183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1619a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org fGpu->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)), NULL); 1620281391b6ca1b37738dfbcc934db460f88865d709bsalomon@google.com return true; 16213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 16223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 16233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1624860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, 1625860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com BufferedDraw buffered, 162621c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoRestoreEffects* are, 162721c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org AutoCheckFlush* acf) { 1628860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com // All users of this draw state should be freeing up all effects when they're done. 1629860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com // Otherwise effects that own resources may keep those resources alive indefinitely. 1630a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageStages()); 1631860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com 163273631cc5a64283b9ed285b40739abe9b9a039b2absalomon@google.com if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffered) { 1633be6b6c5266305f895cd216e616a823afe7fe621brobertphillips@google.com fDrawBuffer->flush(); 163473631cc5a64283b9ed285b40739abe9b9a039b2absalomon@google.com fLastDrawWasBuffered = kNo_BufferedDraw; 16353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1636e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org ASSERT_OWNED_RESOURCE(fRenderTarget.get()); 16373bf3da2c23cf17d4711ec6ccb6e9965ae74e7b1dbsalomon@google.com if (NULL != paint) { 1638a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL != are); 163921c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org SkASSERT(NULL != acf); 1640860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com are->set(fDrawState); 1641e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); 164230b87f78d62a193a4b6eaf0d90461bd1d8935d59bsalomon@google.com#if GR_DEBUG_PARTIAL_COVERAGE_CHECK 164330b87f78d62a193a4b6eaf0d90461bd1d8935d59bsalomon@google.com if ((paint->hasMask() || 0xff != paint->fCoverage) && 164430b87f78d62a193a4b6eaf0d90461bd1d8935d59bsalomon@google.com !fGpu->canApplyCoverage()) { 164530b87f78d62a193a4b6eaf0d90461bd1d8935d59bsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 164630b87f78d62a193a4b6eaf0d90461bd1d8935d59bsalomon@google.com } 164730b87f78d62a193a4b6eaf0d90461bd1d8935d59bsalomon@google.com#endif 1648e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org } else { 1649fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com fDrawState->reset(fViewMatrix); 1650e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org fDrawState->setRenderTarget(fRenderTarget.get()); 16513bf3da2c23cf17d4711ec6ccb6e9965ae74e7b1dbsalomon@google.com } 1652e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org GrDrawTarget* target; 165373631cc5a64283b9ed285b40739abe9b9a039b2absalomon@google.com if (kYes_BufferedDraw == buffered) { 165473631cc5a64283b9ed285b40739abe9b9a039b2absalomon@google.com fLastDrawWasBuffered = kYes_BufferedDraw; 1655e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org target = fDrawBuffer; 165673631cc5a64283b9ed285b40739abe9b9a039b2absalomon@google.com } else { 1657a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(kNo_BufferedDraw == buffered); 1658e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org fLastDrawWasBuffered = kNo_BufferedDraw; 1659e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org target = fGpu; 16603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1661e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org fDrawState->setState(GrDrawState::kClip_StateBit, NULL != fClip && 1662e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org !fClip->fClipStack->isWideOpen()); 1663e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org target->setClip(fClip); 1664a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(fDrawState == target->drawState()); 1665e1884e6f16a6dd9f457970ffab3887e01f268703commit-bot@chromium.org return target; 16663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 16673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1668a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com/* 1669a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com * This method finds a path renderer that can draw the specified path on 1670a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com * the provided target. 1671935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com * Due to its expense, the software path renderer has split out so it can 1672a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com * can be individually allowed/disallowed via the "allowSW" boolean. 1673a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com */ 167405069ac4dedd2f4b6c10238dbd31400c0fe3a879bsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const SkPath& path, 16755c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com const SkStrokeRec& stroke, 1676111fa9c0003b99e052d665af57b51ff973dcb416bsalomon@google.com const GrDrawTarget* target, 16770afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com bool allowSW, 16780afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com GrPathRendererChain::DrawType drawType, 16790afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com GrPathRendererChain::StencilSupport* stencilSupport) { 16800afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com 16813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com if (NULL == fPathRendererChain) { 16820afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); 16833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com } 1684a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com 1685290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, 1686290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com stroke, 1687a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com target, 16880afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com drawType, 16890afd9ef7f06395f1bbbe9a18d8fcfa181d5f6bb0bsalomon@google.com stencilSupport); 1690a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com 1691a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com if (NULL == pr && allowSW) { 1692a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com if (NULL == fSoftwarePathRenderer) { 16933697dec537a5d9941c5662d1b6c948c921edb5d4tomhudson@google.com fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); 1694a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com } 1695a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com pr = fSoftwarePathRenderer; 1696a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com } 1697a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com 1698a1a88ae20406b1cc7eae3d64bc1788d92eaf3816robertphillips@google.com return pr; 16993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 17003f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 17013f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 17026012533a061b85ff4f42e4ba808624071dcfe01bcommit-bot@chromium.orgbool GrContext::isConfigRenderable(GrPixelConfig config, bool withMSAA) const { 17036012533a061b85ff4f42e4ba808624071dcfe01bcommit-bot@chromium.org return fGpu->caps()->isConfigRenderable(config, withMSAA); 1704e1f4ecccd0cd95301aab293853959a84860d1c56robertphillips@google.com} 1705e1f4ecccd0cd95301aab293853959a84860d1c56robertphillips@google.com 17063f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrContext::setupDrawBuffer() { 1707a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL == fDrawBuffer); 1708a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL == fDrawBufferVBAllocPool); 1709a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(NULL == fDrawBufferIBAllocPool); 17103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 17113f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fDrawBufferVBAllocPool = 17123697dec537a5d9941c5662d1b6c948c921edb5d4tomhudson@google.com SkNEW_ARGS(GrVertexBufferAllocPool, (fGpu, false, 17133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 17143697dec537a5d9941c5662d1b6c948c921edb5d4tomhudson@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)); 17153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com fDrawBufferIBAllocPool = 17163697dec537a5d9941c5662d1b6c948c921edb5d4tomhudson@google.com SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu, false, 17173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 17183697dec537a5d9941c5662d1b6c948c921edb5d4tomhudson@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)); 17193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 17203697dec537a5d9941c5662d1b6c948c921edb5d4tomhudson@google.com fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu, 17210ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawBufferVBAllocPool, 17220ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawBufferIBAllocPool)); 1723ec04ec0e334f46f82393827204a431667b8a0368bsalomon@google.com 17240ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com fDrawBuffer->setDrawState(fDrawState); 17253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 17263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1727c9f13ee9268ca0bc11d617b69a03e65582eb8210bsalomon@google.comGrDrawTarget* GrContext::getTextTarget() { 172821c4256a8eccc702d1c4b561da1a3a3e212d3c23commit-bot@chromium.org return this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL); 17293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 17303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 17313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 17323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com return fGpu->getQuadIndexBuffer(); 17333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com} 17343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com 1735f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.comnamespace { 1736f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.comvoid test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { 1737f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com GrConfigConversionEffect::PMConversion pmToUPM; 1738f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com GrConfigConversionEffect::PMConversion upmToPM; 1739f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM); 1740f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com *pmToUPMValue = pmToUPM; 1741f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com *upmToPMValue = upmToPM; 1742f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com} 1743f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com} 1744f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 17454783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.comconst GrEffectRef* GrContext::createPMToUPMEffect(GrTexture* texture, 17464783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com bool swapRAndB, 17474783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com const SkMatrix& matrix) { 1748f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (!fDidTestPMConversions) { 1749f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 1750c18a64e62fa6d9519f435315d682c3f2c4210820bsalomon@google.com fDidTestPMConversions = true; 1751f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1752f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com GrConfigConversionEffect::PMConversion pmToUPM = 1753f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); 1754f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { 17554783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix); 1756f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } else { 17574783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com return NULL; 1758f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1759f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com} 1760f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 17614783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.comconst GrEffectRef* GrContext::createUPMToPMEffect(GrTexture* texture, 17624783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com bool swapRAndB, 17634783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com const SkMatrix& matrix) { 1764f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (!fDidTestPMConversions) { 1765f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 1766c18a64e62fa6d9519f435315d682c3f2c4210820bsalomon@google.com fDidTestPMConversions = true; 1767f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1768f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com GrConfigConversionEffect::PMConversion upmToPM = 1769f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); 1770f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { 17714783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix); 1772f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } else { 17734783fbd25c350b0ea9fc02264b4b1a291c5988ebbsalomon@google.com return NULL; 1774f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com } 1775f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com} 1776f71764d3272e28817cb5025d2b503aa0170ef9b8bsalomon@google.com 177709af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.orgGrPath* GrContext::createPath(const SkPath& inPath, const SkStrokeRec& stroke) { 177809af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org SkASSERT(fGpu->caps()->pathRenderingSupport()); 177909af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org 178009af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org // TODO: now we add to fTextureCache. This should change to fResourceCache. 178109af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org GrResourceKey resourceKey = GrPath::ComputeKey(inPath, stroke); 178209af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org GrPath* path = static_cast<GrPath*>(fTextureCache->find(resourceKey)); 178309af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org if (NULL != path && path->isEqualTo(inPath, stroke)) { 178409af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org path->ref(); 178509af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org } else { 178609af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org path = fGpu->createPath(inPath, stroke); 178709af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org fTextureCache->purgeAsNeeded(1, path->sizeInBytes()); 178809af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org fTextureCache->addResource(resourceKey, path); 178909af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org } 179009af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org return path; 179109af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org} 179209af991708bb73d5e1c8bff9c1e7f8423bde09ddcommit-bot@chromium.org 179300e32ee9f771bd4d9cd04e4c76e6f5f59b26a4dfbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 17943592f532d77bedf33bdc7486c155acfb41c774e5robertphillips@google.com#if GR_CACHE_STATS 17953e52c155a99bba22fb3641e6181e65623cabd43drobertphillips@google.comvoid GrContext::printCacheStats() const { 17963e52c155a99bba22fb3641e6181e65623cabd43drobertphillips@google.com fTextureCache->printStats(); 17973e52c155a99bba22fb3641e6181e65623cabd43drobertphillips@google.com} 17983e52c155a99bba22fb3641e6181e65623cabd43drobertphillips@google.com#endif 1799