diff options
32 files changed, 171 insertions, 147 deletions
diff --git a/include/gpu/GrTextureProvider.h b/include/gpu/GrTextureProvider.h index 28fda48c43..44c8cbc657 100644 --- a/include/gpu/GrTextureProvider.h +++ b/include/gpu/GrTextureProvider.h @@ -61,41 +61,26 @@ public: } /** - * Enum that determines how closely a returned scratch texture must match - * a provided GrSurfaceDesc. TODO: Remove this. createTexture() should be used - * for exact match and refScratchTexture() should be replaced with createApproxTexture(). + * Finds a texture that approximately matches the descriptor. Will be at least as large in width + * and height as desc specifies. If desc specifies that the texture should be a render target + * then result will be a render target. Format and sample count will always match the request. + * The contents of the texture are undefined. The caller owns a ref on the returned texture and + * must balance with a call to unref. */ + GrTexture* createApproxTexture(const GrSurfaceDesc&); + + /** Legacy function that no longer should be used. */ enum ScratchTexMatch { - /** - * Finds a texture that exactly matches the descriptor. - */ kExact_ScratchTexMatch, - /** - * Finds a texture that approximately matches the descriptor. Will be - * at least as large in width and height as desc specifies. If desc - * specifies that texture is a render target then result will be a - * render target. If desc specifies a render target and doesn't set the - * no stencil flag then result will have a stencil. Format and aa level - * will always match. - */ kApprox_ScratchTexMatch }; - - /** - * Returns a texture matching the desc. It's contents are unknown. The caller - * owns a ref on the returned texture and must balance with a call to unref. - * It is guaranteed that the same texture will not be returned in subsequent - * calls until all refs to the texture are dropped. - * - * internalFlag is a temporary workaround until changes in the internal - * architecture are complete. Use the default value. - * - * TODO: Once internal flag can be removed, this should be replaced with - * createApproxTexture() and exact textures should be created with - * createTexture(). - */ - GrTexture* refScratchTexture(const GrSurfaceDesc&, ScratchTexMatch match, - bool internalFlag = false); + GrTexture* refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match) { + if (kApprox_ScratchTexMatch == match) { + return this->createApproxTexture(desc); + } else { + return this->createTexture(desc, true); + } + } /////////////////////////////////////////////////////////////////////////// // Wrapped Backend Surfaces @@ -145,7 +130,16 @@ protected: */ bool existsResourceWithUniqueKey(const GrUniqueKey& key) const; - GrTexture* internalRefScratchTexture(const GrSurfaceDesc&, uint32_t flags); + enum ScratchTextureFlags { + kExact_ScratchTextureFlag = 0x1, + kNoPendingIO_ScratchTextureFlag = 0x2, // (http://skbug.com/4156) + kNoCreate_ScratchTextureFlag = 0x4, + }; + + /** A common impl for GrTextureProvider and GrResourceProvider variants. */ + GrTexture* internalCreateApproxTexture(const GrSurfaceDesc& desc, uint32_t scratchTextureFlags); + + GrTexture* refScratchTexture(const GrSurfaceDesc&, uint32_t scratchTextureFlags); void abandon() { fCache = NULL; diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index 75f601ebdb..3214eeb40e 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -318,8 +318,7 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont desc.fHeight = bounds.height(); desc.fConfig = kRGBA_8888_GrPixelConfig; - SkAutoTUnref<GrTexture> dst(context->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch)); + SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc)); if (!dst) { return false; } diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp index c9d72bb673..dda265d8bf 100644 --- a/src/effects/SkAlphaThresholdFilter.cpp +++ b/src/effects/SkAlphaThresholdFilter.cpp @@ -273,8 +273,8 @@ bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp, // the outside. maskDesc.fWidth = texture->width(); maskDesc.fHeight = texture->height(); - SkAutoTUnref<GrTexture> maskTexture(context->textureProvider()->refScratchTexture( - maskDesc, GrTextureProvider::kApprox_ScratchTexMatch)); + SkAutoTUnref<GrTexture> maskTexture( + context->textureProvider()->createApproxTexture(maskDesc)); if (!maskTexture) { return false; } diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index 11332b10da..fa61da97ca 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -428,8 +428,7 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, desc.fHeight = bounds.height(); desc.fConfig = kSkia8888_GrPixelConfig; - SkAutoTUnref<GrTexture> dst(context->textureProvider()->refScratchTexture(desc, - GrTextureProvider::kApprox_ScratchTexMatch)); + SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc)); if (!dst) { return false; diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp index 401057b24b..7c239a1bc3 100644 --- a/src/effects/SkGpuBlurUtils.cpp +++ b/src/effects/SkGpuBlurUtils.cpp @@ -183,14 +183,12 @@ GrTexture* GaussianBlur(GrContext* context, GrTexture* tempTexture; SkAutoTUnref<GrTexture> temp1, temp2; - temp1.reset(context->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch)); + temp1.reset(context->textureProvider()->createApproxTexture(desc)); dstTexture = temp1.get(); if (canClobberSrc) { tempTexture = srcTexture; } else { - temp2.reset(context->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch)); + temp2.reset(context->textureProvider()->createApproxTexture(desc)); tempTexture = temp2.get(); } diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index a30955faf7..898b094a6b 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -382,8 +382,7 @@ bool SkLightingImageFilterInternal::filterImageGPU(Proxy* proxy, desc.fHeight = bounds.height(); desc.fConfig = kRGBA_8888_GrPixelConfig; - SkAutoTUnref<GrTexture> dst(context->textureProvider()->refScratchTexture(desc, - GrTextureProvider::kApprox_ScratchTexMatch)); + SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc)); if (!dst) { return false; } diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 30ba25159d..20f76c1d93 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -662,8 +662,7 @@ bool apply_morphology(const SkBitmap& input, SkIRect srcRect = rect; if (radius.fWidth > 0) { - GrTexture* scratch = context->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch); + GrTexture* scratch = context->textureProvider()->createApproxTexture(desc); if (NULL == scratch) { return false; } @@ -686,8 +685,7 @@ bool apply_morphology(const SkBitmap& input, srcRect = dstRect; } if (radius.fHeight > 0) { - GrTexture* scratch = context->textureProvider()->refScratchTexture(desc, - GrTextureProvider::kApprox_ScratchTexMatch); + GrTexture* scratch = context->textureProvider()->createApproxTexture(desc); if (NULL == scratch) { return false; } diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index b45a4225d1..dc61b4e76e 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -160,8 +160,7 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, desc.fWidth = src.width(); desc.fHeight = src.height(); desc.fConfig = kSkia8888_GrPixelConfig; - SkAutoTUnref<GrTexture> dst(context->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch)); + SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc)); if (!dst) { return false; } diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp index 960d7b4222..086db5dd85 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp @@ -529,7 +529,8 @@ private: PathDataList* fPathList; }; -static GrBatchAtlas* create_atlas(GrTextureProvider* provider, GrBatchAtlas::EvictionFunc func, void* data) { +static GrBatchAtlas* create_atlas(GrResourceProvider* provider, GrBatchAtlas::EvictionFunc func, + void* data) { GrBatchAtlas* atlas; // Create a new atlas GrSurfaceDesc desc; @@ -540,8 +541,9 @@ static GrBatchAtlas* create_atlas(GrTextureProvider* provider, GrBatchAtlas::Evi // We don't want to flush the context so we claim we're in the middle of flushing so as to // guarantee we do not recieve a texture with pending IO - GrTexture* texture = provider->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch, true); + // TODO: Determine how to avoid having to do this. (http://skbug.com/4156) + static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag; + GrTexture* texture = provider->createApproxTexture(desc, kFlags); if (texture) { atlas = SkNEW_ARGS(GrBatchAtlas, (texture, NUM_PLOTS_X, NUM_PLOTS_Y)); } else { diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index ca83f6acc2..bbaf8db200 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -66,7 +66,7 @@ GR_DECLARE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey); static const GrIndexBuffer* ref_quads_index_buffer(GrResourceProvider* resourceProvider) { GR_DEFINE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey); - return resourceProvider->refOrCreateInstancedIndexBuffer( + return resourceProvider->findOrCreateInstancedIndexBuffer( kQuadIdxBufPattern, kIdxsPerQuad, kQuadsNumInIdxBuffer, kQuadNumVertices, gQuadsIndexBufferKey); } @@ -100,7 +100,7 @@ GR_DECLARE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey); static const GrIndexBuffer* ref_lines_index_buffer(GrResourceProvider* resourceProvider) { GR_DEFINE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey); - return resourceProvider->refOrCreateInstancedIndexBuffer( + return resourceProvider->findOrCreateInstancedIndexBuffer( kLineSegIdxBufPattern, kIdxsPerLineSeg, kLineSegsNumInIdxBuffer, kLineSegNumVertices, gLinesIndexBufferKey); } diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 93b276ad43..ffee841464 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -162,7 +162,7 @@ private: 4, 5, 6, 6, 7, 4, }; GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect); - return resourceProvider->refOrCreateInstancedIndexBuffer(gFillAARectIdx, + return resourceProvider->findOrCreateInstancedIndexBuffer(gFillAARectIdx, kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect, gAAFillRectIndexBufferKey); } @@ -543,7 +543,7 @@ private: }; GR_STATIC_ASSERT(SK_ARRAY_COUNT(gMiterIndices) == kMiterIndexCnt); GR_DEFINE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey); - return resourceProvider->refOrCreateInstancedIndexBuffer(gMiterIndices, + return resourceProvider->findOrCreateInstancedIndexBuffer(gMiterIndices, kMiterIndexCnt, kNumMiterRectsInIndexBuffer, kMiterVertexCnt, gMiterIndexBufferKey); } else { @@ -606,7 +606,7 @@ private: GR_STATIC_ASSERT(SK_ARRAY_COUNT(gBevelIndices) == kBevelIndexCnt); GR_DEFINE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey); - return resourceProvider->refOrCreateInstancedIndexBuffer(gBevelIndices, + return resourceProvider->findOrCreateInstancedIndexBuffer(gBevelIndices, kBevelIndexCnt, kNumBevelRectsInIndexBuffer, kBevelVertexCnt, gBevelIndexBufferKey); } diff --git a/src/gpu/GrBatchFontCache.cpp b/src/gpu/GrBatchFontCache.cpp index 64d6bb1a1c..b85c5bd595 100644 --- a/src/gpu/GrBatchFontCache.cpp +++ b/src/gpu/GrBatchFontCache.cpp @@ -10,6 +10,7 @@ #include "GrFontAtlasSizes.h" #include "GrGpu.h" #include "GrRectanizer.h" +#include "GrResourceProvider.h" #include "GrSurfacePriv.h" #include "SkString.h" @@ -28,8 +29,9 @@ static GrBatchAtlas* make_atlas(GrContext* context, GrPixelConfig config, // We don't want to flush the context so we claim we're in the middle of flushing so as to // guarantee we do not recieve a texture with pending IO - GrTexture* texture = context->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch, true); + // TODO: Determine how to avoid having to do this. (http://skbug.com/4156) + static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag; + GrTexture* texture = context->resourceProvider()->createApproxTexture(desc, kFlags); if (!texture) { return NULL; } diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp index 733d1e6ece..6013b58bcf 100644 --- a/src/gpu/GrBlurUtils.cpp +++ b/src/gpu/GrBlurUtils.cpp @@ -83,8 +83,7 @@ static bool draw_with_mask_filter(GrDrawContext* drawContext, desc.fHeight = dstM.fBounds.height(); desc.fConfig = kAlpha_8_GrPixelConfig; - SkAutoTUnref<GrTexture> texture(textureProvider->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch)); + SkAutoTUnref<GrTexture> texture(textureProvider->createApproxTexture(desc)); if (!texture) { return false; } @@ -116,8 +115,7 @@ static GrTexture* create_mask_GPU(GrContext* context, desc.fConfig = kAlpha_8_GrPixelConfig; } - GrTexture* mask = context->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch); + GrTexture* mask = context->textureProvider()->createApproxTexture(desc); if (NULL == mask) { return NULL; } diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp index e9172108f3..78bb7ad66a 100644 --- a/src/gpu/GrBufferAllocPool.cpp +++ b/src/gpu/GrBufferAllocPool.cpp @@ -302,11 +302,14 @@ GrGeometryBuffer* GrBufferAllocPool::getBuffer(size_t size) { GrResourceProvider* rp = fGpu->getContext()->resourceProvider(); + static const GrResourceProvider::BufferUsage kUsage = GrResourceProvider::kDynamic_BufferUsage; + // Shouldn't have to use this flag (http://skbug.com/4156) + static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag; if (kIndex_BufferType == fBufferType) { - return rp->getIndexBuffer(size, /* dynamic = */ true, /* duringFlush = */ true); + return rp->createIndexBuffer(size, kUsage, kFlags); } else { SkASSERT(kVertex_BufferType == fBufferType); - return rp->getVertexBuffer(size, /* dynamic = */ true, /* duringFlush = */ true); + return rp->createVertexBuffer(size, kUsage, kFlags); } } diff --git a/src/gpu/GrClipMaskCache.h b/src/gpu/GrClipMaskCache.h index 4b702c0d41..edba54d372 100644 --- a/src/gpu/GrClipMaskCache.h +++ b/src/gpu/GrClipMaskCache.h @@ -195,10 +195,10 @@ private: fLastClipGenID = clipGenID; - // HACK: set the last param to true to indicate that this request is at - // flush time and therefore we require a scratch texture with no pending IO operations. - fLastMask.reset(resourceProvider->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch, /*flushing=*/true)); + // TODO: Determine if we really need the NoPendingIO flag anymore. + // (http://skbug.com/4156) + static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag; + fLastMask.reset(resourceProvider->createApproxTexture(desc, kFlags)); fLastBound = bound; } diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 73637d88b4..3363795108 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -514,8 +514,7 @@ GrTexture* GrClipMaskManager::createTempMask(int width, int height) { desc.fConfig = kRGBA_8888_GrPixelConfig; } - return this->getContext()->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch); + return this->getContext()->textureProvider()->createApproxTexture(desc); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index fd788cbd93..9f83fed191 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -365,8 +365,8 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkAutoTUnref<GrTexture> tempTexture; if (GrGpu::kNoDraw_DrawPreference != drawPreference) { - tempTexture.reset(this->textureProvider()->refScratchTexture( - tempDrawInfo.fTempSurfaceDesc, GrTextureProvider::kApprox_ScratchTexMatch)); + tempTexture.reset( + this->textureProvider()->createApproxTexture(tempDrawInfo.fTempSurfaceDesc)); if (!tempTexture && GrGpu::kRequireDraw_DrawPreference == drawPreference) { return false; } @@ -495,17 +495,19 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkAutoTUnref<GrSurface> surfaceToRead(SkRef(src)); bool didTempDraw = false; if (GrGpu::kNoDraw_DrawPreference != drawPreference) { - GrTextureProvider::ScratchTexMatch match = GrTextureProvider::kApprox_ScratchTexMatch; if (tempDrawInfo.fUseExactScratch) { // We only respect this when the entire src is being read. Otherwise we can trigger too // many odd ball texture sizes and trash the cache. - if (width == src->width() && height == src->height()) { - match = GrTextureProvider::kExact_ScratchTexMatch; + if (width != src->width() || height != src->height()) { + tempDrawInfo.fUseExactScratch = false; } } SkAutoTUnref<GrTexture> temp; - temp.reset(this->textureProvider()->refScratchTexture(tempDrawInfo.fTempSurfaceDesc, - match)); + if (tempDrawInfo.fUseExactScratch) { + temp.reset(this->textureProvider()->createTexture(tempDrawInfo.fTempSurfaceDesc, true)); + } else { + temp.reset(this->textureProvider()->createApproxTexture(tempDrawInfo.fTempSurfaceDesc)); + } if (temp) { SkMatrix textureMatrix; textureMatrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 60dd58693a..0049767e8b 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -95,8 +95,8 @@ bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil desc.fWidth = copyRect.width(); desc.fHeight = copyRect.height(); - SkAutoTUnref<GrTexture> copy( - fResourceProvider->refScratchTexture(desc, GrTextureProvider::kApprox_ScratchTexMatch)); + static const uint32_t kFlags = 0; + SkAutoTUnref<GrTexture> copy(fResourceProvider->createApproxTexture(desc, kFlags)); if (!copy) { SkDebugf("Failed to create temporary copy of destination texture.\n"); diff --git a/src/gpu/GrIndexBuffer.h b/src/gpu/GrIndexBuffer.h index bf64ff87d2..2e3b437adf 100644 --- a/src/gpu/GrIndexBuffer.h +++ b/src/gpu/GrIndexBuffer.h @@ -36,9 +36,12 @@ public: protected: GrIndexBuffer(GrGpu* gpu, size_t gpuMemorySize, bool dynamic, bool cpuBacked) : INHERITED(gpu, gpuMemorySize, dynamic, cpuBacked) { - GrScratchKey key; - ComputeScratchKey(gpuMemorySize, dynamic, &key); - this->setScratchKey(key); + // We currently only make buffers scratch if they're both pow2 sized and not cpuBacked. + if (!cpuBacked && SkIsPow2(gpuMemorySize)) { + GrScratchKey key; + ComputeScratchKey(gpuMemorySize, dynamic, &key); + this->setScratchKey(key); + } } private: diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp index 3948d7e05a..4d5f2b46f8 100644 --- a/src/gpu/GrLayerCache.cpp +++ b/src/gpu/GrLayerCache.cpp @@ -250,12 +250,13 @@ bool GrLayerCache::lock(GrCachedLayer* layer, const GrSurfaceDesc& desc, bool* n } // TODO: make the test for exact match depend on the image filters themselves - GrTextureProvider::ScratchTexMatch usage = GrTextureProvider::kApprox_ScratchTexMatch; + SkAutoTUnref<GrTexture> tex; if (layer->fFilter) { - usage = GrTextureProvider::kExact_ScratchTexMatch; + tex.reset(fContext->textureProvider()->createTexture(desc, true)); + } else { + tex.reset(fContext->textureProvider()->createApproxTexture(desc)); } - SkAutoTUnref<GrTexture> tex(fContext->textureProvider()->refScratchTexture(desc, usage)); if (!tex) { return false; } diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index d337bbb365..c710408040 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -1383,11 +1383,11 @@ static const GrIndexBuffer* ref_rrect_index_buffer(bool strokeOnly, GR_DEFINE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey); GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey); if (strokeOnly) { - return resourceProvider->refOrCreateInstancedIndexBuffer( + return resourceProvider->findOrCreateInstancedIndexBuffer( gRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer, kVertsPerRRect, gStrokeRRectOnlyIndexBufferKey); } else { - return resourceProvider->refOrCreateInstancedIndexBuffer( + return resourceProvider->findOrCreateInstancedIndexBuffer( gRRectIndices, kIndicesPerRRect, kNumRRectsInIndexBuffer, kVertsPerRRect, gRRectOnlyIndexBufferKey); diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp index 3c447bded6..a79b67514e 100644 --- a/src/gpu/GrResourceProvider.cpp +++ b/src/gpu/GrResourceProvider.cpp @@ -28,7 +28,9 @@ const GrIndexBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16 const GrUniqueKey& key) { size_t bufferSize = patternSize * reps * sizeof(uint16_t); - GrIndexBuffer* buffer = this->getIndexBuffer(bufferSize, /* dynamic = */ false, true); + // This is typically used in GrBatchs, so we assume kNoPendingIO. + GrIndexBuffer* buffer = this->createIndexBuffer(bufferSize, kStatic_BufferUsage, + kNoPendingIO_Flag); if (!buffer) { return NULL; } @@ -83,21 +85,23 @@ GrPathRange* GrResourceProvider::createGlyphs(const SkTypeface* tf, const SkDesc return this->gpu()->pathRendering()->createGlyphs(tf, desc, stroke); } -GrIndexBuffer* GrResourceProvider::getIndexBuffer(size_t size, bool dynamic, - bool calledDuringFlush) { +GrIndexBuffer* GrResourceProvider::createIndexBuffer(size_t size, BufferUsage usage, + uint32_t flags) { if (this->isAbandoned()) { return NULL; } + bool noPendingIO = SkToBool(flags & kNoPendingIO_Flag); + bool dynamic = kDynamic_BufferUsage == usage; if (dynamic) { // bin by pow2 with a reasonable min static const uint32_t MIN_SIZE = 1 << 12; size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size))); GrScratchKey key; - GrIndexBuffer::ComputeScratchKey(size, dynamic, &key); + GrIndexBuffer::ComputeScratchKey(size, true, &key); uint32_t scratchFlags = 0; - if (calledDuringFlush) { + if (noPendingIO) { scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag; } else { scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag; @@ -107,25 +111,26 @@ GrIndexBuffer* GrResourceProvider::getIndexBuffer(size_t size, bool dynamic, return static_cast<GrIndexBuffer*>(resource); } } - - return this->gpu()->createIndexBuffer(size, dynamic); + return this->gpu()->createIndexBuffer(size, dynamic); } -GrVertexBuffer* GrResourceProvider::getVertexBuffer(size_t size, bool dynamic, - bool calledDuringFlush) { +GrVertexBuffer* GrResourceProvider::createVertexBuffer(size_t size, BufferUsage usage, + uint32_t flags) { if (this->isAbandoned()) { return NULL; } + bool noPendingIO = SkToBool(flags & kNoPendingIO_Flag); + bool dynamic = kDynamic_BufferUsage == usage; if (dynamic) { // bin by pow2 with a reasonable min - static const uint32_t MIN_SIZE = 1 << 15; + static const uint32_t MIN_SIZE = 1 << 12; size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size))); GrScratchKey key; - GrVertexBuffer::ComputeScratchKey(size, dynamic, &key); + GrVertexBuffer::ComputeScratchKey(size, true, &key); uint32_t scratchFlags = 0; - if (calledDuringFlush) { + if (noPendingIO) { scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag; } else { scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag; @@ -135,6 +140,5 @@ GrVertexBuffer* GrResourceProvider::getVertexBuffer(size_t size, bool dynamic, return static_cast<GrVertexBuffer*>(resource); } } - return this->gpu()->createVertexBuffer(size, dynamic); } diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h index f0b79b97f5..9ba1426fb6 100644 --- a/src/gpu/GrResourceProvider.h +++ b/src/gpu/GrResourceProvider.h @@ -24,10 +24,13 @@ class SkTypeface; * An extension of the texture provider for arbitrary resource types. This class is intended for * use within the Gr code base, not by clients or extensions (e.g. third party GrProcessor * derivatives). + * + * This currently inherits from GrTextureProvider non-publically to force callers to provider + * make a flags (pendingIO) decision and not use the GrTP methods that don't take flags. This + * can be relaxed once http://skbug.com/4156 is fixed. */ -class GrResourceProvider : public GrTextureProvider { +class GrResourceProvider : protected GrTextureProvider { public: - GrResourceProvider(GrGpu* gpu, GrResourceCache* cache); template <typename T> T* findAndRefTByUniqueKey(const GrUniqueKey& key) { @@ -47,11 +50,11 @@ public: * * @return The index buffer if successful, otherwise NULL. */ - const GrIndexBuffer* refOrCreateInstancedIndexBuffer(const uint16_t* pattern, - int patternSize, - int reps, - int vertCount, - const GrUniqueKey& key) { + const GrIndexBuffer* findOrCreateInstancedIndexBuffer(const uint16_t* pattern, + int patternSize, + int reps, + int vertCount, + const GrUniqueKey& key) { if (GrIndexBuffer* buffer = this->findAndRefTByUniqueKey<GrIndexBuffer>(key)) { return buffer; } @@ -81,13 +84,34 @@ public: GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStrokeInfo&); GrPathRange* createGlyphs(const SkTypeface*, const SkDescriptor*, const GrStrokeInfo&); - using GrTextureProvider::assignUniqueKeyToResource; using GrTextureProvider::findAndRefResourceByUniqueKey; using GrTextureProvider::abandon; - GrIndexBuffer* getIndexBuffer(size_t size, bool dynamic, bool calledDuringFlush); - GrVertexBuffer* getVertexBuffer(size_t size, bool dynamic, bool calledDuringFlush); + enum Flags { + /** If the caller intends to do direct reads/writes to/from the CPU then this flag must be + * set when accessing resources during a GrDrawTarget flush. This includes the execution of + * GrBatch objects. The reason is that these memory operations are done immediately and + * will occur out of order WRT the operations being flushed. + * Make this automatic: http://skbug.com/4156 + */ + kNoPendingIO_Flag = kNoPendingIO_ScratchTextureFlag, + }; + + enum BufferUsage { + /** Caller intends to specify the buffer data rarely with respect to the number of draws + that read the data. */ + kStatic_BufferUsage, + /** Caller intends to respecify the buffer data frequently between draws. */ + kDynamic_BufferUsage, + }; + GrIndexBuffer* createIndexBuffer(size_t size, BufferUsage, uint32_t flags); + GrVertexBuffer* createVertexBuffer(size_t size, BufferUsage, uint32_t flags); + + GrTexture* createApproxTexture(const GrSurfaceDesc& desc, uint32_t flags) { + SkASSERT(0 == flags || kNoPendingIO_Flag == flags); + return this->internalCreateApproxTexture(desc, flags); + } private: const GrIndexBuffer* createInstancedIndexBuffer(const uint16_t* pattern, diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 4266fcbbd0..df1f91bb24 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -248,8 +248,7 @@ GrTexture* GrSWMaskHelper::createTexture() { SkASSERT(fContext->caps()->isConfigTexturable(desc.fConfig)); } - return fContext->textureProvider()->refScratchTexture( - desc, GrTextureProvider::kApprox_ScratchTexMatch); + return fContext->textureProvider()->createApproxTexture(desc); } void GrSWMaskHelper::sendTextureData(GrTexture *texture, const GrSurfaceDesc& desc, diff --git a/src/gpu/GrTextureProvider.cpp b/src/gpu/GrTextureProvider.cpp index cf93209dbc..0a6b248d7a 100644 --- a/src/gpu/GrTextureProvider.cpp +++ b/src/gpu/GrTextureProvider.cpp @@ -29,7 +29,7 @@ GrTexture* GrTextureProvider::createTexture(const GrSurfaceDesc& desc, bool budg if (!GrPixelConfigIsCompressed(desc.fConfig)) { static const uint32_t kFlags = kExact_ScratchTextureFlag | kNoCreate_ScratchTextureFlag; - if (GrTexture* texture = this->internalRefScratchTexture(desc, kFlags)) { + if (GrTexture* texture = this->refScratchTexture(desc, kFlags)) { if (!srcData || texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, srcData, rowBytes)) { if (!budgeted) { @@ -43,8 +43,12 @@ GrTexture* GrTextureProvider::createTexture(const GrSurfaceDesc& desc, bool budg return fGpu->createTexture(desc, budgeted, srcData, rowBytes); } -GrTexture* GrTextureProvider::refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match, - bool calledDuringFlush) { +GrTexture* GrTextureProvider::createApproxTexture(const GrSurfaceDesc& desc) { + return this->internalCreateApproxTexture(desc, 0); +} + +GrTexture* GrTextureProvider::internalCreateApproxTexture(const GrSurfaceDesc& desc, + uint32_t scratchFlags) { if (this->isAbandoned()) { return NULL; } @@ -52,26 +56,19 @@ GrTexture* GrTextureProvider::refScratchTexture(const GrSurfaceDesc& desc, Scrat if (GrPixelConfigIsCompressed(desc.fConfig)) { return NULL; } else { - uint32_t flags = 0; - if (kExact_ScratchTexMatch == match) { - flags |= kExact_ScratchTextureFlag; - } - if (calledDuringFlush) { - flags |= kNoPendingIO_ScratchTextureFlag; - } - return this->internalRefScratchTexture(desc, flags); + return this->refScratchTexture(desc, scratchFlags); } } -GrTexture* GrTextureProvider::internalRefScratchTexture(const GrSurfaceDesc& inDesc, - uint32_t flags) { +GrTexture* GrTextureProvider::refScratchTexture(const GrSurfaceDesc& inDesc, + uint32_t scratchFlags) { SkASSERT(!this->isAbandoned()); SkASSERT(!GrPixelConfigIsCompressed(inDesc.fConfig)); SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc); if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) { - if (!(kExact_ScratchTextureFlag & flags)) { + if (!(kExact_ScratchTextureFlag & scratchFlags)) { // bin by pow2 with a reasonable min const int minSize = SkTMin(16, fGpu->caps()->minTextureSize()); GrSurfaceDesc* wdesc = desc.writable(); @@ -82,7 +79,7 @@ GrTexture* GrTextureProvider::internalRefScratchTexture(const GrSurfaceDesc& inD GrScratchKey key; GrTexturePriv::ComputeScratchKey(*desc, &key); uint32_t scratchFlags = 0; - if (kNoPendingIO_ScratchTextureFlag & flags) { + if (kNoPendingIO_ScratchTextureFlag & scratchFlags) { scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag; } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) { // If it is not a render target then it will most likely be populated by @@ -100,7 +97,7 @@ GrTexture* GrTextureProvider::internalRefScratchTexture(const GrSurfaceDesc& inD } } - if (!(kNoCreate_ScratchTextureFlag & flags)) { + if (!(kNoCreate_ScratchTextureFlag & scratchFlags)) { return fGpu->createTexture(*desc, true, NULL, 0); } diff --git a/src/gpu/GrVertexBuffer.h b/src/gpu/GrVertexBuffer.h index 3c12cd76d2..3c62cd61ca 100644 --- a/src/gpu/GrVertexBuffer.h +++ b/src/gpu/GrVertexBuffer.h @@ -27,9 +27,12 @@ public: protected: GrVertexBuffer(GrGpu* gpu, size_t gpuMemorySize, bool dynamic, bool cpuBacked) : INHERITED(gpu, gpuMemorySize, dynamic, cpuBacked) { - GrScratchKey key; - ComputeScratchKey(gpuMemorySize, dynamic, &key); - this->setScratchKey(key); + // We currently only make buffers scratch if they're both pow2 sized and not cpuBacked. + if (!cpuBacked && SkIsPow2(gpuMemorySize)) { + GrScratchKey key; + ComputeScratchKey(gpuMemorySize, dynamic, &key); + this->setScratchKey(key); + } } private: diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 867c2edac8..4a835bb18d 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1806,10 +1806,11 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint // layers are never draw in repeat modes, so we can request an approx // match and ignore any padding. - const GrTextureProvider::ScratchTexMatch match = (kNever_TileUsage == cinfo.fTileUsage) ? - GrTextureProvider::kApprox_ScratchTexMatch : - GrTextureProvider::kExact_ScratchTexMatch; - texture.reset(fContext->textureProvider()->refScratchTexture(desc, match)); + if (kNever_TileUsage == cinfo.fTileUsage) { + texture.reset(fContext->textureProvider()->createApproxTexture(desc)); + } else { + texture.reset(fContext->textureProvider()->createTexture(desc, true)); + } if (texture) { SkSurfaceProps props(this->surfaceProps().flags(), cinfo.fPixelGeometry); diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 3334095a95..9aa79618a2 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -407,9 +407,11 @@ static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe bool needsExactTexture = (yuvDesc.fWidth != yuvInfo.fSize[0].fWidth) || (yuvDesc.fHeight != yuvInfo.fSize[0].fHeight); - yuvTextures[i].reset(ctx->textureProvider()->refScratchTexture(yuvDesc, - needsExactTexture ? GrTextureProvider::kExact_ScratchTexMatch : - GrTextureProvider::kApprox_ScratchTexMatch)); + if (needsExactTexture) { + yuvTextures[i].reset(ctx->textureProvider()->createTexture(yuvDesc, true)); + } else { + yuvTextures[i].reset(ctx->textureProvider()->createApproxTexture(yuvDesc)); + } if (!yuvTextures[i] || !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, yuvDesc.fConfig, planes[i], yuvInfo.fRowBytes[i])) { diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 7ce6831b63..c89c08de6e 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -224,8 +224,7 @@ SkImage* SkImage::NewFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace colorS dstDesc.fConfig = kRGBA_8888_GrPixelConfig; dstDesc.fSampleCnt = 0; - SkAutoTUnref<GrTexture> dst(ctx->textureProvider()->refScratchTexture( - dstDesc, GrTextureProvider::kExact_ScratchTexMatch)); + SkAutoTUnref<GrTexture> dst(ctx->textureProvider()->createTexture(dstDesc, true)); if (!dst) { return NULL; } diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index d36c48d82e..ded1492f98 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -200,13 +200,13 @@ bool GrDrawTarget::programUnitTest(GrContext* context, int maxStages) { dummyDesc.fWidth = 34; dummyDesc.fHeight = 18; SkAutoTUnref<GrTexture> dummyTexture1( - fResourceProvider->createTexture(dummyDesc, false, NULL, 0)); + context->textureProvider()->createTexture(dummyDesc, false, NULL, 0)); dummyDesc.fFlags = kNone_GrSurfaceFlags; dummyDesc.fConfig = kAlpha_8_GrPixelConfig; dummyDesc.fWidth = 16; dummyDesc.fHeight = 22; SkAutoTUnref<GrTexture> dummyTexture2( - fResourceProvider->createTexture(dummyDesc, false, NULL, 0)); + context->textureProvider()->createTexture(dummyDesc, false, NULL, 0)); if (!dummyTexture1 || ! dummyTexture2) { SkDebugf("Could not allocate dummy textures"); @@ -226,7 +226,7 @@ bool GrDrawTarget::programUnitTest(GrContext* context, int maxStages) { for (int t = 0; t < NUM_TESTS; t++) { // setup random render target(can fail) SkAutoTUnref<GrRenderTarget> rt(random_render_target( - fResourceProvider, &random, this->caps())); + context->textureProvider(), &random, this->caps())); if (!rt.get()) { SkDebugf("Could not allocate render target"); return false; diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp index b7f7572896..5dcdfb1830 100644 --- a/tests/GrPorterDuffTest.cpp +++ b/tests/GrPorterDuffTest.cpp @@ -966,7 +966,7 @@ static void test_no_dual_source_blending(skiatest::Reporter* reporter) { fakeDesc.fConfig = kRGBA_8888_GrPixelConfig; fakeDesc.fWidth = fakeDesc.fHeight = 100; fakeDesc.fTextureHandle = 1; - SkAutoTUnref<GrTexture> fakeTexture(ctx->resourceProvider()->wrapBackendTexture(fakeDesc, + SkAutoTUnref<GrTexture> fakeTexture(ctx->textureProvider()->wrapBackendTexture(fakeDesc, kBorrow_GrWrapOwnership)); GrXferProcessor::DstTexture fakeDstTexture; fakeDstTexture.setTexture(fakeTexture); diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp index d6d33307e1..dbfd825038 100644 --- a/tests/TessellatingPathRendererTests.cpp +++ b/tests/TessellatingPathRendererTests.cpp @@ -261,8 +261,7 @@ DEF_GPUTEST(TessellatingPathRendererTests, reporter, factory) { desc.fHeight = 800; desc.fConfig = kSkia8888_GrPixelConfig; desc.fOrigin = kTopLeft_GrSurfaceOrigin; - SkAutoTUnref<GrTexture> texture(context->textureProvider()->refScratchTexture(desc, - GrTextureProvider::kExact_ScratchTexMatch)); + SkAutoTUnref<GrTexture> texture(context->textureProvider()->createApproxTexture(desc)); GrTestTarget tt; context->getTestTarget(&tt); GrRenderTarget* rt = texture->asRenderTarget(); |