11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrContext.h" 111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrBufferAllocPool.h" 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrClipIterator.h" 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrGpu.h" 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrIndexBuffer.h" 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrInOrderDrawBuffer.h" 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrPathRenderer.h" 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrPathUtils.h" 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrResourceCache.h" 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrStencilBuffer.h" 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrTextStrike.h" 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkTLazy.h" 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkTrace.h" 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define DEFER_TEXT_RENDERING 1 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB) 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// When we're using coverage AA but the blend is incompatible (given gpu 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// limitations) should we disable AA or draw wrong? 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define DISABLE_COVERAGE_AA_FOR_BLEND 1 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const size_t MAX_TEXTURE_CACHE_COUNT = 256; 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const size_t MAX_TEXTURE_CACHE_BYTES = 16 * 1024 * 1024; 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18; 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// We are currently only batching Text and drawRectToRect, both 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// of which use the quad index buffer. 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0; 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0; 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this) 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 461cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext* GrContext::Create(GrEngine engine, 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPlatform3DContext context3D) { 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrContext* ctx = NULL; 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGpu* fGpu = GrGpu::Create(engine, context3D); 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != fGpu) { 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ctx = new GrContext(fGpu); 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->unref(); 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return ctx; 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 571cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::~GrContext() { 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->flush(); 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger delete fTextureCache; 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger delete fFontCache; 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger delete fDrawBuffer; 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger delete fDrawBufferVBAllocPool; 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger delete fDrawBufferIBAllocPool; 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSafeUnref(fAAFillRectIndexBuffer); 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSafeUnref(fAAStrokeRectIndexBuffer); 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->unref(); 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSafeUnref(fPathRendererChain); 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::contextLost() { 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger contextDestroyed(); 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setupDrawBuffer(); 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::contextDestroyed() { 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // abandon first to so destructors 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // don't try to free the resources in the API. 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->abandonResources(); 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // a path renderer may be holding onto resources that 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // are now unusable 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSafeSetNull(fPathRendererChain); 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger delete fDrawBuffer; 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer = NULL; 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger delete fDrawBufferVBAllocPool; 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBufferVBAllocPool = NULL; 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger delete fDrawBufferIBAllocPool; 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBufferIBAllocPool = NULL; 931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSafeSetNull(fAAFillRectIndexBuffer); 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSafeSetNull(fAAStrokeRectIndexBuffer); 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->removeAll(); 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fFontCache->freeAll(); 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->markContextDirty(); 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::resetContext() { 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->markContextDirty(); 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::freeGpuResources() { 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->flush(); 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->removeAll(); 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fFontCache->freeAll(); 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // a path renderer may be holding onto resources 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSafeSetNull(fPathRendererChain); 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergersize_t GrContext::getGpuTextureCacheBytes() const { 1154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fTextureCache->getCachedResourceBytes(); 1164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::PaintStageVertexLayoutBits( 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrPaint& paint, 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const bool hasTexCoords[GrPaint::kTotalStages]) { 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int stageMask = paint.getActiveStageMask(); 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int layout = 0; 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < GrPaint::kTotalStages; ++i) { 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if ((1 << i) & stageMask) { 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != hasTexCoords && hasTexCoords[i]) { 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(i, i); 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i); 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return layout; 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerenum { 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // flags for textures 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kNPOTBit = 0x1, 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kFilterBit = 0x2, 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kScratchBit = 0x4, 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // resource type 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kTextureBit = 0x8, 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kStencilBufferBit = 0x10 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1511cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrTexture* GrContext::TextureCacheEntry::texture() const { 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == fEntry) { 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return NULL; 1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return (GrTexture*) fEntry->resource(); 1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// returns true if this is a "special" texture because of gpu NPOT limitations 1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool gen_texture_key_values(const GrGpu* gpu, 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrSamplerState* sampler, 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrContext::TextureKey clientKey, 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int height, 1664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int sampleCnt, 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool scratch, 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]) { 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_STATIC_ASSERT(sizeof(GrContext::TextureKey) == sizeof(uint64_t)); 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we assume we only need 16 bits of width and height 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // assert that texture creation will fail anyway if this assumption 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // would cause key collisions. 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(gpu->getCaps().fMaxTextureSize <= SK_MaxU16); 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[0] = clientKey & 0xffffffffUL; 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[1] = (clientKey >> 32) & 0xffffffffUL; 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[2] = width | (height << 16); 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger v[3] = (sampleCnt << 24); 1794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(sampleCnt >= 0 && sampleCnt < 256); 1804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!gpu->getCaps().fNPOTTextureTileSupport) { 1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool tiled = NULL != sampler && 1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ((sampler->getWrapX() != GrSamplerState::kClamp_WrapMode) || 1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (sampler->getWrapY() != GrSamplerState::kClamp_WrapMode)); 1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (tiled && !isPow2) { 1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[3] |= kNPOTBit; 1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (GrSamplerState::kNearest_Filter != sampler->getFilter()) { 1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[3] |= kFilterBit; 1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (scratch) { 1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[3] |= kScratchBit; 1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[3] |= kTextureBit; 2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return v[3] & kNPOTBit; 2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// we should never have more than one stencil buffer with same combo of 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// (width,height,samplecount) 2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid gen_stencil_key_values(int width, int height, 2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int sampleCnt, uint32_t v[4]) { 2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[0] = width; 2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[1] = height; 2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[2] = sampleCnt; 2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger v[3] = kStencilBufferBit; 2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid gen_stencil_key_values(const GrStencilBuffer* sb, 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]) { 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gen_stencil_key_values(sb->width(), sb->height(), 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sb->numSamples(), v); 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2231cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::TextureCacheEntry GrContext::findAndLockTexture( 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger TextureKey key, 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int height, 2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrSamplerState* sampler) { 2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]; 2294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger gen_texture_key_values(fGpu, sampler, key, width, height, 0, false, v); 2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceKey resourceKey(v); 2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return TextureCacheEntry(fTextureCache->findAndLock(resourceKey, 2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceCache::kNested_LockType)); 2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::isTextureInCache(TextureKey key, 2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, 2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int height, 2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrSamplerState* sampler) const { 2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]; 2404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger gen_texture_key_values(fGpu, sampler, key, width, height, 0, false, v); 2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceKey resourceKey(v); 2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fTextureCache->hasKey(resourceKey); 2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2451cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) { 2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(sb); 2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]; 2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gen_stencil_key_values(sb, v); 2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceKey resourceKey(v); 2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fTextureCache->createAndLock(resourceKey, sb); 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2531cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int sampleCnt) { 2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]; 2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gen_stencil_key_values(width, height, sampleCnt, v); 2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceKey resourceKey(v); 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey, 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceCache::kSingle_LockType); 2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != entry) { 2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource(); 2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return sb; 2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return NULL; 2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) { 2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(sbEntry->resource()); 2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->unlock(sbEntry); 2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void stretchImage(void* dst, 2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstW, 2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstH, 2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void* src, 2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcW, 2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int srcH, 2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int bpp) { 2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrFixed dx = (srcW << 16) / dstW; 2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrFixed dy = (srcH << 16) / dstH; 2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrFixed y = dy >> 1; 2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int dstXLimit = dstW*bpp; 2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int j = 0; j < dstH; ++j) { 2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrFixed x = dx >> 1; 2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void* dstRow = (uint8_t*)dst + j*dstW*bpp; 2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < dstXLimit; i += bpp) { 2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy((uint8_t*) dstRow + i, 2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (uint8_t*) srcRow + (x>>16)*bpp, 2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bpp); 2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += dx; 2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger y += dy; 2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3001cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::TextureCacheEntry GrContext::createAndLockTexture( 3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger TextureKey key, 3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrSamplerState* sampler, 3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrTextureDesc& desc, 3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void* srcData, 3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t rowBytes) { 3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT0("GrContext::createAndLockTexture"); 3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DUMP_TEXTURE_UPLOAD 3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight); 3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger TextureCacheEntry entry; 3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]; 3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool special = gen_texture_key_values(fGpu, sampler, key, 3154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger desc.fWidth, desc.fHeight, 3164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger desc.fSampleCnt, false, v); 3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceKey resourceKey(v); 3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (special) { 3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != sampler); 3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger TextureCacheEntry clampEntry = this->findAndLockTexture(key, 3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fWidth, 3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fHeight, 3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger NULL); 3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == clampEntry.texture()) { 3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clampEntry = this->createAndLockTexture(key, NULL, desc, 3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcData, rowBytes); 3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != clampEntry.texture()); 3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == clampEntry.texture()) { 3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return entry; 3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTextureDesc rtDesc = desc; 3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rtDesc.fFlags = rtDesc.fFlags | 3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kRenderTarget_GrTextureFlagBit | 3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kNoStencil_GrTextureFlagBit; 3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rtDesc.fWidth = GrNextPow2(GrMax(desc.fWidth, 64)); 3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64)); 3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != texture) { 3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoStateRestore asr(fGpu); 3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = fGpu->drawState(); 3464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->reset(); 3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setRenderTarget(texture->asRenderTarget()); 3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setTexture(0, clampEntry.texture()); 3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSamplerState::Filter filter; 3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if filtering is not desired then we want to ensure all 3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // texels in the resampled image are copies of texels from 3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // the original. 3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (GrSamplerState::kNearest_Filter == sampler->getFilter()) { 3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger filter = GrSamplerState::kNearest_Filter; 3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger filter = GrSamplerState::kBilinear_Filter; 3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger filter); 3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const GrVertexLayout layout = 3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); 3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0); 3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (arg.succeeded()) { 3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPoint* verts = (GrPoint*) arg.vertices(); 3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[0].setIRectFan(0, 0, 3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texture->width(), 3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texture->height(), 3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2*sizeof(GrPoint)); 3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); 3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, 4); 3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger entry.set(fTextureCache->createAndLock(resourceKey, texture)); 3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texture->releaseRenderTarget(); 3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // TODO: Our CPU stretch doesn't filter. But we create separate 3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // stretched textures when the sampler state is either filtered or 3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // not. Either implement filtered stretch blit on CPU or just create 3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // one when FBO case fails. 3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rtDesc.fFlags = kNone_GrTextureFlags; 3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // no longer need to clamp at min RT size. 3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rtDesc.fWidth = GrNextPow2(desc.fWidth); 3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rtDesc.fHeight = GrNextPow2(desc.fHeight); 3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int bpp = GrBytesPerPixel(desc.fConfig); 3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAutoSMalloc<128*128*4> stretchedPixels(bpp * 3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rtDesc.fWidth * 3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rtDesc.fHeight); 3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcData, desc.fWidth, desc.fHeight, bpp); 3941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t stretchedRowBytes = rtDesc.fWidth * bpp; 3961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTexture* texture = fGpu->createTexture(rtDesc, 3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger stretchedPixels.get(), 3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger stretchedRowBytes); 4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != texture); 4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger entry.set(fTextureCache->createAndLock(resourceKey, texture)); 4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->unlock(clampEntry.cacheEntry()); 4041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 4061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes); 4071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != texture) { 4081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger entry.set(fTextureCache->createAndLock(resourceKey, texture)); 4091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return entry; 4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void gen_scratch_tex_key_values(const GrGpu* gpu, 4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrTextureDesc& desc, 4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]) { 4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Instead of a client-provided key of the texture contents 4191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we create a key of from the descriptor. 4204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrContext::TextureKey descKey = (desc.fFlags << 8) | 4211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ((uint64_t) desc.fConfig << 32); 4221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // this code path isn't friendly to tiling with NPOT restricitons 4231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // We just pass ClampNoFilter() 4241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gen_texture_key_values(gpu, NULL, descKey, desc.fWidth, 4254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger desc.fHeight, desc.fSampleCnt, true, v); 4261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4291cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::TextureCacheEntry GrContext::lockScratchTexture( 4301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrTextureDesc& inDesc, 4311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ScratchTexMatch match) { 4321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTextureDesc desc = inDesc; 4341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kExact_ScratchTexMatch != match) { 4351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // bin by pow2 with a reasonable min 4361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const int MIN_SIZE = 256; 4371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 4381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 4391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceEntry* entry; 4421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int origWidth = desc.fWidth; 4431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int origHeight = desc.fHeight; 4441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool doubledW = false; 4451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool doubledH = false; 4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 4481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]; 4491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gen_scratch_tex_key_values(fGpu, desc, v); 4501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceKey key(v); 4511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger entry = fTextureCache->findAndLock(key, 4521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceCache::kNested_LockType); 4531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we miss, relax the fit of the flags... 4541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // then try doubling width... then height. 4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != entry || kExact_ScratchTexMatch == match) { 4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!(desc.fFlags & kRenderTarget_GrTextureFlagBit)) { 4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fFlags = desc.fFlags | kRenderTarget_GrTextureFlagBit; 4601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 4611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (!doubledW) { 4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fFlags = inDesc.fFlags; 4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fWidth *= 2; 4651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger doubledW = true; 4661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (!doubledH) { 4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fFlags = inDesc.fFlags; 4681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fWidth = origWidth; 4691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fHeight *= 2; 4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger doubledH = true; 4711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 4721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 4731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (true); 4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == entry) { 4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fFlags = inDesc.fFlags; 4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fWidth = origWidth; 4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fHeight = origHeight; 4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTexture* texture = fGpu->createTexture(desc, NULL, 0); 4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != texture) { 4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t v[4]; 4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gen_scratch_tex_key_values(fGpu, desc, v); 4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrResourceKey key(v); 4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger entry = fTextureCache->createAndLock(key, texture); 4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // If the caller gives us the same desc/sampler twice we don't want 4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // to return the same texture the second time (unless it was previously 4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // released). So we detach the entry from the cache and reattach at release. 4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != entry) { 4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->detach(entry); 4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return TextureCacheEntry(entry); 4971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::unlockTexture(TextureCacheEntry entry) { 5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(entry.texture()); 5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // If this is a scratch texture we detached it from the cache 5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // while it was locked (to avoid two callers simultaneously getting 5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // the same texture). 5041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kScratchBit & entry.cacheEntry()->key().getValue32(3)) { 5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->reattachAndUnlock(entry.cacheEntry()); 5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->unlock(entry.cacheEntry()); 5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5111cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& desc, 5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void* srcData, 5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t rowBytes) { 5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->createTexture(desc, srcData, rowBytes); 5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::getTextureCacheLimits(int* maxTextures, 5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t* maxTextureBytes) const { 5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->getLimits(maxTextures, maxTextureBytes); 5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 5231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache->setLimits(maxTextures, maxTextureBytes); 5241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::getMaxTextureSize() const { 5271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->getCaps().fMaxTextureSize; 5281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::getMaxRenderTargetSize() const { 5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->getCaps().fMaxRenderTargetSize; 5321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 5351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5361cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) { 5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->createPlatformTexture(desc); 5381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5401cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) { 5411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->createPlatformRenderTarget(desc); 5421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 5451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::supportsIndex8PixelConfig(const GrSamplerState* sampler, 5471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, int height) const { 5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrDrawTarget::Caps& caps = fGpu->getCaps(); 5491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!caps.f8BitPaletteSupport) { 5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 5511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!isPow2) { 5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool tiled = NULL != sampler && 5571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (sampler->getWrapX() != GrSamplerState::kClamp_WrapMode || 5581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampler->getWrapY() != GrSamplerState::kClamp_WrapMode); 5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (tiled && !caps.fNPOTTextureTileSupport) { 5601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 5611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 5641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrClip& GrContext::getClip() const { return fGpu->getClip(); } 5691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setClip(const GrClip& clip) { 5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->setClip(clip); 5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawState()->enableState(GrDrawState::kClip_StateBit); 5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setClip(const GrIRect& rect) { 5761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrClip clip; 5771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clip.setFromIRect(rect); 5781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->setClip(clip); 5791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 5821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::clear(const GrIRect* rect, const GrColor color) { 5841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->flush(); 5851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->clear(rect, color); 5861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawPaint(const GrPaint& paint) { 5891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // set rect to be big enough to fill the space, but not super-huge, so we 5901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // don't overflow fixed-point implementations 5911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrRect r; 5921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger r.setLTRB(0, 0, 5931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrIntToScalar(getRenderTarget()->width()), 5941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrIntToScalar(getRenderTarget()->height())); 5951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix inverse; 5961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkTLazy<GrPaint> tmpPaint; 5971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrPaint* p = &paint; 5981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = fGpu->drawState(); 5991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAutoMatrix am; 6001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // We attempt to map r by the inverse matrix and draw that. mapRect will 6021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // map the four corners and bound them with a new rect. This will not 6031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // produce a correct result for some perspective matrices. 6041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!this->getMatrix().hasPerspective()) { 6051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!drawState->getViewInverse(&inverse)) { 6061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Could not invert matrix"); 6071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 6081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inverse.mapRect(&r); 6101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 6111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) { 6121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!drawState->getViewInverse(&inverse)) { 6131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Could not invert matrix"); 6141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 6151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmpPaint.set(paint); 6171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmpPaint.get()->preConcatActiveSamplerMatrices(inverse); 6181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger p = tmpPaint.get(); 6191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger am.set(this, GrMatrix::I()); 6211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // by definition this fills the entire clip, no need for AA 6231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.fAntiAlias) { 6241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!tmpPaint.isValid()) { 6251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmpPaint.set(paint); 6261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger p = tmpPaint.get(); 6271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(p == tmpPaint.get()); 6291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmpPaint.get()->fAntiAlias = false; 6301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->drawRect(*p, r); 6321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 6351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 6371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline bool disable_coverage_aa_for_blend(GrDrawTarget* target) { 6381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage(); 6391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 6431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* create a triangle strip that strokes the specified triangle. There are 8 6451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unique vertices, but we repreat the last 2 to close up. Alternatively we 6461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger could use an indices array, and then only send 8 verts, but not sure that 6471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger would be faster. 6481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 6491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect, 6501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrScalar width) { 6511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrScalar rad = GrScalarHalf(width); 6521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rect.sort(); 6531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[0].set(rect.fLeft + rad, rect.fTop + rad); 6551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[1].set(rect.fLeft - rad, rect.fTop - rad); 6561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[2].set(rect.fRight - rad, rect.fTop + rad); 6571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[3].set(rect.fRight + rad, rect.fTop - rad); 6581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[4].set(rect.fRight - rad, rect.fBottom - rad); 6591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[5].set(rect.fRight + rad, rect.fBottom + rad); 6601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 6611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 6621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[8] = verts[0]; 6631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts[9] = verts[1]; 6641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void setInsetFan(GrPoint* pts, size_t stride, 6671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrRect& r, GrScalar dx, GrScalar dy) { 6681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride); 6691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const uint16_t gFillAARectIdx[] = { 6721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, 1, 5, 5, 4, 0, 6731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1, 2, 6, 6, 5, 1, 6741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2, 3, 7, 7, 6, 2, 6751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3, 0, 4, 4, 7, 3, 6761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4, 5, 6, 6, 7, 4, 6771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 6781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::aaFillRectIndexCount() const { 6801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return GR_ARRAY_COUNT(gFillAARectIdx); 6811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6831cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrIndexBuffer* GrContext::aaFillRectIndexBuffer() { 6841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == fAAFillRectIndexBuffer) { 6851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fAAFillRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gFillAARectIdx), 6861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger false); 6871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != fAAFillRectIndexBuffer) { 6881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #if GR_DEBUG 6891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool updated = 6901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #endif 6911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fAAFillRectIndexBuffer->updateData(gFillAARectIdx, 6921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sizeof(gFillAARectIdx)); 6931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_DEBUGASSERT(updated); 6941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fAAFillRectIndexBuffer; 6971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const uint16_t gStrokeAARectIdx[] = { 7001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, 7011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, 7021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, 7031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, 7041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, 7061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, 7071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, 7081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, 7091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, 7111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, 7121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, 7131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, 7141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 7151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::aaStrokeRectIndexCount() const { 7171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return GR_ARRAY_COUNT(gStrokeAARectIdx); 7181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 7191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7201cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrIndexBuffer* GrContext::aaStrokeRectIndexBuffer() { 7211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == fAAStrokeRectIndexBuffer) { 7221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fAAStrokeRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gStrokeAARectIdx), 7231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger false); 7241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != fAAStrokeRectIndexBuffer) { 7251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #if GR_DEBUG 7261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool updated = 7271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #endif 7281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, 7291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sizeof(gStrokeAARectIdx)); 7301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_DEBUGASSERT(updated); 7311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fAAStrokeRectIndexBuffer; 7341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 7351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic GrVertexLayout aa_rect_layout(const GrDrawTarget* target, 7371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool useCoverage) { 7381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout = 0; 7391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int s = 0; s < GrDrawState::kNumStages; ++s) { 7401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != target->getDrawState().getTexture(s)) { 7411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); 7421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (useCoverage) { 7451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger layout |= GrDrawTarget::kCoverage_VertexLayoutBit; 7461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 7471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger layout |= GrDrawTarget::kColor_VertexLayoutBit; 7481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return layout; 7501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 7511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::fillAARect(GrDrawTarget* target, 7531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrRect& devRect, 7541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool useVertexCoverage) { 7551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 7561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t vsize = GrDrawTarget::VertexSize(layout); 7581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0); 7601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!geo.succeeded()) { 7611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to get space for vertices!\n"); 7621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 7631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(); 7651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == indexBuffer) { 7661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to create index buffer!\n"); 7671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 7681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 7711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 7731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 7741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setInsetFan(fan0Pos, vsize, devRect, -GR_ScalarHalf, -GR_ScalarHalf); 7761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setInsetFan(fan1Pos, vsize, devRect, GR_ScalarHalf, GR_ScalarHalf); 7771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts += sizeof(GrPoint); 7791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; ++i) { 7801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 7811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrColor innerColor; 7841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (useVertexCoverage) { 7851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger innerColor = 0xffffffff; 7861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 7871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger innerColor = target->getDrawState().getColor(); 7881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts += 4 * vsize; 7911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; ++i) { 7921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 7931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->setIndexSourceToBuffer(indexBuffer); 7961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawIndexed(kTriangles_PrimitiveType, 0, 7981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, 8, this->aaFillRectIndexCount()); 7991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::strokeAARect(GrDrawTarget* target, 8021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrRect& devRect, 8031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrVec& devStrokeSize, 8041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool useVertexCoverage) { 8051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrScalar& dx = devStrokeSize.fX; 8061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrScalar& dy = devStrokeSize.fY; 8071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrScalar rx = GrMul(dx, GR_ScalarHalf); 8081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrScalar ry = GrMul(dy, GR_ScalarHalf); 8091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrScalar spare; 8111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 8121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrScalar w = devRect.width() - dx; 8131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrScalar h = devRect.height() - dy; 8141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger spare = GrMin(w, h); 8151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (spare <= 0) { 8181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrRect r(devRect); 8191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger r.inset(-rx, -ry); 8201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fillAARect(target, r, useVertexCoverage); 8211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 8221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 8241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t vsize = GrDrawTarget::VertexSize(layout); 8251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0); 8271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!geo.succeeded()) { 8281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to get space for vertices!\n"); 8291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 8301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(); 8321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == indexBuffer) { 8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to create index buffer!\n"); 8341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 8351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 8381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 8401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 8411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); 8421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); 8431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setInsetFan(fan0Pos, vsize, devRect, -rx - GR_ScalarHalf, -ry - GR_ScalarHalf); 8451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setInsetFan(fan1Pos, vsize, devRect, -rx + GR_ScalarHalf, -ry + GR_ScalarHalf); 8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setInsetFan(fan2Pos, vsize, devRect, rx - GR_ScalarHalf, ry - GR_ScalarHalf); 8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setInsetFan(fan3Pos, vsize, devRect, rx + GR_ScalarHalf, ry + GR_ScalarHalf); 8481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts += sizeof(GrPoint); 8501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; ++i) { 8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrColor innerColor; 8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (useVertexCoverage) { 8561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger innerColor = 0xffffffff; 8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 8581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger innerColor = target->getDrawState().getColor(); 8591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts += 4 * vsize; 8611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 8; ++i) { 8621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger verts += 8 * vsize; 8661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 8; ++i) { 8671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 8681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->setIndexSourceToBuffer(indexBuffer); 8711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawIndexed(kTriangles_PrimitiveType, 8721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, 0, 16, aaStrokeRectIndexCount()); 8731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/** 8761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Returns true if the rects edges are integer-aligned. 8771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 8781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isIRect(const GrRect& r) { 8791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && 8801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom); 8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool apply_aa_to_rect(GrDrawTarget* target, 8841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrRect& rect, 8851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrScalar width, 8861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrMatrix* matrix, 8871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix* combinedMatrix, 8881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrRect* devRect, 8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool* useVertexCoverage) { 8904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // we use a simple coverage ramp to do aa on axis-aligned rects 8914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // we check if the rect will be axis-aligned, and the rect won't land on 8924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // integer coords. 8931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we are keeping around the "tweak the alpha" trick because 8951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // it is our only hope for the fixed-pipe implementation. 8961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // In a shader implementation we can give a separate coverage input 8971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // TODO: remove this ugliness when we drop the fixed-pipe impl 8981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *useVertexCoverage = false; 8991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!target->canTweakAlphaForCoverage()) { 9004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (disable_coverage_aa_for_blend(target)) { 9011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DEBUG 9024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger //GrPrintf("Turning off AA to correctly apply blend.\n"); 9031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 9041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 9054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 9064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *useVertexCoverage = true; 9071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrDrawState& drawState = target->getDrawState(); 9101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (drawState.getRenderTarget()->isMultisampled()) { 9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 9121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == width && target->willUseHWAALines()) { 9151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 9161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!drawState.getViewMatrix().preservesAxisAlignment()) { 9191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 9201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != matrix && 9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger !matrix->preservesAxisAlignment()) { 9241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 9251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *combinedMatrix = drawState.getViewMatrix(); 9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != matrix) { 9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger combinedMatrix->preConcat(*matrix); 9301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(combinedMatrix->preservesAxisAlignment()); 9311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger combinedMatrix->mapRect(devRect, rect); 9341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger devRect->sort(); 9351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (width < 0) { 9371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !isIRect(*devRect); 9381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 9391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 9401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 9421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawRect(const GrPaint& paint, 9441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrRect& rect, 9451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrScalar width, 9461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrMatrix* matrix) { 9471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT0("GrContext::drawRect"); 9481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 9501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int stageMask = paint.getActiveStageMask(); 9511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrRect devRect = rect; 9531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix combinedMatrix; 9541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool useVertexCoverage; 9551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool needAA = paint.fAntiAlias && 9561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger !this->getRenderTarget()->isMultisampled(); 9571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 9581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &combinedMatrix, &devRect, 9591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &useVertexCoverage); 9601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (doAA) { 9621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 9631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (width >= 0) { 9641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVec strokeSize;; 9651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (width > 0) { 9661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger strokeSize.set(width, width); 9671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger combinedMatrix.mapVectors(&strokeSize, 1); 9681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger strokeSize.setAbs(strokeSize); 9691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 9701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger strokeSize.set(GR_Scalar1, GR_Scalar1); 9711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger strokeAARect(target, devRect, strokeSize, useVertexCoverage); 9731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 9741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fillAARect(target, devRect, useVertexCoverage); 9751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 9771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (width >= 0) { 9801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // TODO: consider making static vertex buffers for these cases. 9811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Hairline could be done by just adding closing vertex to 9821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // unitSquareVertexBuffer() 9831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 9841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const int worstCaseVertCount = 10; 9861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0); 9871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!geo.succeeded()) { 9891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to get space for vertices!\n"); 9901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 9911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrimitiveType primType; 9941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int vertCount; 9951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPoint* vertex = geo.positions(); 9961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (width > 0) { 9981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vertCount = 10; 9991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger primType = kTriangleStrip_PrimitiveType; 10001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger setStrokeRectStrip(vertex, rect, width); 10011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 10021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // hairline 10031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vertCount = 5; 10041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger primType = kLineStrip_PrimitiveType; 10051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vertex[0].set(rect.fLeft, rect.fTop); 10061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vertex[1].set(rect.fRight, rect.fTop); 10071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vertex[2].set(rect.fRight, rect.fBottom); 10081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vertex[3].set(rect.fLeft, rect.fBottom); 10091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vertex[4].set(rect.fLeft, rect.fTop); 10101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState::AutoViewMatrixRestore avmr; 10131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != matrix) { 10141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = target->drawState(); 10151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger avmr.set(drawState); 10161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->preConcatViewMatrix(*matrix); 10171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->preConcatSamplerMatrices(stageMask, *matrix); 10181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawNonIndexed(primType, 0, vertCount); 10211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 10221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_STATIC_RECT_VB 10231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 10241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 10251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == sqVB) { 10261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to create static rect vb.\n"); 10271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 10281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->setVertexSourceToBuffer(layout, sqVB); 10301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = target->drawState(); 10311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState::AutoViewMatrixRestore avmr(drawState); 10321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix m; 10331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m.setAll(rect.width(), 0, rect.fLeft, 10341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, rect.height(), rect.fTop, 10351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, 0, GrMatrix::I()[8]); 10361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != matrix) { 10381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m.postConcat(*matrix); 10391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->preConcatViewMatrix(m); 10411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->preConcatSamplerMatrices(stageMask, m); 10421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 10441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 10451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawSimpleRect(rect, matrix, stageMask); 10461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 10471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 10491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawRectToRect(const GrPaint& paint, 10511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrRect& dstRect, 10521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrRect& srcRect, 10531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrMatrix* dstMatrix, 10541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrMatrix* srcMatrix) { 10551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT0("GrContext::drawRectToRect"); 10561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // srcRect refers to paint's first texture 10581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == paint.getTexture(0)) { 10591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawRect(paint, dstRect, -1, dstMatrix); 10601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 10611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB); 10641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_STATIC_RECT_VB 10661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 10671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = target->drawState(); 10681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 10691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState::AutoViewMatrixRestore avmr(drawState); 10701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix m; 10721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m.setAll(dstRect.width(), 0, dstRect.fLeft, 10741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, dstRect.height(), dstRect.fTop, 10751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, 0, GrMatrix::I()[8]); 10761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != dstMatrix) { 10771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m.postConcat(*dstMatrix); 10781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->preConcatViewMatrix(m); 10801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // srcRect refers to first stage 10821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int otherStageMask = paint.getActiveStageMask() & 10831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (~(1 << GrPaint::kFirstTextureStage)); 10841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (otherStageMask) { 10851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->preConcatSamplerMatrices(otherStageMask, m); 10861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m.setAll(srcRect.width(), 0, srcRect.fLeft, 10891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, srcRect.height(), srcRect.fTop, 10901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0, 0, GrMatrix::I()[8]); 10911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != srcMatrix) { 10921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m.postConcat(*srcMatrix); 10931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m); 10951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 10971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == sqVB) { 10981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to create static rect vb.\n"); 10991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 11001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->setVertexSourceToBuffer(layout, sqVB); 11021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 11031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 11041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget* target; 11061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if BATCH_RECT_TO_RECT 11071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = this->prepareToDraw(paint, kBuffered_DrawCategory); 11081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 11091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 11101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 11111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 11131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; 11141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcRects[0] = &srcRect; 11151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger srcMatrices[0] = srcMatrix; 11161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices); 11181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 11191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 11201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawVertices(const GrPaint& paint, 11221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrimitiveType primitiveType, 11231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int vertexCount, 11241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrPoint positions[], 11251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrPoint texCoords[], 11261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrColor colors[], 11271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint16_t indices[], 11281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int indexCount) { 11291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT0("GrContext::drawVertices"); 11301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoReleaseGeometry geo; 11321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 11341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool hasTexCoords[GrPaint::kTotalStages] = { 11361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger NULL != texCoords, // texCoordSrc provides explicit stage 0 coords 11371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0 // remaining stages use positions 11381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 11391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); 11411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != colors) { 11431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger layout |= GrDrawTarget::kColor_VertexLayoutBit; 11441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int vertexSize = GrDrawTarget::VertexSize(layout); 11461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (sizeof(GrPoint) != vertexSize) { 11481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!geo.set(target, layout, vertexCount, 0)) { 11491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to get space for vertices!\n"); 11501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 11511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int texOffsets[GrDrawState::kMaxTexCoords]; 11531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int colorOffset; 11541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, 11551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texOffsets, 11561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &colorOffset, 11571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger NULL, 11581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger NULL); 11591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void* curVertex = geo.vertices(); 11601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < vertexCount; ++i) { 11621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *((GrPoint*)curVertex) = positions[i]; 11631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (texOffsets[0] > 0) { 11651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; 11661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (colorOffset > 0) { 11681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 11691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger curVertex = (void*)((intptr_t)curVertex + vertexSize); 11711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 11731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->setVertexSourceToArray(layout, positions, vertexCount); 11741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we don't currently apply offscreen AA to this path. Need improved 11771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // management of GrDrawTarget's geometry to avoid copying points per-tile. 11781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != indices) { 11801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->setIndexSourceToArray(indices, indexCount); 11811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 11821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 11831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->drawNonIndexed(primitiveType, 0, vertexCount); 11841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 11861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 11884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkDraw.h" 11894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkRasterClip.h" 11904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 11914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergernamespace { 11924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 11934f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkPath::FillType gr_fill_to_sk_fill(GrPathFill fill) { 11944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger switch (fill) { 11954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case kWinding_PathFill: 11964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkPath::kWinding_FillType; 11974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case kEvenOdd_PathFill: 11984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkPath::kEvenOdd_FillType; 11994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case kInverseWinding_PathFill: 12004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkPath::kInverseWinding_FillType; 12014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case kInverseEvenOdd_PathFill: 12024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkPath::kInverseEvenOdd_FillType; 12034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger default: 12044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrCrash("Unexpected fill."); 12054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkPath::kWinding_FillType; 12064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 12084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 12094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger// gets device coord bounds of path (not considering the fill) and clip. The 12104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger// path bounds will be a subset of the clip bounds. returns false if path bounds 12114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger// would be empty. 12124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool get_path_and_clip_bounds(const GrDrawTarget* target, 12134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrPath& path, 12144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrVec* translate, 12154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrIRect* pathBounds, 12164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrIRect* clipBounds) { 12174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // compute bounds as intersection of rt size, clip, and path 12184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 12194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (NULL == rt) { 12204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 12214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *pathBounds = GrIRect::MakeWH(rt->width(), rt->height()); 12234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrClip& clip = target->getClip(); 12244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (clip.hasConservativeBounds()) { 12254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clip.getConservativeBounds().roundOut(clipBounds); 12264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!pathBounds->intersect(*clipBounds)) { 12274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 12284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 12304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // pathBounds is currently the rt extent, set clip bounds to that rect. 12314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *clipBounds = *pathBounds; 12324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrRect pathSBounds = path.getBounds(); 12344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!pathSBounds.isEmpty()) { 12354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (NULL != translate) { 12364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pathSBounds.offset(*translate); 12374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->getDrawState().getViewMatrix().mapRect(&pathSBounds, 12394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pathSBounds); 12404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrIRect pathIBounds; 12414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pathSBounds.roundOut(&pathIBounds); 12424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!pathBounds->intersect(pathIBounds)) { 12434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 12444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 12464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 12474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 12494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 12504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 12514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/** 12524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * sw rasterizes path to A8 mask using the context's matrix and uploads to a 12534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * scratch texture. 12544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 12554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 12564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool sw_draw_path_to_mask_texture(const GrPath& clientPath, 12574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrIRect& pathDevBounds, 12584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrPathFill fill, 12594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrContext* context, 12604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrPoint* translate, 12614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAutoScratchTexture* tex) { 12624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkPaint paint; 12634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkPath tmpPath; 12644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPath* pathToDraw = &clientPath; 12654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (kHairLine_PathFill == fill) { 12664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint.setStyle(SkPaint::kStroke_Style); 12674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint.setStrokeWidth(SK_Scalar1); 12684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 12694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint.setStyle(SkPaint::kFill_Style); 12704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkPath::FillType skfill = gr_fill_to_sk_fill(fill); 12714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (skfill != pathToDraw->getFillType()) { 12724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger tmpPath = *pathToDraw; 12734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger tmpPath.setFillType(skfill); 12744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pathToDraw = &tmpPath; 12754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint.setAntiAlias(true); 12784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint.setColor(SK_ColorWHITE); 12794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 12804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrMatrix matrix = context->getMatrix(); 12814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (NULL != translate) { 12824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger matrix.postTranslate(translate->fX, translate->fY); 12834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 12854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger matrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1, 12864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger -pathDevBounds.fTop * SK_Scalar1); 12874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(), 12884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pathDevBounds.height()); 12894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 12904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkBitmap bm; 12914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bm.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom); 12924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!bm.allocPixels()) { 12934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 12944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 12954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger sk_bzero(bm.getPixels(), bm.getSafeSize()); 12964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 12974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkDraw draw; 12984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger sk_bzero(&draw, sizeof(draw)); 12994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRasterClip rc(bounds); 13004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger draw.fRC = &rc; 13014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger draw.fClip = &rc.bwRgn(); 13024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger draw.fMatrix = &matrix; 13034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger draw.fBitmap = &bm; 13044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger draw.drawPath(*pathToDraw, paint); 13054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrTextureDesc desc = { 13074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger kNone_GrTextureFlags, 13084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bounds.fRight, 13094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bounds.fBottom, 13104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger kAlpha_8_GrPixelConfig, 13114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger {0} // samples 13124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger }; 13134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger tex->set(context, desc); 13154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrTexture* texture = tex->texture(); 13164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (NULL == texture) { 13184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 13194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkAutoLockPixels alp(bm); 13214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 13224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bm.getPixels(), bm.rowBytes()); 13234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 13244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid draw_around_inv_path(GrDrawTarget* target, 13274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrDrawState::StageMask stageMask, 13284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrIRect& clipBounds, 13294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrIRect& pathBounds) { 13304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 13314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrRect rect; 13324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (clipBounds.fTop < pathBounds.fTop) { 13334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rect.iset(clipBounds.fLeft, clipBounds.fTop, 13344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clipBounds.fRight, pathBounds.fTop); 13354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->drawSimpleRect(rect, NULL, stageMask); 13364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (clipBounds.fLeft < pathBounds.fLeft) { 13384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rect.iset(clipBounds.fLeft, pathBounds.fTop, 13394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pathBounds.fLeft, pathBounds.fBottom); 13404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->drawSimpleRect(rect, NULL, stageMask); 13414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (clipBounds.fRight > pathBounds.fRight) { 13434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rect.iset(pathBounds.fRight, pathBounds.fTop, 13444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clipBounds.fRight, pathBounds.fBottom); 13454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->drawSimpleRect(rect, NULL, stageMask); 13464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (clipBounds.fBottom > pathBounds.fBottom) { 13484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rect.iset(clipBounds.fLeft, pathBounds.fBottom, 13494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clipBounds.fRight, clipBounds.fBottom); 13504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->drawSimpleRect(rect, NULL, stageMask); 13514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawPath(const GrPaint& paint, const GrPath& path, 13571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPathFill fill, const GrPoint* translate) { 13581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (path.isEmpty()) { 13601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (GrIsFillInverted(fill)) { 13611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->drawPaint(paint); 13621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 13641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 13674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrDrawState::StageMask stageMask = paint.getActiveStageMask(); 13681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled(); 13701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // An Assumption here is that path renderer would use some form of tweaking 13721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // the src color (either the input alpha or in the frag shader) to implement 13731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // aa. If we have some future driver-mojo path AA that can do the right 13741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // thing WRT to the blend then we'll need some query on the PR. 13751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (disable_coverage_aa_for_blend(target)) { 13761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DEBUG 13771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger //GrPrintf("Turning off AA to correctly apply blend.\n"); 13781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 13791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prAA = false; 13801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPathRenderer* pr = NULL; 13831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (prAA) { 13844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pr = this->getPathRenderer(path, fill, target, true); 13851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == pr) { 13864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAutoScratchTexture ast; 13874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrIRect pathBounds, clipBounds; 13884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!get_path_and_clip_bounds(target, path, translate, 13894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &pathBounds, &clipBounds)) { 13904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return; 13914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (NULL == pr && sw_draw_path_to_mask_texture(path, pathBounds, 13934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fill, this, 13944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger translate, &ast)) { 13954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrTexture* texture = ast.texture(); 13964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(NULL != texture); 13974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 13984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger enum { 13994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger kPathMaskStage = GrPaint::kTotalStages, 14004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger }; 14014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->drawState()->setTexture(kPathMaskStage, texture); 14024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->drawState()->sampler(kPathMaskStage)->reset(); 14034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrScalar w = GrIntToScalar(pathBounds.width()); 14044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrScalar h = GrIntToScalar(pathBounds.height()); 14054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrRect maskRect = GrRect::MakeWH(w / texture->width(), 14064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger h / texture->height()); 14074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 14084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger srcRects[kPathMaskStage] = &maskRect; 14094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger stageMask |= 1 << kPathMaskStage; 14104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrRect dstRect = GrRect::MakeLTRB( 14114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SK_Scalar1* pathBounds.fLeft, 14124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SK_Scalar1* pathBounds.fTop, 14134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SK_Scalar1* pathBounds.fRight, 14144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SK_Scalar1* pathBounds.fBottom); 14154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->drawRect(dstRect, NULL, stageMask, srcRects, NULL); 14164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->drawState()->setTexture(kPathMaskStage, NULL); 14174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (GrIsFillInverted(fill)) { 14184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger draw_around_inv_path(target, stageMask, 14194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger clipBounds, pathBounds); 14204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 14214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return; 14224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 14231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 14254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pr = this->getPathRenderer(path, fill, target, false); 14261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == pr) { 14291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DEBUG 14301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Unable to find path renderer compatible with path.\n"); 14311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 14321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 14331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pr->drawPath(path, fill, translate, target, stageMask, prAA); 14361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 14391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::flush(int flagsBitfield) { 14411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kDiscard_FlushBit & flagsBitfield) { 14421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer->reset(); 14431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 14441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->flushDrawBuffer(); 14451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { 14471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->forceRenderTargetFlush(); 14481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::flushText() { 14521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kText_DrawCategory == fLastDrawCategory) { 14531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flushDrawBuffer(); 14541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::flushDrawBuffer() { 14581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING 14591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fDrawBuffer) { 14601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer->playback(fGpu); 14611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer->reset(); 14621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 14641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::internalWriteTexturePixels(GrTexture* texture, 14671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int left, int top, 14681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, int height, 14691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfig config, 14701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const void* buffer, 14711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t rowBytes, 14721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t flags) { 14731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 14741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(texture); 14751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!(kDontFlush_PixelOpsFlag & flags)) { 14771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->flush(); 14781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // TODO: use scratch texture to perform conversion 14801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (GrPixelConfigIsUnpremultiplied(texture->config()) != 14811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfigIsUnpremultiplied(config)) { 14821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 14831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->writeTexturePixels(texture, left, top, width, height, 14861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config, buffer, rowBytes); 14871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::internalReadTexturePixels(GrTexture* texture, 14901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int left, int top, 14911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, int height, 14921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfig config, 14931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void* buffer, 14941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t rowBytes, 14951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t flags) { 14961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT0("GrContext::readTexturePixels"); 14971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(texture); 14981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // TODO: code read pixels for textures that aren't also rendertargets 15001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrRenderTarget* target = texture->asRenderTarget(); 15011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != target) { 15021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return this->internalReadRenderTargetPixels(target, 15031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger left, top, width, height, 15041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config, buffer, rowBytes, 15051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flags); 15061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 15071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 15081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 15101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkConfig8888.h" 15124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergernamespace { 15144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/** 15154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 15164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * formats are representable as Config8888 and so the function returns false 15174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * if the GrPixelConfig has no equivalent Config8888. 15184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 15194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool grconfig_to_config8888(GrPixelConfig config, 15204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkCanvas::Config8888* config8888) { 15214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger switch (config) { 15224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case kRGBA_8888_PM_GrPixelConfig: 15234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *config8888 = SkCanvas::kRGBA_Premul_Config8888; 15244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 15254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case kRGBA_8888_UPM_GrPixelConfig: 15264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 15274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 15284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case kBGRA_8888_PM_GrPixelConfig: 15294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *config8888 = SkCanvas::kBGRA_Premul_Config8888; 15304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 15314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case kBGRA_8888_UPM_GrPixelConfig: 15324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 15334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 15344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger default: 15354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 15364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 15384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 15394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, 15411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int left, int top, 15421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, int height, 15431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfig config, 15441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void* buffer, 15451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t rowBytes, 15461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t flags) { 15471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 15481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(target); 15491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == target) { 15511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = fGpu->drawState()->getRenderTarget(); 15521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == target) { 15531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 15541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!(kDontFlush_PixelOpsFlag & flags)) { 15581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->flush(); 15591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!GrPixelConfigIsUnpremultiplied(target->config()) && 15624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrPixelConfigIsUnpremultiplied(config) && 15634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger !fGpu->canPreserveReadWriteUnpremulPixels()) { 15644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkCanvas::Config8888 srcConfig8888, dstConfig8888; 15654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!grconfig_to_config8888(target->config(), &srcConfig8888) || 15664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger !grconfig_to_config8888(config, &dstConfig8888)) { 15674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 15684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // do read back using target's own config 15704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->internalReadRenderTargetPixels(target, 15714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger left, top, 15724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger width, height, 15734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->config(), 15744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger buffer, rowBytes, 15754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger kDontFlush_PixelOpsFlag); 15764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // sw convert the pixels to unpremul config 15774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger uint32_t* pixels = reinterpret_cast<uint32_t*>(buffer); 15784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkConvertConfig8888Pixels(pixels, rowBytes, dstConfig8888, 15794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger pixels, rowBytes, srcConfig8888, 15804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger width, height); 15814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 15824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTexture* src = target->asTexture(); 15851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool swapRAndB = NULL != src && 15861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->preferredReadPixelsConfig(config) == 15871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfigSwapRAndB(config); 15881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool flipY = NULL != src && 15901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->readPixelsWillPayForYFlip(target, left, top, 15911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger width, height, config, 15921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rowBytes); 15931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) && 15941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfigIsUnpremultiplied(config)); 15951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == src && alphaConversion) { 15971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we should fallback to cpu conversion here. This could happen when 15981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we were given an external render target by the client that is not 15991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // also a texture (e.g. FBO 0 in GL) 16001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 16011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 16021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we draw to a scratch texture if any of these conversion are applied 16031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAutoScratchTexture ast; 16041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (flipY || swapRAndB || alphaConversion) { 16051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != src); 16061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (swapRAndB) { 16071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config = GrPixelConfigSwapRAndB(config); 16081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnknown_GrPixelConfig != config); 16091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 16101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Make the scratch a render target because we don't have a robust 16111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // readTexturePixels as of yet (it calls this function). 16121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrTextureDesc desc = { 16131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kRenderTarget_GrTextureFlagBit, 16141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger width, height, 16154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger config, 16164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger {0}, // samples 16171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 16181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // When a full readback is faster than a partial we could always make 16201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // the scratch exactly match the passed rect. However, if we see many 16211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // different size rectangles we will trash our texture cache and pay the 16221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // cost of creating and destroying many textures. So, we only request 16231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // an exact match when the caller is reading an entire RT. 16241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ScratchTexMatch match = kApprox_ScratchTexMatch; 16251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == left && 16261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 0 == top && 16271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->width() == width && 16281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target->height() == height && 16291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->fullReadPixelsIsFasterThanPartial()) { 16301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger match = kExact_ScratchTexMatch; 16311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 16321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ast.set(this, desc, match); 16331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTexture* texture = ast.texture(); 16341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!texture) { 16351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 16361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 16371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = texture->asRenderTarget(); 16381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != target); 16391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoStateRestore asr(fGpu); 16411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = fGpu->drawState(); 16424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->reset(); 16431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setRenderTarget(target); 16441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix matrix; 16461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (flipY) { 16471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger matrix.setTranslate(SK_Scalar1 * left, 16481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_Scalar1 * (top + height)); 16491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger matrix.set(GrMatrix::kMScaleY, -GR_Scalar1); 16501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 16511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 16521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 16531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger matrix.postIDiv(src->width(), src->height()); 16541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->sampler(0)->reset(matrix); 16551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->sampler(0)->setRAndBSwap(swapRAndB); 16561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setTexture(0, src); 16571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrRect rect; 16581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height); 16591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawSimpleRect(rect, NULL, 0x1); 16601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger left = 0; 16611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger top = 0; 16621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 16631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->readPixels(target, 16641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger left, top, width, height, 16651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config, buffer, rowBytes, flipY); 16661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 16671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 16694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(target); 16704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger ASSERT_OWNED_RESOURCE(target); 16714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // In the future we may track whether there are any pending draws to this 16724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // target. We don't today so we always perform a flush. We don't promise 16734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // this to our clients, though. 16744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->flush(); 16754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fGpu->resolveRenderTarget(target); 16764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 16774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { 16791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == src || NULL == dst) { 16801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 16811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 16821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(src); 16831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoStateRestore asr(fGpu); 16851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = fGpu->drawState(); 16864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->reset(); 16871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setRenderTarget(dst); 16881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix sampleM; 16891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleM.setIDiv(src->width(), src->height()); 16901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setTexture(0, src); 16911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->sampler(0)->reset(sampleM); 16924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRect rect = SkRect::MakeXYWH(0, 0, 16934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SK_Scalar1 * src->width(), 16944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SK_Scalar1 * src->height()); 16951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawSimpleRect(rect, NULL, 1 << 0); 16961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 16971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, 16991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int left, int top, 17001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int width, int height, 17011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfig config, 17021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const void* buffer, 17031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger size_t rowBytes, 17041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint32_t flags) { 17051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 17061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(target); 17071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == target) { 17091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = fGpu->drawState()->getRenderTarget(); 17101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == target) { 17111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 17121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 17131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 17141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // TODO: when underlying api has a direct way to do this we should use it 17161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // (e.g. glDrawPixels on desktop GL). 17171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // If the RT is also a texture and we don't have to do PM/UPM conversion 17191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // then take the texture path, which we expect to be at least as fast or 17201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // faster since it doesn't use an intermediate texture as we do below. 17211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if !GR_MAC_BUILD 17231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // At least some drivers on the Mac get confused when glTexImage2D is called 17241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // on a texture attached to an FBO. The FBO still sees the old image. TODO: 17251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // determine what OS versions and/or HW is affected. 17261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != target->asTexture() && 17271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfigIsUnpremultiplied(target->config()) == 17281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfigIsUnpremultiplied(config)) { 17291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->internalWriteTexturePixels(target->asTexture(), 17311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger left, top, width, height, 17321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config, buffer, rowBytes, flags); 17331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 17341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 17351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 17364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!GrPixelConfigIsUnpremultiplied(target->config()) && 17374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrPixelConfigIsUnpremultiplied(config) && 17384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger !fGpu->canPreserveReadWriteUnpremulPixels()) { 17394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkCanvas::Config8888 srcConfig8888, dstConfig8888; 17404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!grconfig_to_config8888(config, &srcConfig8888) || 17414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger !grconfig_to_config8888(target->config(), &dstConfig8888)) { 17424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return; 17434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 17444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // allocate a tmp buffer and sw convert the pixels to premul 17454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(width * height); 17464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 17474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 17484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger src, rowBytes, srcConfig8888, 17494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger width, height); 17504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // upload the already premul pixels 17514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->internalWriteRenderTargetPixels(target, 17524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger left, top, 17534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger width, height, 17544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger target->config(), 17554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger tmpPixels, 4 * width, flags); 17564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return; 17574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 17581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool swapRAndB = fGpu->preferredReadPixelsConfig(config) == 17601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPixelConfigSwapRAndB(config); 17611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (swapRAndB) { 17621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config = GrPixelConfigSwapRAndB(config); 17631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 17641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrTextureDesc desc = { 17664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger kNone_GrTextureFlags, width, height, config, {0} 17671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 17681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAutoScratchTexture ast(this, desc); 17691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrTexture* texture = ast.texture(); 17701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == texture) { 17711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 17721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 17731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->internalWriteTexturePixels(texture, 0, 0, width, height, 17741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger config, buffer, rowBytes, flags); 17751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoStateRestore asr(fGpu); 17771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = fGpu->drawState(); 17784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->reset(); 17791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix matrix; 17811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); 17821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setViewMatrix(matrix); 17831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setRenderTarget(target); 17841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setTexture(0, texture); 17851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger matrix.setIDiv(texture->width(), texture->height()); 17871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 17881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSamplerState::kNearest_Filter, 17891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger matrix); 17901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->sampler(0)->setRAndBSwap(swapRAndB); 17911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); 17931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const int VCOUNT = 4; 17941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // TODO: Use GrGpu::drawRect here 17951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0); 17961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!geo.succeeded()) { 17971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Failed to get space for vertices!\n"); 17981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 17991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); 18011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT); 18021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 18031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 18041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) { 18061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = target->drawState(); 18071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < GrPaint::kMaxTextures; ++i) { 18091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int s = i + GrPaint::kFirstTextureStage; 18101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setTexture(s, paint.getTexture(i)); 18111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(paint.getTexture(i)); 18121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getTexture(i)) { 18131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *drawState->sampler(s) = paint.getTextureSampler(i); 18141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setFirstCoverageStage(GrPaint::kFirstMaskStage); 18181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < GrPaint::kMaxMasks; ++i) { 18201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int s = i + GrPaint::kFirstMaskStage; 18211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setTexture(s, paint.getMask(i)); 18221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(paint.getMask(i)); 18231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getMask(i)) { 18241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *drawState->sampler(s) = paint.getMaskSampler(i); 18251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setColor(paint.fColor); 18291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.fDither) { 18311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->enableState(GrDrawState::kDither_StateBit); 18321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 18331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->disableState(GrDrawState::kDither_StateBit); 18341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.fAntiAlias) { 18361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->enableState(GrDrawState::kHWAntialias_StateBit); 18371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 18381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->disableState(GrDrawState::kHWAntialias_StateBit); 18391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.fColorMatrixEnabled) { 18411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->enableState(GrDrawState::kColorMatrix_StateBit); 18421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 18431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->disableState(GrDrawState::kColorMatrix_StateBit); 18441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); 18461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); 18471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setColorMatrix(paint.fColorMatrix); 18484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->setCoverage(paint.fCoverage); 18491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) { 18511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 18521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 18541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18551cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 18561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger DrawCategory category) { 18571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (category != fLastDrawCategory) { 18581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flushDrawBuffer(); 18591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fLastDrawCategory = category; 18601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setPaint(paint, fGpu); 18621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget* target = fGpu; 18631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (category) { 18641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case kText_DrawCategory: 18651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if DEFER_TEXT_RENDERING 18661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = fDrawBuffer; 18671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer->initializeDrawStateAndClip(*fGpu); 18681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 18691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = fGpu; 18701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 18711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 18721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case kUnbuffered_DrawCategory: 18731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = fGpu; 18741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 18751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case kBuffered_DrawCategory: 18761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = fDrawBuffer; 18771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer->initializeDrawStateAndClip(*fGpu); 18781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 18791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return target; 18811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 18821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18831cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrPathRenderer* GrContext::getPathRenderer(const GrPath& path, 18841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPathFill fill, 18854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrDrawTarget* target, 18861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool antiAlias) { 18871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == fPathRendererChain) { 18881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fPathRendererChain = 18891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag); 18901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fPathRendererChain->getPathRenderer(path, fill, target, antiAlias); 18921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 18931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 18951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setRenderTarget(GrRenderTarget* target) { 18971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(target); 18981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->flush(false); 18991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawState()->setRenderTarget(target); 19001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19021cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrRenderTarget* GrContext::getRenderTarget() { 19031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->drawState()->getRenderTarget(); 19041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrRenderTarget* GrContext::getRenderTarget() const { 19071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->getDrawState().getRenderTarget(); 19081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrMatrix& GrContext::getMatrix() const { 19111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->getDrawState().getViewMatrix(); 19121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setMatrix(const GrMatrix& m) { 19151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawState()->setViewMatrix(m); 19161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::concatMatrix(const GrMatrix& m) const { 19191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawState()->preConcatViewMatrix(m); 19201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 19231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger intptr_t mask = 1 << shift; 19241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (pred) { 19251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bits |= mask; 19261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 19271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bits &= ~mask; 19281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 19291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return bits; 19301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::resetStats() { 19331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->resetStats(); 19341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrGpuStats& GrContext::getStats() const { 19371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->getStats(); 19381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::printStats() const { 19411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->printStats(); 19421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19441cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::GrContext(GrGpu* gpu) { 19451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu = gpu; 19461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->ref(); 19471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->setContext(this); 19481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fPathRendererChain = NULL; 19501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fTextureCache = new GrResourceCache(MAX_TEXTURE_CACHE_COUNT, 19521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger MAX_TEXTURE_CACHE_BYTES); 19531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fFontCache = new GrFontCache(fGpu); 19541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fLastDrawCategory = kUnbuffered_DrawCategory; 19561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer = NULL; 19581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBufferVBAllocPool = NULL; 19591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBufferIBAllocPool = NULL; 19601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fAAFillRectIndexBuffer = NULL; 19621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fAAStrokeRectIndexBuffer = NULL; 19631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setupDrawBuffer(); 19651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setupDrawBuffer() { 19681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL == fDrawBuffer); 19701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL == fDrawBufferVBAllocPool); 19711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL == fDrawBufferIBAllocPool); 19721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT 19741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBufferVBAllocPool = 19751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger new GrVertexBufferAllocPool(fGpu, false, 19761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 19771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS); 19781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBufferIBAllocPool = 19791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger new GrIndexBufferAllocPool(fGpu, false, 19801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 19811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS); 19821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer = new GrInOrderDrawBuffer(fGpu, 19841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBufferVBAllocPool, 19851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBufferIBAllocPool); 19861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 19871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if BATCH_RECT_TO_RECT 19891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); 19901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 19911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19931cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { 19941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget* target; 19951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if DEFER_TEXT_RENDERING 19961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = prepareToDraw(paint, kText_DrawCategory); 19971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 19981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger target = prepareToDraw(paint, kUnbuffered_DrawCategory); 19991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 20001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setPaint(paint, target); 20011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return target; 20021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 20031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 20051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fGpu->getQuadIndexBuffer(); 20061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 20071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::convolve(GrTexture* texture, 20091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkRect& rect, 20101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const float* kernel, 20114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int kernelWidth, 20124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrSamplerState::FilterDirection direction) { 20131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ASSERT_OWNED_RESOURCE(texture); 20141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawTarget::AutoStateRestore asr(fGpu); 20161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrDrawState* drawState = fGpu->drawState(); 20174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrRenderTarget* target = drawState->getRenderTarget(); 20184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->reset(); 20194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->setRenderTarget(target); 20201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrMatrix sampleM; 20211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleM.setIDiv(texture->width(), texture->height()); 20221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 20231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrSamplerState::kConvolution_Filter, 20241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleM); 20254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->sampler(0)->setConvolutionParams(kernelWidth, kernel); 20264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->sampler(0)->setFilterDirection(direction); 20274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->setTexture(0, texture); 20284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fGpu->drawSimpleRect(rect, NULL, 1 << 0); 20294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 20301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid GrContext::applyMorphology(GrTexture* texture, 20324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkRect& rect, 20334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int radius, 20344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrSamplerState::Filter filter, 20354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrSamplerState::FilterDirection direction) { 20364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger ASSERT_OWNED_RESOURCE(texture); 20374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(filter == GrSamplerState::kErode_Filter || 20384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger filter == GrSamplerState::kDilate_Filter); 20394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 20404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrDrawTarget::AutoStateRestore asr(fGpu); 20414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrDrawState* drawState = fGpu->drawState(); 20424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrRenderTarget* target = drawState->getRenderTarget(); 20434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->reset(); 20444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->setRenderTarget(target); 20454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrMatrix sampleM; 20464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger sampleM.setIDiv(texture->width(), texture->height()); 20474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 20484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger filter, 20494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger sampleM); 20504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->sampler(0)->setMorphologyRadius(radius); 20514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawState->sampler(0)->setFilterDirection(direction); 20521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger drawState->setTexture(0, texture); 20531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fGpu->drawSimpleRect(rect, NULL, 1 << 0); 20541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 20551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2057