GrContext.cpp revision a0a66c118392fdc6f84f18ac634473468e31becb
127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com#include "GrContext.h" 111fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com 12b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com#include "effects/GrMorphologyEffect.h" 13b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com#include "effects/GrConvolutionEffect.h" 14b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com 15278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrBufferAllocPool.h" 16278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrClipIterator.h" 1705ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com#include "GrGpu.h" 1827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrIndexBuffer.h" 1927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrInOrderDrawBuffer.h" 2027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h" 21d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h" 2250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#include "GrResourceCache.h" 2372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com#include "GrSoftwarePathRenderer.h" 24558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com#include "GrStencilBuffer.h" 25278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrTextStrike.h" 268c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com#include "SkTLazy.h" 27c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com#include "SkTLS.h" 280c8d93a94099dee2dff8da6000ded9ad59676488tomhudson@google.com#include "SkTrace.h" 2927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 303c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#define DEFER_TEXT_RENDERING 1 3127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 323c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#define DEFER_PATHS 1 33fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com 343c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB) 3527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 363b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org#define MAX_BLUR_SIGMA 4.0f 373b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 38d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// When we're using coverage AA but the blend is incompatible (given gpu 39d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// limitations) should we disable AA or draw wrong? 40950d7a8d8def14efc98d12d6947347fde351b737bsalomon@google.com#define DISABLE_COVERAGE_AA_FOR_BLEND 1 41d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 424b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#if GR_DEBUG 434b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com // change this to a 1 to see notifications when partial coverage fails 444b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 454b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#else 464b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 474b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#endif 484b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com 498f7e1dac5c92bf1f53feb603a9bd249d53afa81absalomon@google.comstatic const size_t kDefaultTextureCacheBudget = 16 * 1024 * 1024; 5027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5160361493548d5259d0a8afae84274c2a3c31dcacbsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; 5227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 5327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 54fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com// path rendering is the only thing we defer today that uses non-static indices 55fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = DEFER_PATHS ? 1 << 11 : 0; 56fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = DEFER_PATHS ? 4 : 0; 5727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 58bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this) 59bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 6005ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comGrContext* GrContext::Create(GrEngine engine, 6105ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com GrPlatform3DContext context3D) { 6227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrContext* ctx = NULL; 6327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrGpu* fGpu = GrGpu::Create(engine, context3D); 6427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != fGpu) { 6527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ctx = new GrContext(fGpu); 6627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->unref(); 6727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 6827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return ctx; 6927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 7027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 71c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.comnamespace { 72c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.comvoid* CreateThreadInstanceCount() { 73c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com return new int(0); 74c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 75c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.comvoid DeleteThreadInstanceCount(void* v) { 76c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com delete reinterpret_cast<int*>(v); 77c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 78c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com#define THREAD_INSTANCE_COUNT \ 79c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com (*reinterpret_cast<int*>(SkTLS::Get(CreateThreadInstanceCount, \ 80c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com DeleteThreadInstanceCount))) 81c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 82c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 83c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 84c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.comint GrContext::GetThreadInstanceCount() { 85c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com return THREAD_INSTANCE_COUNT; 86c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 87c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 8827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() { 898fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 905acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 915acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // Since the gpu can hold scratch textures, give it a chance to let go 925acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // of them before freeing the texture cache 935acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com fGpu->purgeResources(); 945acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 9527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fTextureCache; 9627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fFontCache; 9727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBuffer; 9827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBufferVBAllocPool; 99de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com delete fDrawBufferIBAllocPool; 1003008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 101f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->unref(); 102f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 103205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->unref(); 1043008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeUnref(fPathRendererChain); 10572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrSafeUnref(fSoftwarePathRenderer); 10610e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->unref(); 107c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 108c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com --THREAD_INSTANCE_COUNT; 10927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 11027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1118fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::contextLost() { 11253a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com contextDestroyed(); 11353a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com this->setupDrawBuffer(); 11453a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com} 11553a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com 11653a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.comvoid GrContext::contextDestroyed() { 117205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // abandon first to so destructors 118205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // don't try to free the resources in the API. 119205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->abandonResources(); 120205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1213008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources that 1223008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // are now unusable 1233008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeSetNull(fPathRendererChain); 12472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrSafeSetNull(fSoftwarePathRenderer); 1253008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1268fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBuffer; 1278fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 128205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1298fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferVBAllocPool; 1308fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 131205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1328fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferIBAllocPool; 1338fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 1348fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 135f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->reset(); 136205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1378fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTextureCache->removeAll(); 1388fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 1398fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1408fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1418fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1428fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::resetContext() { 1438fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1448fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1458fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1468fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() { 1478fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 148ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com 149ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com fGpu->purgeResources(); 150ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com 151f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->reset(); 152f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 1538fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTextureCache->removeAll(); 1548fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 1553008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources 1563008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeSetNull(fPathRendererChain); 15772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrSafeSetNull(fSoftwarePathRenderer); 15827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 15927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 16005e70247c31ae927074ef27ea9893634a8dda543twiz@google.comsize_t GrContext::getGpuTextureCacheBytes() const { 16105e70247c31ae927074ef27ea9893634a8dda543twiz@google.com return fTextureCache->getCachedResourceBytes(); 16205e70247c31ae927074ef27ea9893634a8dda543twiz@google.com} 16305e70247c31ae927074ef27ea9893634a8dda543twiz@google.com 164fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 165fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 16626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.comint GrContext::PaintStageVertexLayoutBits( 16726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com const GrPaint& paint, 16826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com const bool hasTexCoords[GrPaint::kTotalStages]) { 16926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 17026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int layout = 0; 17126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kTotalStages; ++i) { 17226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if ((1 << i) & stageMask) { 17326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (NULL != hasTexCoords && hasTexCoords[i]) { 17426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(i, i); 17526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } else { 17626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i); 17726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 17826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 17926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 18026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com return layout; 18126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com} 18226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 18326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 18426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 18526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 18650398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrTexture* GrContext::TextureCacheEntry::texture() const { 18750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == fEntry) { 18850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return NULL; 18950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } else { 19050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return (GrTexture*) fEntry->resource(); 19150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 19250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 19350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 19450398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace { 195558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 196558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// we should never have more than one stencil buffer with same combo of 197558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// (width,height,samplecount) 198558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(int width, int height, 199558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt, uint32_t v[4]) { 200558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[0] = width; 201558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[1] = height; 202558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[2] = sampleCnt; 203a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com v[3] = GrResourceKey::kStencilBuffer_TypeBit; 204558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 205558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 206558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(const GrStencilBuffer* sb, 207558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]) { 208558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb->width(), sb->height(), 209558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com sb->numSamples(), v); 210558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 21182c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 2123b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgvoid scale_rect(SkRect* rect, float xScale, float yScale) { 2135af56069010b33562d337a4f76543d898ca8d485robertphillips@google.com rect->fLeft = SkScalarMul(rect->fLeft, SkFloatToScalar(xScale)); 2145af56069010b33562d337a4f76543d898ca8d485robertphillips@google.com rect->fTop = SkScalarMul(rect->fTop, SkFloatToScalar(yScale)); 2155af56069010b33562d337a4f76543d898ca8d485robertphillips@google.com rect->fRight = SkScalarMul(rect->fRight, SkFloatToScalar(xScale)); 2165af56069010b33562d337a4f76543d898ca8d485robertphillips@google.com rect->fBottom = SkScalarMul(rect->fBottom, SkFloatToScalar(yScale)); 2173b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2183b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 219b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.comfloat adjust_sigma(float sigma, int *scaleFactor, int *radius) { 2203b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org *scaleFactor = 1; 2213b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org while (sigma > MAX_BLUR_SIGMA) { 2223b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org *scaleFactor *= 2; 2233b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sigma *= 0.5f; 2243b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 225b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com *radius = static_cast<int>(ceilf(sigma * 3.0f)); 226b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius); 2273b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org return sigma; 2283b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2293b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 2303b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgvoid apply_morphology(GrGpu* gpu, 2313b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* texture, 2323b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const SkRect& rect, 2333b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org int radius, 234b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com GrContext::MorphologyType morphType, 235b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::Direction direction) { 2363b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 237873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrRenderTarget* target = gpu->drawState()->getRenderTarget(); 238873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit); 2393b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrDrawState* drawState = gpu->drawState(); 2403b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setRenderTarget(target); 2413b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrMatrix sampleM; 2423b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 243b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com drawState->sampler(0)->reset(sampleM); 244b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com SkAutoTUnref<GrCustomStage> morph( 245b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com new GrMorphologyEffect(direction, radius, morphType)); 246b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com drawState->sampler(0)->setCustomStage(morph); 2473b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setTexture(0, texture); 2483b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org gpu->drawSimpleRect(rect, NULL, 1 << 0); 2493b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2503b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 251b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.comvoid convolve_gaussian(GrGpu* gpu, 252b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com GrTexture* texture, 253b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com const SkRect& rect, 254b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com float sigma, 255b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com int radius, 256b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::Direction direction) { 257873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrRenderTarget* target = gpu->drawState()->getRenderTarget(); 258873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit); 2593b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrDrawState* drawState = gpu->drawState(); 2603b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setRenderTarget(target); 2613b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrMatrix sampleM; 2623b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 263b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com drawState->sampler(0)->reset(sampleM); 264b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com SkAutoTUnref<GrConvolutionEffect> conv(new 265b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com GrConvolutionEffect(direction, radius)); 266b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com conv->setGaussianKernel(sigma); 267b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com drawState->sampler(0)->setCustomStage(conv); 2683b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setTexture(0, texture); 2693b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org gpu->drawSimpleRect(rect, NULL, 1 << 0); 2703b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2713b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 272fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com} 273fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 2741fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::findAndLockTexture( 275a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com const GrTextureDesc& desc, 2761fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler) { 27775b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, sampler, desc, false); 278558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return TextureCacheEntry(fTextureCache->findAndLock(resourceKey, 279558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType)); 280558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 281558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 28275b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.combool GrContext::isTextureInCache(const GrTextureDesc& desc, 2831fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler) const { 28475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, sampler, desc, false); 285fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com return fTextureCache->hasKey(resourceKey); 286fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com} 287fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com 288558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) { 289bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sb); 290558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 291558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb, v); 292558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 293558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return fTextureCache->createAndLock(resourceKey, sb); 294558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 295558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 296558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 297558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt) { 298558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 299558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(width, height, sampleCnt, v); 300558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 301558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey, 302558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kSingle_LockType); 303558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com if (NULL != entry) { 304558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource(); 305558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return sb; 306558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } else { 307558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return NULL; 308558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } 309558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 310558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 311558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) { 312bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sbEntry->resource()); 313558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com fTextureCache->unlock(sbEntry); 31427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 31527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 31627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic void stretchImage(void* dst, 31727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstW, 31827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstH, 31927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* src, 32027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcW, 32127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcH, 32227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int bpp) { 32327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dx = (srcW << 16) / dstW; 32427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dy = (srcH << 16) / dstH; 32527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 32627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed y = dy >> 1; 32727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 32827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstXLimit = dstW*bpp; 32927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int j = 0; j < dstH; ++j) { 33027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed x = dx >> 1; 33127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 33227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* dstRow = (uint8_t*)dst + j*dstW*bpp; 33327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < dstXLimit; i += bpp) { 33427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com memcpy((uint8_t*) dstRow + i, 33527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com (uint8_t*) srcRow + (x>>16)*bpp, 33627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bpp); 33727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com x += dx; 33827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 33927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com y += dy; 34027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 34127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 34227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3431fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::createAndLockTexture( 3441fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler, 3451fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrTextureDesc& desc, 3461fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com void* srcData, 3471fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com size_t rowBytes) { 348278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::createAndLockTexture"); 34927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 35027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_DUMP_TEXTURE_UPLOAD 35127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight); 35227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 35327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 35450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com TextureCacheEntry entry; 35550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 35675b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, sampler, 357a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com desc, false); 358a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com 359a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com if (GrTexture::NeedsResizing(resourceKey)) { 360a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com // The desired texture is NPOT and tiled but that isn't supported by 361a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com // the current hardware. Resize the texture to be a POT 3621fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com GrAssert(NULL != sampler); 36375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com TextureCacheEntry clampEntry = this->findAndLockTexture(desc, 3641fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com NULL); 36527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 36650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 36775b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com clampEntry = this->createAndLockTexture(NULL, desc, 3681fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com srcData, rowBytes); 36950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL != clampEntry.texture()); 37050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 37150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return entry; 37227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 37327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 374fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com GrTextureDesc rtDesc = desc; 375fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = rtDesc.fFlags | 376fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kRenderTarget_GrTextureFlagBit | 377fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kNoStencil_GrTextureFlagBit; 3789962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fWidth = GrNextPow2(GrMax(desc.fWidth, 64)); 3799962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64)); 38027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 38127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 38227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 38327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 384873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, 385873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::kReset_ASRInit); 3868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 3878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(texture->asRenderTarget()); 3888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, clampEntry.texture()); 38982c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 3906aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com GrSamplerState::Filter filter; 3916aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // if filtering is not desired then we want to ensure all 3926aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // texels in the resampled image are copies of texels from 3936aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // the original. 394a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com if (GrTexture::NeedsFiltering(resourceKey)) { 3956aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::kBilinear_Filter; 396a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com } else { 397a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com filter = GrSamplerState::kNearest_Filter; 3986aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } 3991e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 4001e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com filter); 40127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 40227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const GrVertexLayout layout = 40327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); 40427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0); 40527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 40627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (arg.succeeded()) { 40727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* verts = (GrPoint*) arg.vertices(); 40827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].setIRectFan(0, 0, 40927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->width(), 41027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->height(), 41127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2*sizeof(GrPoint)); 41227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); 41347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 41427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 4); 41550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 41627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 4171da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com texture->releaseRenderTarget(); 41827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 41927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: Our CPU stretch doesn't filter. But we create separate 42027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // stretched textures when the sampler state is either filtered or 42127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // not. Either implement filtered stretch blit on CPU or just create 42227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // one when FBO case fails. 42327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 424fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = kNone_GrTextureFlags; 42527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // no longer need to clamp at min RT size. 42627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth = GrNextPow2(desc.fWidth); 42727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight = GrNextPow2(desc.fHeight); 42864c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com int bpp = GrBytesPerPixel(desc.fConfig); 4293582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com SkAutoSMalloc<128*128*4> stretchedPixels(bpp * 43027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth * 43127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight); 43227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 43327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcData, desc.fWidth, desc.fHeight, bpp); 43427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 43527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t stretchedRowBytes = rtDesc.fWidth * bpp; 43627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 43727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, 43827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedPixels.get(), 43927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedRowBytes); 44027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrAssert(NULL != texture); 44150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 44227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 44350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(clampEntry.cacheEntry()); 44427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 44527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 44627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes); 44727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 44850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 44927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 45027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 45127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return entry; 45227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 45327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 45450398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrContext::TextureCacheEntry GrContext::lockScratchTexture( 45550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrTextureDesc& inDesc, 45650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com ScratchTexMatch match) { 457b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTextureDesc desc = inDesc; 45875b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fClientCacheID = kScratch_CacheID; 45975b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com 46050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (kExact_ScratchTexMatch != match) { 46150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // bin by pow2 with a reasonable min 46250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com static const int MIN_SIZE = 256; 46350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 46450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 46550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 466b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 46750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceEntry* entry; 468b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origWidth = desc.fWidth; 469b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origHeight = desc.fHeight; 470b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledW = false; 471b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledH = false; 472b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 473b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com do { 47475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, desc, true); 475558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com entry = fTextureCache->findAndLock(key, 476558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType); 477b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // if we miss, relax the fit of the flags... 478b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // then try doubling width... then height. 47950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL != entry || kExact_ScratchTexMatch == match) { 480b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 481b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 482b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (!(desc.fFlags & kRenderTarget_GrTextureFlagBit)) { 483b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags | kRenderTarget_GrTextureFlagBit; 484b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 485b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 486b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledW) { 487b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 488b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth *= 2; 489b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledW = true; 490b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledH) { 491b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 492b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 493b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight *= 2; 494b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledH = true; 495b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else { 496b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 497b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 498b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 499b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } while (true); 500b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 501b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL == entry) { 502b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 503b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 504b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight = origHeight; 505b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, NULL, 0); 506b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != texture) { 50775b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, 508a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com texture->desc(), 509a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com true); 510b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com entry = fTextureCache->createAndLock(key, texture); 511b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 512b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 513b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 514b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // If the caller gives us the same desc/sampler twice we don't want 515b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // to return the same texture the second time (unless it was previously 516b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // released). So we detach the entry from the cache and reattach at release. 517b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != entry) { 518b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com fTextureCache->detach(entry); 519b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 52050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return TextureCacheEntry(entry); 521b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com} 522b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 52315c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.comvoid GrContext::addExistingTextureToCache(GrTexture* texture) { 52415c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 52515c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com if (NULL == texture) { 52615c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com return; 52715c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com } 52815c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 52915c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, 53015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com texture->desc(), 53115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com true); 53215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com fTextureCache->attach(key, texture); 53315c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com} 53415c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 53550398bf7f1953e640e5529616e710cf540799731bsalomon@google.comvoid GrContext::unlockTexture(TextureCacheEntry entry) { 536bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(entry.texture()); 53750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // If this is a scratch texture we detached it from the cache 53850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // while it was locked (to avoid two callers simultaneously getting 53950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // the same texture). 540a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com if (GrTexture::IsScratchTexture(entry.cacheEntry()->key())) { 54150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->reattachAndUnlock(entry.cacheEntry()); 542fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } else { 54350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(entry.cacheEntry()); 544fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 54527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 54627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 54715c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.comvoid GrContext::freeEntry(TextureCacheEntry entry) { 54815c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com ASSERT_OWNED_RESOURCE(entry.texture()); 54915c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 55015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com fTextureCache->freeEntry(entry.cacheEntry()); 55115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com} 55215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 55375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn, 55427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcData, 55527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t rowBytes) { 55675b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc descCopy = descIn; 55775b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com descCopy.fClientCacheID = kUncached_CacheID; 55875b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com return fGpu->createTexture(descCopy, srcData, rowBytes); 55927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 56027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5618f7e1dac5c92bf1f53feb603a9bd249d53afa81absalomon@google.comsize_t GrContext::getTextureCacheBudget() const { 5628f7e1dac5c92bf1f53feb603a9bd249d53afa81absalomon@google.com return fTextureCache->getBudget(); 56327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 56427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5658f7e1dac5c92bf1f53feb603a9bd249d53afa81absalomon@google.comvoid GrContext::setTextureCacheBudget(size_t maxTextureBytes) { 5668f7e1dac5c92bf1f53feb603a9bd249d53afa81absalomon@google.com fTextureCache->setBudget(maxTextureBytes); 56727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 56827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 569919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const { 57018c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxTextureSize; 571919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 572919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 573919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 57418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxRenderTargetSize; 57527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 57627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 57727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 57827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 579e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) { 580e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformTexture(desc); 581e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 582e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 583e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) { 584e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformRenderTarget(desc); 585e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 586e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 5875877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 5885877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com 5891fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrSamplerState* sampler, 5901f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com int width, int height) const { 59118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com const GrDrawTarget::Caps& caps = fGpu->getCaps(); 59218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!caps.f8BitPaletteSupport) { 59327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 59427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 59527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 59627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 59727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 59827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!isPow2) { 5991fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com bool tiled = NULL != sampler && 6001fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com (sampler->getWrapX() != GrSamplerState::kClamp_WrapMode || 6011fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com sampler->getWrapY() != GrSamplerState::kClamp_WrapMode); 60218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (tiled && !caps.fNPOTTextureTileSupport) { 60327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 60427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 60527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 60627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return true; 60727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 60827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 60927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 61027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 61105ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrClip& GrContext::getClip() const { return fGpu->getClip(); } 61205ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com 61327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrClip& clip) { 61427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->setClip(clip); 61510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->enableState(GrDrawState::kClip_StateBit); 61627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 61727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 61827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrIRect& rect) { 61927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrClip clip; 620d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com clip.setFromIRect(rect); 62127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->setClip(clip); 62227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 62327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 62427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 62527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 626c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.comvoid GrContext::clear(const GrIRect* rect, 627c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com const GrColor color, 628c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com GrRenderTarget* target) { 629398109cc3e56b8122ad21c4d43a74a83be5b42a8bsalomon@google.com this->flush(); 630c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com fGpu->clear(rect, color, target); 63127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 63227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 63327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawPaint(const GrPaint& paint) { 63427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 63527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // don't overflow fixed-point implementations 636d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrRect r; 637d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com r.setLTRB(0, 0, 638d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->width()), 639d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->height())); 64027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix inverse; 6418c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com SkTLazy<GrPaint> tmpPaint; 6428c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com const GrPaint* p = &paint; 6438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrAutoMatrix am; 6448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6454f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 6464f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // map the four corners and bound them with a new rect. This will not 6474f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // produce a correct result for some perspective matrices. 6488c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!this->getMatrix().hasPerspective()) { 64910e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com if (!fDrawState->getViewInverse(&inverse)) { 6508c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrPrintf("Could not invert matrix"); 6518c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6528c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 65327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com inverse.mapRect(&r); 65427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 6558c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) { 65610e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com if (!fDrawState->getViewInverse(&inverse)) { 6578c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrPrintf("Could not invert matrix"); 6588c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6598c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6608c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 6618c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->preConcatActiveSamplerMatrices(inverse); 6628c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 6638c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6644f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com am.set(this, GrMatrix::I()); 66527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 6664f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // by definition this fills the entire clip, no need for AA 6674f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com if (paint.fAntiAlias) { 6688c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!tmpPaint.isValid()) { 6698c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 6708c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 6718c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6728c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrAssert(p == tmpPaint.get()); 6738c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->fAntiAlias = false; 6744f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com } 6754f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com this->drawRect(*p, r); 67627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 67727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 678205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 679205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 680d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.comnamespace { 681d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.cominline bool disable_coverage_aa_for_blend(GrDrawTarget* target) { 682d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage(); 683d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 684d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 685d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 68606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 68706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 68827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 68927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 69027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 69127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster. 69227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 693205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect, 69427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width) { 69527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrScalar rad = GrScalarHalf(width); 696205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com rect.sort(); 69727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 69827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 69927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 70027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 70127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 70227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 70327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 70427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 70527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 70627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[8] = verts[0]; 70727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[9] = verts[1]; 70827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 70927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 71020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com/** 71120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Returns true if the rects edges are integer-aligned. 71220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 71320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.comstatic bool isIRect(const GrRect& r) { 71420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && 71520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom); 71620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com} 71720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 718205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 719205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& rect, 720205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar width, 721205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrMatrix* matrix, 722205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix* combinedMatrix, 723a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrRect* devRect, 724a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool* useVertexCoverage) { 7252eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we use a simple coverage ramp to do aa on axis-aligned rects 7262eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we check if the rect will be axis-aligned, and the rect won't land on 7272eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // integer coords. 728d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 729a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // we are keeping around the "tweak the alpha" trick because 730a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // it is our only hope for the fixed-pipe implementation. 731a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // In a shader implementation we can give a separate coverage input 732289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 733a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = false; 734d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (!target->canTweakAlphaForCoverage()) { 7352eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 7361983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 7372eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 7381983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 739a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 7402eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com } else { 7412eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com *useVertexCoverage = true; 742a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 743205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 7448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 7458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 746205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 747205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 748205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 749471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com if (0 == width && target->willUseHWAALines()) { 750205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 751205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 752205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 754205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 755205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 756205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 757205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix && 758205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com !matrix->preservesAxisAlignment()) { 759205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 760205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 761205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com *combinedMatrix = drawState.getViewMatrix(); 763205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix) { 764205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->preConcat(*matrix); 765205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrAssert(combinedMatrix->preservesAxisAlignment()); 766205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 767205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 768205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->mapRect(devRect, rect); 769205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com devRect->sort(); 770205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 771205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width < 0) { 77220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return !isIRect(*devRect); 773205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 774205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return true; 775205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 776205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 777205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 77827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 77927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& rect, 78027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width, 78127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* matrix) { 782278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRect"); 78327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 78427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 785972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com GrDrawState::AutoTextureRelease atr(fDrawState); 78626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 78727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 788205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect devRect = rect; 789205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix combinedMatrix; 790a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage; 791289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool needAA = paint.fAntiAlias && 792289533ada623f2238a83771eec977f204f75994fbsalomon@google.com !this->getRenderTarget()->isMultisampled(); 793289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 794289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &combinedMatrix, &devRect, 795289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &useVertexCoverage); 796205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 797205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 7988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 799205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 800205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrVec strokeSize;; 801205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width > 0) { 802205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(width, width); 803cc4dac3dac215dc0dd56f7b30d07cc304671b033bsalomon@google.com combinedMatrix.mapVectors(&strokeSize, 1); 804205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.setAbs(strokeSize); 805205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 806205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(GR_Scalar1, GR_Scalar1); 807205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 808f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->strokeAARect(this->getGpu(), target, devRect, 809f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com strokeSize, useVertexCoverage); 810205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 811f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->fillAARect(this->getGpu(), target, 812f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com devRect, useVertexCoverage); 813205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 814205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 815205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 816205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 81727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 81827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: consider making static vertex buffers for these cases. 81927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // Hairline could be done by just adding closing vertex to 82027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // unitSquareVertexBuffer() 82126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 82226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 82327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int worstCaseVertCount = 10; 82427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0); 82527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 82627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 8276513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 82827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 82927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 83027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 83127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primType; 83227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertCount; 83327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* vertex = geo.positions(); 83427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 83527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width > 0) { 83627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 10; 83747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com primType = kTriangleStrip_GrPrimitiveType; 83827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com setStrokeRectStrip(vertex, rect, width); 83927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 84027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // hairline 84127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 5; 84247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com primType = kLineStrip_GrPrimitiveType; 84327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 84427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 84527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 84627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 84727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 84827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 84927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 8508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 85127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 8528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com avmr.set(drawState); 8548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(*matrix); 8558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, *matrix); 85627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 85727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 85827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 85927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 8608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#if GR_STATIC_RECT_VB 86126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 8626513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 8636513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 8646513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 8656513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 8666513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 8676513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 8688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 87027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 8718295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com m.setAll(rect.width(), 0, rect.fLeft, 872205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, rect.height(), rect.fTop, 873205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, GrMatrix::I()[8]); 87427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 87527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 87627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*matrix); 87727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 8788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 8798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, m); 88026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 88147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 8828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#else 88326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com target->drawSimpleRect(rect, matrix, stageMask); 8848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#endif 88527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 88627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 88727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 88827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 88927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& dstRect, 89027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& srcRect, 89127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* dstMatrix, 89227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* srcMatrix) { 893278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRectToRect"); 89427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 89526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to paint's first texture 89626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (NULL == paint.getTexture(0)) { 89727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com drawRect(paint, dstRect, -1, dstMatrix); 89827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 89927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 900de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com 90127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB); 90227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 90327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_STATIC_RECT_VB 90427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 905972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com GrDrawState::AutoTextureRelease atr(fDrawState); 9068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 90726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 9088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 90927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 91027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 91127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 91227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(dstRect.width(), 0, dstRect.fLeft, 91327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, dstRect.height(), dstRect.fTop, 91427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 91527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != dstMatrix) { 91627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*dstMatrix); 91727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 9188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 91927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 92026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to first stage 92126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int otherStageMask = paint.getActiveStageMask() & 92226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com (~(1 << GrPaint::kFirstTextureStage)); 92326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (otherStageMask) { 9248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(otherStageMask, m); 92526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 92626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 92727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(srcRect.width(), 0, srcRect.fLeft, 92827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, srcRect.height(), srcRect.fTop, 92927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 93027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != srcMatrix) { 93127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*srcMatrix); 93227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 9338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m); 93427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9356513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 9366513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 9376513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 9386513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 9396513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 9406513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 94147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 94227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 94327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 94427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 945de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#if BATCH_RECT_TO_RECT 94627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kBuffered_DrawCategory); 947de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#else 94827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 94927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 950972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com GrDrawState::AutoTextureRelease atr(fDrawState); 95127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9529381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 9539381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; 95427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcRects[0] = &srcRect; 95527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcMatrices[0] = srcMatrix; 95627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 95727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices); 95827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 95927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 96027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 96127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 96227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 96327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 96427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint positions[], 96527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint texCoords[], 96627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 96727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 96827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 969278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawVertices"); 97027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 97127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo; 97227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 97327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 974972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com GrDrawState::AutoTextureRelease atr(fDrawState); 97527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 97626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com bool hasTexCoords[GrPaint::kTotalStages] = { 97726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com NULL != texCoords, // texCoordSrc provides explicit stage 0 coords 97826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 0 // remaining stages use positions 97926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com }; 98026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 98126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); 98227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 98327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != colors) { 98427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 98527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 98626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int vertexSize = GrDrawTarget::VertexSize(layout); 98727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 98827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (sizeof(GrPoint) != vertexSize) { 98927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.set(target, layout, vertexCount, 0)) { 9906513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 99127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 99227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 9939381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com int texOffsets[GrDrawState::kMaxTexCoords]; 99427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int colorOffset; 99526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, 99626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com texOffsets, 997aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com &colorOffset, 998a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL, 999a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL); 100027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* curVertex = geo.vertices(); 100127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 100227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 100327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *((GrPoint*)curVertex) = positions[i]; 100427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 100527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (texOffsets[0] > 0) { 100627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; 100727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 100827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (colorOffset > 0) { 100927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 101027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 101126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 101227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 101327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 101427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->setVertexSourceToArray(layout, positions, vertexCount); 101527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 101627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1017919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // we don't currently apply offscreen AA to this path. Need improved 1018919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 1019a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com 10208295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (NULL != indices) { 1021919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 10228295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 102327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 10248295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 10258295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 102627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 102727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 102806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 1029150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.comnamespace { 1030150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 103193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.comstruct CircleVertex { 103293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPoint fPos; 103393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPoint fCenter; 103493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar fOuterRadius; 103593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar fInnerRadius; 103693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com}; 103793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 103893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com/* Returns true if will map a circle to another circle. This can be true 103993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com * if the matrix only includes square-scale, rotation, translation. 104093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com */ 104193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.cominline bool isSimilarityTransformation(const SkMatrix& matrix, 104293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar tol = SK_ScalarNearlyZero) { 104393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (matrix.isIdentity() || matrix.getType() == SkMatrix::kTranslate_Mask) { 104493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return true; 104593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 104693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (matrix.hasPerspective()) { 104793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return false; 104893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 104993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 105093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar mx = matrix.get(SkMatrix::kMScaleX); 105193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar sx = matrix.get(SkMatrix::kMSkewX); 105293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar my = matrix.get(SkMatrix::kMScaleY); 105393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar sy = matrix.get(SkMatrix::kMSkewY); 105493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 105593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (mx == 0 && sx == 0 && my == 0 && sy == 0) { 105693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return false; 105793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 105893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 105993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com // it has scales or skews, but it could also be rotation, check it out. 106093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkVector vec[2]; 106193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com vec[0].set(mx, sx); 106293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com vec[1].set(sy, my); 106393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 106493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) && 106593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(), 106693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalarSquare(tol)); 106793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 106893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 106993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 107093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 107193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com// TODO: strokeWidth can't be larger than zero right now. 107293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com// It will be fixed when drawPath() can handle strokes. 107393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.comvoid GrContext::drawOval(const GrPaint& paint, 107493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com const GrRect& rect, 107593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar strokeWidth) { 107693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com DrawCategory category = (DEFER_PATHS) ? kBuffered_DrawCategory : 107793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com kUnbuffered_DrawCategory; 107893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, category); 1079972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com GrDrawState::AutoTextureRelease atr(fDrawState); 108093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrDrawState* drawState = target->drawState(); 108193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrMatrix vm = drawState->getViewMatrix(); 108293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 108393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (!isSimilarityTransformation(vm) || 108493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com !paint.fAntiAlias || 108593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com rect.height() != rect.width()) { 108693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkPath path; 108793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com path.addOval(rect); 108893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPathFill fill = (strokeWidth == 0) ? 108947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com kHairLine_GrPathFill : kWinding_GrPathFill; 109093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com this->internalDrawPath(paint, path, fill, NULL); 109193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return; 109293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 109393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 109493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com const GrRenderTarget* rt = drawState->getRenderTarget(); 109593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (NULL == rt) { 109693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return; 109793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 109893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 109993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, paint.getActiveStageMask()); 110093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 110193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 110293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com layout |= GrDrawTarget::kEdge_VertexLayoutBit; 110393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrAssert(sizeof(CircleVertex) == GrDrawTarget::VertexSize(layout)); 110493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 110593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPoint center = GrPoint::Make(rect.centerX(), rect.centerY()); 110693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar radius = SkScalarHalf(rect.width()); 110793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 110893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com vm.mapPoints(¢er, 1); 110993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com radius = vm.mapRadius(radius); 111093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 111193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar outerRadius = radius; 111293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar innerRadius = 0; 111393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar halfWidth = 0; 111493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (strokeWidth == 0) { 111593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com halfWidth = SkScalarHalf(SK_Scalar1); 111693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 111793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com outerRadius += halfWidth; 111893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com innerRadius = SkMaxScalar(0, radius - halfWidth); 111993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 112093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 112193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 4, 0); 112293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (!geo.succeeded()) { 112393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 112493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return; 112593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 112693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 112793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); 112893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1129a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com // The fragment shader will extend the radius out half a pixel 1130a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com // to antialias. Expand the drawn rect here so all the pixels 1131a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com // will be captured. 1132a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com SkScalar L = center.fX - outerRadius - SkFloatToScalar(0.5f); 1133a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com SkScalar R = center.fX + outerRadius + SkFloatToScalar(0.5f); 1134a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com SkScalar T = center.fY - outerRadius - SkFloatToScalar(0.5f); 1135a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com SkScalar B = center.fY + outerRadius + SkFloatToScalar(0.5f); 113693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 113793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[0].fPos = SkPoint::Make(L, T); 113893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[1].fPos = SkPoint::Make(R, T); 113993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[2].fPos = SkPoint::Make(L, B); 114093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[3].fPos = SkPoint::Make(R, B); 114193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 114293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com for (int i = 0; i < 4; ++i) { 114393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com // this goes to fragment shader, it should be in y-points-up space. 114493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[i].fCenter = SkPoint::Make(center.fX, rt->height() - center.fY); 114593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 114693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[i].fOuterRadius = outerRadius; 114793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[i].fInnerRadius = innerRadius; 114893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 114993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 115093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com drawState->setVertexEdgeType(GrDrawState::kCircle_EdgeType); 115147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); 1152150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 115327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 11548d033a1b125886c62906d975b5cc28a382064526bsalomon@google.comvoid GrContext::drawPath(const GrPaint& paint, const SkPath& path, 115507f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com GrPathFill fill, const GrPoint* translate) { 115627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1157fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 1158fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (GrIsFillInverted(fill)) { 1159fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->drawPaint(paint); 1160fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1161fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1162fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1163fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 116493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkRect ovalRect; 116593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (!GrIsFillInverted(fill) && path.isOval(&ovalRect)) { 116693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (translate) { 116793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com ovalRect.offset(*translate); 116893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 116947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com SkScalar width = (fill == kHairLine_GrPathFill) ? 0 : -SK_Scalar1; 117093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com this->drawOval(paint, ovalRect, width); 117193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return; 117293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 117393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 117493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com internalDrawPath(paint, path, fill, translate); 117593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 117693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 11778d033a1b125886c62906d975b5cc28a382064526bsalomon@google.comvoid GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, 117893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPathFill fill, const GrPoint* translate) { 117993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1180fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // Note that below we may sw-rasterize the path into a scratch texture. 1181fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // Scratch textures can be recycled after they are returned to the texture 1182fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // cache. This presents a potential hazard for buffered drawing. However, 1183fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // the writePixels that uploads to the scratch will perform a flush so we're 1184fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // OK. 1185fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com DrawCategory category = (DEFER_PATHS) ? kBuffered_DrawCategory : 1186fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com kUnbuffered_DrawCategory; 1187fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, category); 1188972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com GrDrawState::AutoTextureRelease atr(fDrawState); 1189150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawState::StageMask stageMask = paint.getActiveStageMask(); 1190d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1191289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled(); 1192289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1193d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1194d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1195d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1196d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1197d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 11981983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 1199979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 12001983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 1201289533ada623f2238a83771eec977f204f75994fbsalomon@google.com prAA = false; 1202d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 1203289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 120472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrPathRenderer* pr = this->getPathRenderer(path, fill, target, prAA, true); 12053008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == pr) { 12061983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 12073008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 12081983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 12093008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 12103008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 12113008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1212c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com pr->drawPath(path, fill, translate, target, stageMask, prAA); 121327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 12148295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 121527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 121627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1217a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1218a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1219a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1220a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 1221c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com this->flushDrawBuffer(); 1222a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } 1223a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { 122427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->forceRenderTargetFlush(); 122527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 122627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 122727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 122827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushDrawBuffer() { 122953a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com if (fDrawBuffer) { 123058b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // With addition of the AA clip path, flushing the draw buffer can 123158b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // result in the generation of an AA clip mask. During this 123258b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // process the SW path renderer may be invoked which recusively 123358b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // calls this method (via internalWriteTexturePixels) creating 123458b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // infinite recursion 123558b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com GrInOrderDrawBuffer* temp = fDrawBuffer; 123658b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com fDrawBuffer = NULL; 123758b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com 123858b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com temp->flushTo(fGpu); 123958b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com 124058b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com fDrawBuffer = temp; 124153a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 124227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 124327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 12446f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteTexturePixels(GrTexture* texture, 12456f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 12466f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 12476f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 12486f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 12496f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 12506f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 12516f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 1252bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1253bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 12546f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 12556f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 12566f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 12576f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com // TODO: use scratch texture to perform conversion 12586f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (GrPixelConfigIsUnpremultiplied(texture->config()) != 12596f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 12606f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 12616f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 12626f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 12636f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com fGpu->writeTexturePixels(texture, left, top, width, height, 12646f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes); 12656f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 12666f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 12676f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadTexturePixels(GrTexture* texture, 12686f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 12696f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 12706f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 12716f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 12726f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 12736f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1274278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readTexturePixels"); 1275bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1276669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1277a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // TODO: code read pixels for textures that aren't also rendertargets 1278669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 1279669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL != target) { 12806f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return this->internalReadRenderTargetPixels(target, 12816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com left, top, width, height, 12826f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, 12836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com flags); 1284669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } else { 1285669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1286669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1287669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com} 1288669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1289a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkConfig8888.h" 1290a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1291a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.comnamespace { 1292a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com/** 1293a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 1294a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * formats are representable as Config8888 and so the function returns false 1295a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * if the GrPixelConfig has no equivalent Config8888. 1296a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com */ 1297a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.combool grconfig_to_config8888(GrPixelConfig config, 1298a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888* config8888) { 1299a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com switch (config) { 1300a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kRGBA_8888_PM_GrPixelConfig: 1301a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kRGBA_Premul_Config8888; 1302a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1303a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kRGBA_8888_UPM_GrPixelConfig: 1304a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 1305a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1306a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kBGRA_8888_PM_GrPixelConfig: 1307a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kBGRA_Premul_Config8888; 1308a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1309a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kBGRA_8888_UPM_GrPixelConfig: 1310a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 1311a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1312a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com default: 1313a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1314a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1315a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1316a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1317a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 13186f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, 13196f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 13206f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 13216f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 13226f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 13236f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 13246f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1325278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 1326bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1327bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 1328669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL == target) { 132910e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com target = fDrawState->getRenderTarget(); 1330c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (NULL == target) { 1331c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1332c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1333c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1334669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 13356f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 13366f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 13376f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1338c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1339a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!GrPixelConfigIsUnpremultiplied(target->config()) && 1340a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com GrPixelConfigIsUnpremultiplied(config) && 1341a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !fGpu->canPreserveReadWriteUnpremulPixels()) { 1342a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1343a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!grconfig_to_config8888(target->config(), &srcConfig8888) || 1344a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !grconfig_to_config8888(config, &dstConfig8888)) { 1345a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1346a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1347a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // do read back using target's own config 1348a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com this->internalReadRenderTargetPixels(target, 1349a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com left, top, 1350a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height, 1351a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com target->config(), 1352a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com buffer, rowBytes, 1353a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com kDontFlush_PixelOpsFlag); 1354a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // sw convert the pixels to unpremul config 1355a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com uint32_t* pixels = reinterpret_cast<uint32_t*>(buffer); 1356a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkConvertConfig8888Pixels(pixels, rowBytes, dstConfig8888, 1357a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com pixels, rowBytes, srcConfig8888, 1358a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height); 1359a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1360a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1361a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1362c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* src = target->asTexture(); 13630a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool swapRAndB = NULL != src && 13640a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com fGpu->preferredReadPixelsConfig(config) == 13650a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigSwapRAndB(config); 1366c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1367c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com bool flipY = NULL != src && 1368c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->readPixelsWillPayForYFlip(target, left, top, 1369c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, config, 1370c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 13710a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) && 13720a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)); 1373c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 13740a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (NULL == src && alphaConversion) { 13750a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we should fallback to cpu conversion here. This could happen when 13760a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we were given an external render target by the client that is not 13770a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // also a texture (e.g. FBO 0 in GL) 13780a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 13790a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 13800a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we draw to a scratch texture if any of these conversion are applied 1381c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com GrAutoScratchTexture ast; 13820a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (flipY || swapRAndB || alphaConversion) { 13830a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(NULL != src); 13840a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (swapRAndB) { 13850a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 13860a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(kUnknown_GrPixelConfig != config); 1387c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1388c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // Make the scratch a render target because we don't have a robust 1389c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // readTexturePixels as of yet (it calls this function). 139075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 139175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit; 139275b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 139375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 139475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fConfig = config; 1395c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 139656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // When a full readback is faster than a partial we could always make 139756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // the scratch exactly match the passed rect. However, if we see many 139856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // different size rectangles we will trash our texture cache and pay the 139956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // cost of creating and destroying many textures. So, we only request 140056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // an exact match when the caller is reading an entire RT. 140156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 140256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 140356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 140456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 140556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 140656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 140756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com match = kExact_ScratchTexMatch; 140856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 140956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ast.set(this, desc, match); 1410c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* texture = ast.texture(); 1411c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (!texture) { 1412c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1413c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1414c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com target = texture->asRenderTarget(); 1415c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrAssert(NULL != target); 1416c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1417873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, 1418873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::kReset_ASRInit); 14198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 14208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 1421c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1422c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrMatrix matrix; 1423c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (flipY) { 1424c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 * left, 1425c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com SK_Scalar1 * (top + height)); 1426c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.set(GrMatrix::kMScaleY, -GR_Scalar1); 1427c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } else { 1428c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1429c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1430c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.postIDiv(src->width(), src->height()); 14311e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(matrix); 14321e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 14338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 1434c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrRect rect; 1435c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height); 1436c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->drawSimpleRect(rect, NULL, 0x1); 1437c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left = 0; 1438c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com top = 0; 1439c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1440669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return fGpu->readPixels(target, 1441c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left, top, width, height, 1442c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com config, buffer, rowBytes, flipY); 144327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 144427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 144575f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.comvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 144675f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com GrAssert(target); 144775f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com ASSERT_OWNED_RESOURCE(target); 144875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // In the future we may track whether there are any pending draws to this 144975f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // target. We don't today so we always perform a flush. We don't promise 145075f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // this to our clients, though. 145175f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com this->flush(); 145275f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com fGpu->resolveRenderTarget(target); 145375f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com} 145475f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com 1455ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.orgvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { 1456ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1457ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1458ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1459ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1460ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 14611ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // Writes pending to the source texture are not tracked, so a flush 14621ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // is required to ensure that the copy captures the most recent contents 14631ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // of the source texture. See similar behaviour in 14641ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // GrContext::resolveRenderTarget. 14651ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com this->flush(); 14661ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com 1467873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 14688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 14698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 1470ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrMatrix sampleM; 1471ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 14728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 14731e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(sampleM); 14745db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SkRect rect = SkRect::MakeXYWH(0, 0, 14755db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1 * src->width(), 14765db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1 * src->height()); 1477ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 1478ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1479ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 14806f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, 14816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 14826f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 14836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 14846f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 14856f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 14866f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 14876f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 1488bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 14896f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 14906f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 1491873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com target = fDrawState->getRenderTarget(); 14926f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 14936f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 14946f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 14956f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 149627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 149727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it 149827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // (e.g. glDrawPixels on desktop GL). 149927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1500a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // If the RT is also a texture and we don't have to do PM/UPM conversion 1501a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // then take the texture path, which we expect to be at least as fast or 1502a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // faster since it doesn't use an intermediate texture as we do below. 1503a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1504a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#if !GR_MAC_BUILD 1505a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called 1506a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // on a texture attached to an FBO. The FBO still sees the old image. TODO: 1507a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // determine what OS versions and/or HW is affected. 1508a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (NULL != target->asTexture() && 1509a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(target->config()) == 1510a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 1511a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1512a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com this->internalWriteTexturePixels(target->asTexture(), 1513a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com left, top, width, height, 1514a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config, buffer, rowBytes, flags); 1515a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com return; 1516a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1517a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif 1518a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!GrPixelConfigIsUnpremultiplied(target->config()) && 1519a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com GrPixelConfigIsUnpremultiplied(config) && 1520a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !fGpu->canPreserveReadWriteUnpremulPixels()) { 1521a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1522a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!grconfig_to_config8888(config, &srcConfig8888) || 1523a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !grconfig_to_config8888(target->config(), &dstConfig8888)) { 1524a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return; 1525a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1526a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // allocate a tmp buffer and sw convert the pixels to premul 1527a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(width * height); 1528a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 1529a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 1530a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com src, rowBytes, srcConfig8888, 1531a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height); 1532a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // upload the already premul pixels 1533a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com this->internalWriteRenderTargetPixels(target, 1534a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com left, top, 1535a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height, 1536a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com target->config(), 1537a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com tmpPixels, 4 * width, flags); 1538a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return; 1539a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1540a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1541a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com bool swapRAndB = fGpu->preferredReadPixelsConfig(config) == 1542a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigSwapRAndB(config); 1543a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (swapRAndB) { 1544a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 1545a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1546a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 154775b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 154875b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 154975b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 155075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fConfig = config; 155175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com 155250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture ast(this, desc); 155350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* texture = ast.texture(); 155427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL == texture) { 155527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 155627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 15576f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->internalWriteTexturePixels(texture, 0, 0, width, height, 15586f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, flags); 155927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1560873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 15618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 156227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 156327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix matrix; 156427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); 15658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(matrix); 15668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 15678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, texture); 156827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 15695c63865b529eb5714e41419dfa23c70d26ff6e4ebsalomon@google.com matrix.setIDiv(texture->width(), texture->height()); 15701e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 15711e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState::kNearest_Filter, 15721e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com matrix); 15731e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 157427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 157527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); 157627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int VCOUNT = 4; 15776513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com // TODO: Use GrGpu::drawRect here 157827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0); 157927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 15806513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 158127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 158227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 158327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); 158447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, VCOUNT); 158527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 158627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 158727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 158810e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.comvoid GrContext::setPaint(const GrPaint& paint) { 158926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 159026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxTextures; ++i) { 159126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstTextureStage; 159210e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setTexture(s, paint.getTexture(i)); 1593bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getTexture(i)); 1594f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com if (paint.getTexture(i)) { 159510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com *fDrawState->sampler(s) = paint.getTextureSampler(i); 1596f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 159726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 159826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 159910e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setFirstCoverageStage(GrPaint::kFirstMaskStage); 160026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 160126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxMasks; ++i) { 160226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstMaskStage; 160310e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setTexture(s, paint.getMask(i)); 1604bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getMask(i)); 1605f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com if (paint.getMask(i)) { 160610e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com *fDrawState->sampler(s) = paint.getMaskSampler(i); 1607f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 160826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 160926936d071f9e426e11db9a8cf67f5ce86e83feb1bsalomon@google.com 161026936d071f9e426e11db9a8cf67f5ce86e83feb1bsalomon@google.com // disable all stages not accessible via the paint 161126936d071f9e426e11db9a8cf67f5ce86e83feb1bsalomon@google.com for (int s = GrPaint::kTotalStages; s < GrDrawState::kNumStages; ++s) { 161210e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setTexture(s, NULL); 161326936d071f9e426e11db9a8cf67f5ce86e83feb1bsalomon@google.com } 161426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 161510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setColor(paint.fColor); 161627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 161727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fDither) { 161810e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->enableState(GrDrawState::kDither_StateBit); 161927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 162010e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->disableState(GrDrawState::kDither_StateBit); 162127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 162227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fAntiAlias) { 162310e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->enableState(GrDrawState::kHWAntialias_StateBit); 162427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 162510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->disableState(GrDrawState::kHWAntialias_StateBit); 162627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 162750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org if (paint.fColorMatrixEnabled) { 162810e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->enableState(GrDrawState::kColorMatrix_StateBit); 162910e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setColorMatrix(paint.fColorMatrix); 163050bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org } else { 163110e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->disableState(GrDrawState::kColorMatrix_StateBit); 163250bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org } 163310e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); 163410e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); 163510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setCoverage(paint.fCoverage); 16364b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#if GR_DEBUG_PARTIAL_COVERAGE_CHECK 1637e79c815bca39fa552983b7a8107219aa5084acdbbsalomon@google.com if ((paint.getActiveMaskStageMask() || 0xff != paint.fCoverage) && 163810e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com !fGpu->canApplyCoverage()) { 1639d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 1640d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 164195cd7bdf2b4dee54739f0a375fe99a02f86178b0bsalomon@google.com#endif 164227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 164327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1644de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 164527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DrawCategory category) { 164627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (category != fLastDrawCategory) { 1647fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com this->flushDrawBuffer(); 164827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = category; 164927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 165010e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com this->setPaint(paint); 165127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = fGpu; 165227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com switch (category) { 1653193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com case kUnbuffered_DrawCategory: 1654193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com target = fGpu; 1655193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com break; 1656193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com case kBuffered_DrawCategory: 1657193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com target = fDrawBuffer; 1658193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com fDrawBuffer->setClip(fGpu->getClip()); 1659193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com break; 1660193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com default: 1661193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com GrCrash("Unexpected DrawCategory."); 1662193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com break; 166327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 166427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 166527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 166627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 166772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com/* 166872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * This method finds a path renderer that can draw the specified path on 166972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * the provided target. 167072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * Due to its expense, the software path renderer has split out so it can 167172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * can be individually allowed/disallowed via the "allowSW" boolean. 167272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com */ 16738d033a1b125886c62906d975b5cc28a382064526bsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const SkPath& path, 1674289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathFill fill, 1675c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com const GrDrawTarget* target, 167672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com bool antiAlias, 167772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com bool allowSW) { 16783008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 16793008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = 16803008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag); 16813008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 168272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 168372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, fill, 168472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com target, 168572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com antiAlias); 168672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 168772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == pr && allowSW) { 168872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == fSoftwarePathRenderer) { 168972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com fSoftwarePathRenderer = new GrSoftwarePathRenderer(this); 169072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 169172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 169272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com pr = fSoftwarePathRenderer; 169372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 169472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 169572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com return pr; 16963008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 16973008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 169827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 169927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 170027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setRenderTarget(GrRenderTarget* target) { 1701bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 170210e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com if (fDrawState->getRenderTarget() != target) { 1703fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com this->flush(false); 170410e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setRenderTarget(target); 1705fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com } 170627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 170727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 170827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrRenderTarget* GrContext::getRenderTarget() { 170910e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com return fDrawState->getRenderTarget(); 171027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 171127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 171227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrRenderTarget* GrContext::getRenderTarget() const { 171310e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com return fDrawState->getRenderTarget(); 171427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 171527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 171699a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.combool GrContext::isConfigRenderable(GrPixelConfig config) const { 171799a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com return fGpu->isConfigRenderable(config); 171899a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com} 171999a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com 172027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrMatrix& GrContext::getMatrix() const { 172110e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com return fDrawState->getViewMatrix(); 172227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 172327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 172427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setMatrix(const GrMatrix& m) { 172510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setViewMatrix(m); 172627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 172727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 172827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::concatMatrix(const GrMatrix& m) const { 172910e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->preConcatViewMatrix(m); 173027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 173127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 173227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 173327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com intptr_t mask = 1 << shift; 173427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (pred) { 173527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits |= mask; 173627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 173727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits &= ~mask; 173827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 173927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return bits; 174027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 174127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1742583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.comGrContext::GrContext(GrGpu* gpu) { 1743c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com ++THREAD_INSTANCE_COUNT; 1744c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 174527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu = gpu; 174627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->ref(); 1747669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com fGpu->setContext(this); 17488fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 174910e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState = new GrDrawState(); 175010e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fGpu->setDrawState(fDrawState); 175110e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com 17523008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = NULL; 175372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com fSoftwarePathRenderer = NULL; 1754dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 17558f7e1dac5c92bf1f53feb603a9bd249d53afa81absalomon@google.com fTextureCache = new GrResourceCache(kDefaultTextureCacheBudget); 175627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fFontCache = new GrFontCache(fGpu); 175727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 175827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = kUnbuffered_DrawCategory; 175927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 17608fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 17618fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 17628fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 17638fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1764f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer = new GrAARectRenderer; 176510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com 17668fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->setupDrawBuffer(); 17678fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 17688fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 17698fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() { 17708fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 17718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBuffer); 17728fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferVBAllocPool); 17738fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferIBAllocPool); 17748fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 177592edd316e5425f7f7fbecbae28483da2851248bbbsalomon@google.com#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT || DEFER_PATHS 1776de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferVBAllocPool = 17778fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrVertexBufferAllocPool(fGpu, false, 177827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 177927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS); 1780de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferIBAllocPool = 17818fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrIndexBufferAllocPool(fGpu, false, 1782de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 178327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS); 178427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1785471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBuffer = new GrInOrderDrawBuffer(fGpu, 1786471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBufferVBAllocPool, 178727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBufferIBAllocPool); 17883c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#endif 17893c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com 17903c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#if BATCH_RECT_TO_RECT 179127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); 17923c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#endif 1793fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com fDrawBuffer->setAutoFlushTarget(fGpu); 179410e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawBuffer->setDrawState(fDrawState); 179527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 179627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 179727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { 179827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 1799193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com return prepareToDraw(paint, kBuffered_DrawCategory); 180027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 180110e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com return prepareToDraw(paint, kUnbuffered_DrawCategory); 180227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 180327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 180427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 180527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 180627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getQuadIndexBuffer(); 180727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 1808dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 18093b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgGrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, 18103b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAutoScratchTexture* temp1, 18113b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAutoScratchTexture* temp2, 18123b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const SkRect& rect, 18133b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float sigmaX, float sigmaY) { 1814ceb441476e1712861e87a9bb428f119349ef6bb5senorblanco@chromium.org ASSERT_OWNED_RESOURCE(srcTexture); 18153b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrRenderTarget* oldRenderTarget = this->getRenderTarget(); 18163b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrClip oldClip = this->getClip(); 18173b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* origTexture = srcTexture; 18183b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAutoMatrix avm(this, GrMatrix::I()); 18193b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkIRect clearRect; 1820b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com int scaleFactorX, radiusX; 1821b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com int scaleFactorY, radiusY; 1822b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &radiusX); 1823b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &radiusY); 18243b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18253b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect srcRect(rect); 18263b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 18273b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.roundOut(); 18288637a365518a82901d313d61eecd83a0c5102fe9robertphillips@google.com scale_rect(&srcRect, static_cast<float>(scaleFactorX), 18298637a365518a82901d313d61eecd83a0c5102fe9robertphillips@google.com static_cast<float>(scaleFactorY)); 18303b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setClip(srcRect); 1831bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 183299a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com GrAssert(kBGRA_8888_PM_GrPixelConfig == srcTexture->config() || 183399a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com kRGBA_8888_PM_GrPixelConfig == srcTexture->config() || 183499a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com kAlpha_8_GrPixelConfig == srcTexture->config()); 183599a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com 183675b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 183775b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 183875b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = SkScalarFloorToInt(srcRect.width()); 183975b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = SkScalarFloorToInt(srcRect.height()); 184075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fConfig = srcTexture->config(); 18411e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com 18423b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org temp1->set(this, desc); 184399a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com if (temp2) { 184499a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com temp2->set(this, desc); 184599a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com } 18463b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18473b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* dstTexture = temp1->texture(); 18483b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrPaint paint; 18493b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.reset(); 18503b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter); 18513b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18523b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 18533b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(), 18543b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture->height()); 18553b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 18563b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect dstRect(srcRect); 18573b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 18583b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org i < scaleFactorY ? 0.5f : 1.0f); 18593b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.setTexture(0, srcTexture); 18603b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->drawRectToRect(paint, dstRect, srcRect); 18613b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect = dstRect; 18623b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkTSwap(srcTexture, dstTexture); 18633b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // If temp2 is non-NULL, don't render back to origTexture 1864972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com if (temp2 && dstTexture == origTexture) { 1865972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com dstTexture = temp2->texture(); 1866972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com } 18673b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 18683b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18697a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkIRect srcIRect; 18707a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com srcRect.roundOut(&srcIRect); 18717a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com 18723b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (sigmaX > 0.0f) { 18733b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorX > 1) { 1874b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // Clear out a radius to the right of the srcRect to prevent the 18753b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // X convolution from reading garbage. 18767a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 1877b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com radiusX, srcIRect.height()); 18783b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 18793b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 188005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 18813b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 1882b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com convolve_gaussian(fGpu, srcTexture, srcRect, sigmaX, radiusX, 1883b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::kX_Direction); 18843b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkTSwap(srcTexture, dstTexture); 188599a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com if (temp2 && dstTexture == origTexture) { 188699a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com dstTexture = temp2->texture(); 188799a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com } 18883b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 18893b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18903b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (sigmaY > 0.0f) { 18913b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorY > 1 || sigmaX > 0.0f) { 1892b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // Clear out a radius below the srcRect to prevent the Y 18933b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // convolution from reading garbage. 18947a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 1895b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com srcIRect.width(), radiusY); 18963b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 18973b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 18983b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18993b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 1900b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com convolve_gaussian(fGpu, srcTexture, srcRect, sigmaY, radiusY, 1901b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::kY_Direction); 19023b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkTSwap(srcTexture, dstTexture); 190399a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com if (temp2 && dstTexture == origTexture) { 190499a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com dstTexture = temp2->texture(); 190599a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com } 19063b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 19073b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 19083b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorX > 1 || scaleFactorY > 1) { 19093b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // Clear one pixel to the right and below, to accommodate bilinear 19103b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // upsampling. 19117a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 19127a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com srcIRect.width() + 1, 1); 19133b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 19147a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 19157a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com 1, srcIRect.height()); 19163b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 19173b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // FIXME: This should be mitchell, not bilinear. 19183b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter); 19193b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(), 19203b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture->height()); 19213b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 19223b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.setTexture(0, srcTexture); 19233b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect dstRect(srcRect); 19247a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); 19253b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->drawRectToRect(paint, dstRect, srcRect); 19263b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect = dstRect; 19273b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkTSwap(srcTexture, dstTexture); 19283b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 19293b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(oldRenderTarget); 19303b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setClip(oldClip); 19313b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org return srcTexture; 19323b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 19333b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 19343b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgGrTexture* GrContext::applyMorphology(GrTexture* srcTexture, 19353b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const GrRect& rect, 19363b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* temp1, GrTexture* temp2, 1937b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com MorphologyType morphType, 19383b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkISize radius) { 1939ceb441476e1712861e87a9bb428f119349ef6bb5senorblanco@chromium.org ASSERT_OWNED_RESOURCE(srcTexture); 19403b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrRenderTarget* oldRenderTarget = this->getRenderTarget(); 19413b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAutoMatrix avm(this, GrMatrix::I()); 19423b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrClip oldClip = this->getClip(); 19437a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com this->setClip(GrRect::MakeWH(SkIntToScalar(srcTexture->width()), 19447a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkIntToScalar(srcTexture->height()))); 19453b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (radius.fWidth > 0) { 19463b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(temp1->asRenderTarget()); 1947b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com apply_morphology(fGpu, srcTexture, rect, radius.fWidth, morphType, 1948b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::kX_Direction); 19497a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkIRect clearRect = SkIRect::MakeXYWH( 19507a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkScalarFloorToInt(rect.fLeft), 19517a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkScalarFloorToInt(rect.fBottom), 19527a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkScalarFloorToInt(rect.width()), 19537a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com radius.fHeight); 19543b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 19553b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture = temp1; 19563b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 19573b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (radius.fHeight > 0) { 19583b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(temp2->asRenderTarget()); 1959b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com apply_morphology(fGpu, srcTexture, rect, radius.fHeight, morphType, 1960b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::kY_Direction); 19613b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture = temp2; 19623b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 19633b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(oldRenderTarget); 19643b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setClip(oldClip); 19653b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org return srcTexture; 1966027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org} 1967c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 196849d9fd5fdb9ffd48538c8fc5a2f6f2d43a2e4fe9robertphillips@google.comvoid GrContext::postClipPush() { 196949d9fd5fdb9ffd48538c8fc5a2f6f2d43a2e4fe9robertphillips@google.com fGpu->postClipPush(); 197049d9fd5fdb9ffd48538c8fc5a2f6f2d43a2e4fe9robertphillips@google.com} 197149d9fd5fdb9ffd48538c8fc5a2f6f2d43a2e4fe9robertphillips@google.com 197249d9fd5fdb9ffd48538c8fc5a2f6f2d43a2e4fe9robertphillips@google.comvoid GrContext::preClipPop() { 197349d9fd5fdb9ffd48538c8fc5a2f6f2d43a2e4fe9robertphillips@google.com fGpu->preClipPop(); 197449d9fd5fdb9ffd48538c8fc5a2f6f2d43a2e4fe9robertphillips@google.com}; 197549d9fd5fdb9ffd48538c8fc5a2f6f2d43a2e4fe9robertphillips@google.com 1976c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 1977