diff options
author | Robert Phillips <robertphillips@google.com> | 2017-04-04 16:50:22 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-04-05 11:55:35 +0000 |
commit | fb0bd98a43fa11e09705837418167dd72bb4a361 (patch) | |
tree | 67579cf4663c41d4b9ec36bbd61020aa3ccbe57f /src | |
parent | be5387b9308ad0b92a48a1272b618b6eaa08a771 (diff) |
Rm readPixels from GrSurface & move read/writeSurfacePixels to GrContextPriv
This is in service of: https://skia-review.googlesource.com/c/11125/ (Add parallel proxyID to StencilOps & RenderTargetOpList) where I want a better choke point for texture creation to improve discard handling.
Change-Id: If57a7de47edc0853dae7bc61337d9acdc03d63b0
Reviewed-on: https://skia-review.googlesource.com/11200
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrContext.cpp | 124 | ||||
-rw-r--r-- | src/gpu/GrContextPriv.h | 62 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 35 | ||||
-rw-r--r-- | src/gpu/GrResourceProvider.cpp | 68 | ||||
-rw-r--r-- | src/gpu/GrResourceProvider.h | 30 | ||||
-rw-r--r-- | src/gpu/GrSurface.cpp | 24 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 15 | ||||
-rw-r--r-- | src/gpu/GrTextureContext.cpp | 30 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 18 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureStripAtlas.cpp | 2 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 2 |
11 files changed, 230 insertions, 180 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 98f709a962..c1961f9557 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -26,6 +26,8 @@ #include "effects/GrConfigConversionEffect.h" #include "text/GrTextBlobCache.h" +#define ASSERT_OWNED_PROXY(P) \ +SkASSERT(!(P) || !((P)->priv().peekTexture()) || (P)->priv().peekTexture()->getContext() == this) #define ASSERT_OWNED_PROXY_PRIV(P) \ SkASSERT(!(P) || !((P)->priv().peekTexture()) || (P)->priv().peekTexture()->getContext() == fContext) @@ -37,6 +39,7 @@ SkASSERT(!(P) || !((P)->priv().peekTexture()) || (P)->priv().peekTexture()->getC #define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; } #define RETURN_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return; } #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; } +#define RETURN_FALSE_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return false; } #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; } //////////////////////////////////////////////////////////////////////////////// @@ -264,19 +267,25 @@ static bool valid_unpremul_config(GrPixelConfig config) { return GrPixelConfigIs8888Unorm(config) || kRGBA_half_GrPixelConfig == config; } -bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpace, - int left, int top, int width, int height, - GrPixelConfig srcConfig, SkColorSpace* srcColorSpace, - const void* buffer, size_t rowBytes, uint32_t pixelOpsFlags) { +bool GrContextPriv::writeSurfacePixels(GrSurfaceProxy* srcProxy, SkColorSpace* dstColorSpace, + int left, int top, int width, int height, + GrPixelConfig srcConfig, SkColorSpace* srcColorSpace, + const void* buffer, size_t rowBytes, + uint32_t pixelOpsFlags) { // TODO: Color space conversion - ASSERT_SINGLE_OWNER - RETURN_FALSE_IF_ABANDONED - ASSERT_OWNED_RESOURCE(surface); - SkASSERT(surface); - GR_AUDIT_TRAIL_AUTO_FRAME(&fAuditTrail, "GrContext::writeSurfacePixels"); + ASSERT_SINGLE_OWNER_PRIV + RETURN_FALSE_IF_ABANDONED_PRIV + ASSERT_OWNED_PROXY_PRIV(srcProxy); + SkASSERT(srcProxy); + GR_AUDIT_TRAIL_AUTO_FRAME(&fContext->fAuditTrail, "GrContextPriv::writeSurfacePixels"); - this->testPMConversionsIfNecessary(pixelOpsFlags); + GrSurface* surface = srcProxy->instantiate(fContext->resourceProvider()); + if (!surface) { + return false; + } + + fContext->testPMConversionsIfNecessary(pixelOpsFlags); // Trim the params here so that if we wind up making a temporary surface it can be as small as // necessary and because GrGpu::getWritePixelsInfo requires it. @@ -298,23 +307,23 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference; // Don't prefer to draw for the conversion (and thereby access a texture from the cache) when // we've already determined that there isn't a roundtrip preserving conversion processor pair. - if (applyPremulToSrc && this->validPMUPMConversionExists(srcConfig)) { + if (applyPremulToSrc && fContext->validPMUPMConversionExists(srcConfig)) { drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference; } GrGpu::WritePixelTempDrawInfo tempDrawInfo; - if (!fGpu->getWritePixelsInfo(surface, width, height, srcConfig, &drawPreference, - &tempDrawInfo)) { + if (!fContext->fGpu->getWritePixelsInfo(surface, width, height, srcConfig, + &drawPreference, &tempDrawInfo)) { return false; } if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().hasPendingIO()) { - this->contextPriv().flush(nullptr); // MDB TODO: tighten this + this->flush(nullptr); // MDB TODO: tighten this } sk_sp<GrTextureProxy> tempProxy; if (GrGpu::kNoDraw_DrawPreference != drawPreference) { - tempProxy = GrSurfaceProxy::MakeDeferred(this->resourceProvider(), + tempProxy = GrSurfaceProxy::MakeDeferred(fContext->resourceProvider(), tempDrawInfo.fTempSurfaceDesc, SkBackingFit::kApprox, SkBudgeted::kYes); @@ -328,7 +337,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa if (tempProxy) { sk_sp<GrFragmentProcessor> fp; if (applyPremulToSrc) { - fp = this->createUPMToPMEffect(tempProxy, SkMatrix::I()); + fp = fContext->createUPMToPMEffect(tempProxy, SkMatrix::I()); fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle); // If premultiplying was the only reason for the draw, fall back to a straight write. if (!fp) { @@ -341,7 +350,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa } if (tempProxy) { if (!fp) { - fp = GrSimpleTextureEffect::Make(this->resourceProvider(), tempProxy, nullptr, + fp = GrSimpleTextureEffect::Make(fContext->resourceProvider(), tempProxy, nullptr, SkMatrix::I()); fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle); @@ -350,9 +359,9 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa } } if (tempProxy->priv().hasPendingIO()) { - this->contextPriv().flush(tempProxy.get()); + this->flush(tempProxy.get()); } - GrTexture* texture = tempProxy->instantiate(this->resourceProvider()); + GrTexture* texture = tempProxy->instantiate(fContext->resourceProvider()); if (!texture) { return false; } @@ -367,9 +376,9 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa buffer = tmpPixels.get(); applyPremulToSrc = false; } - if (!fGpu->writePixels(texture, 0, 0, width, height, - tempDrawInfo.fWriteConfig, buffer, - rowBytes)) { + if (!fContext->fGpu->writePixels(texture, 0, 0, width, height, + tempDrawInfo.fWriteConfig, buffer, + rowBytes)) { return false; } SkMatrix matrix; @@ -380,8 +389,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa GrRenderTarget* renderTarget = surface->asRenderTarget(); SkASSERT(renderTarget); sk_sp<GrRenderTargetContext> renderTargetContext( - this->contextPriv().makeWrappedRenderTargetContext(sk_ref_sp(renderTarget), - nullptr)); + this->makeWrappedRenderTargetContext(sk_ref_sp(renderTarget), nullptr)); if (!renderTargetContext) { return false; } @@ -394,7 +402,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa nullptr); if (kFlushWrites_PixelOp & pixelOpsFlags) { - this->contextPriv().flushSurfaceWrites(renderTargetContext->asRenderTargetProxy()); + this->flushSurfaceWrites(renderTargetContext->asRenderTargetProxy()); } } } @@ -410,24 +418,31 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpa buffer = tmpPixels.get(); applyPremulToSrc = false; } - return fGpu->writePixels(surface, left, top, width, height, srcConfig, buffer, rowBytes); + return fContext->fGpu->writePixels(surface, left, top, width, height, srcConfig, + buffer, rowBytes); } return true; } -bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, - int left, int top, int width, int height, - GrPixelConfig dstConfig, SkColorSpace* dstColorSpace, - void* buffer, size_t rowBytes, uint32_t flags) { +bool GrContextPriv::readSurfacePixels(GrSurfaceProxy* srcProxy, SkColorSpace* srcColorSpace, + int left, int top, int width, int height, + GrPixelConfig dstConfig, SkColorSpace* dstColorSpace, + void* buffer, size_t rowBytes, uint32_t flags) { // TODO: Color space conversion - ASSERT_SINGLE_OWNER - RETURN_FALSE_IF_ABANDONED - ASSERT_OWNED_RESOURCE(src); - SkASSERT(src); - GR_AUDIT_TRAIL_AUTO_FRAME(&fAuditTrail, "GrContext::readSurfacePixels"); + ASSERT_SINGLE_OWNER_PRIV + RETURN_FALSE_IF_ABANDONED_PRIV + ASSERT_OWNED_PROXY_PRIV(srcProxy); + SkASSERT(srcProxy); + GR_AUDIT_TRAIL_AUTO_FRAME(&fContext->fAuditTrail, "GrContextPriv::readSurfacePixels"); + + // MDB TODO: delay this instantiation until later in the method + GrSurface* src = srcProxy->instantiate(fContext->resourceProvider()); + if (!src) { + return false; + } - this->testPMConversionsIfNecessary(flags); + fContext->testPMConversionsIfNecessary(flags); // Adjust the params so that if we wind up using an intermediate surface we've already done // all the trimming and the temporary can be the min size required. @@ -438,7 +453,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, } if (!(kDontFlush_PixelOpsFlag & flags) && src->surfacePriv().hasPendingWrite()) { - this->contextPriv().flush(nullptr); // MDB TODO: tighten this + this->flush(nullptr); // MDB TODO: tighten this } bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); @@ -454,18 +469,17 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference; // Don't prefer to draw for the conversion (and thereby access a texture from the cache) when // we've already determined that there isn't a roundtrip preserving conversion processor pair. - if (unpremul && this->validPMUPMConversionExists(src->config())) { + if (unpremul && fContext->validPMUPMConversionExists(src->config())) { drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference; } GrGpu::ReadPixelTempDrawInfo tempDrawInfo; - if (!fGpu->getReadPixelsInfo(src, width, height, rowBytes, dstConfig, &drawPreference, - &tempDrawInfo)) { + if (!fContext->fGpu->getReadPixelsInfo(src, width, height, rowBytes, dstConfig, + &drawPreference, &tempDrawInfo)) { return false; } - sk_sp<GrSurface> surfaceToRead(SkRef(src)); - sk_sp<GrTextureProxy> drawnProxy; + sk_sp<GrSurfaceProxy> proxyToRead = sk_ref_sp(srcProxy); bool didTempDraw = false; if (GrGpu::kNoDraw_DrawPreference != drawPreference) { if (SkBackingFit::kExact == tempDrawInfo.fTempSurfaceFit) { @@ -478,7 +492,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, // TODO: Need to decide the semantics of this function for color spaces. Do we support // conversion to a passed-in color space? For now, specifying nullptr means that this // path will do no conversion, so it will match the behavior of the non-draw path. - sk_sp<GrRenderTargetContext> tempRTC = this->makeRenderTargetContext( + sk_sp<GrRenderTargetContext> tempRTC = fContext->makeRenderTargetContext( tempDrawInfo.fTempSurfaceFit, tempDrawInfo.fTempSurfaceDesc.fWidth, tempDrawInfo.fTempSurfaceDesc.fHeight, @@ -488,10 +502,10 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, tempDrawInfo.fTempSurfaceDesc.fOrigin); if (tempRTC) { SkMatrix textureMatrix = SkMatrix::MakeTrans(SkIntToScalar(left), SkIntToScalar(top)); - sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(sk_ref_sp(src->asTexture())); + sk_sp<GrTextureProxy> proxy = sk_ref_sp(srcProxy->asTextureProxy()); sk_sp<GrFragmentProcessor> fp; if (unpremul) { - fp = this->createPMToUPMEffect(proxy, textureMatrix); + fp = fContext->createPMToUPMEffect(proxy, textureMatrix); fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle); if (fp) { unpremul = false; // we no longer need to do this on CPU after the read back. @@ -502,7 +516,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, } } if (!fp && tempRTC) { - fp = GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy), + fp = GrSimpleTextureEffect::Make(fContext->resourceProvider(), std::move(proxy), nullptr, textureMatrix); fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle); } @@ -514,8 +528,7 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); tempRTC->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect, nullptr); - drawnProxy = tempRTC->asTextureProxyRef(); - surfaceToRead = sk_ref_sp(drawnProxy->instantiate(this->resourceProvider())); + proxyToRead = tempRTC->asTextureProxyRef(); left = 0; top = 0; didTempDraw = true; @@ -523,6 +536,11 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, } } + if (!proxyToRead) { + return false; + } + + GrSurface* surfaceToRead = proxyToRead->instantiate(fContext->resourceProvider()); if (!surfaceToRead) { return false; } @@ -532,11 +550,11 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace, } GrPixelConfig configToRead = dstConfig; if (didTempDraw) { - this->contextPriv().flushSurfaceWrites(drawnProxy.get()); + this->flushSurfaceWrites(proxyToRead.get()); configToRead = tempDrawInfo.fReadConfig; } - if (!fGpu->readPixels(surfaceToRead.get(), left, top, width, height, configToRead, buffer, - rowBytes)) { + if (!fContext->fGpu->readPixels(surfaceToRead, left, top, width, height, configToRead, + buffer, rowBytes)) { return false; } @@ -815,7 +833,7 @@ sk_sp<GrRenderTargetContext> GrContext::makeRenderTargetContext(SkBackingFit fit sk_sp<GrTexture> tex; if (SkBackingFit::kExact == fit) { - tex.reset(this->resourceProvider()->createTexture(desc, budgeted)); + tex = this->resourceProvider()->createTexture(desc, budgeted); } else { tex.reset(this->resourceProvider()->createApproxTexture(desc, 0)); } @@ -878,7 +896,7 @@ void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { void GrContext::testPMConversionsIfNecessary(uint32_t flags) { ASSERT_SINGLE_OWNER - if (SkToBool(kUnpremul_PixelOpsFlag & flags)) { + if (SkToBool(GrContextPriv::kUnpremul_PixelOpsFlag & flags)) { if (!fDidTestPMConversions) { test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); fDidTestPMConversions = true; diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 0f77ec2d4c..369e8e7ff9 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -96,6 +96,68 @@ public: */ void prepareSurfaceForExternalIO(GrSurfaceProxy*); + /** + * These flags can be used with the read/write pixels functions below. + */ + enum PixelOpsFlags { + /** The GrContext will not be flushed before the surface read or write. This means that + the read or write may occur before previous draws have executed. */ + kDontFlush_PixelOpsFlag = 0x1, + /** Any surface writes should be flushed to the backend 3D API after the surface operation + is complete */ + kFlushWrites_PixelOp = 0x2, + /** The src for write or dst read is unpremultiplied. This is only respected if both the + config src and dst configs are an RGBA/BGRA 8888 format. */ + kUnpremul_PixelOpsFlag = 0x4, + }; + + /** + * Reads a rectangle of pixels from a surface. + * @param surface the surface to read from. + * @param srcColorSpace color space of the surface + * @param left left edge of the rectangle to read (inclusive) + * @param top top edge of the rectangle to read (inclusive) + * @param width width of rectangle to read in pixels. + * @param height height of rectangle to read in pixels. + * @param config the pixel config of the destination buffer + * @param dstColorSpace color space of the destination buffer + * @param buffer memory to read the rectangle into. + * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly + * packed. + * @param pixelOpsFlags see PixelOpsFlags enum above. + * + * @return true if the read succeeded, false if not. The read can fail because of an unsupported + * pixel configs + */ + bool readSurfacePixels(GrSurfaceProxy* src, SkColorSpace* srcColorSpace, + int left, int top, int width, int height, + GrPixelConfig config, SkColorSpace* dstColorSpace, void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0); + + /** + * Writes a rectangle of pixels to a surface. + * @param surface the surface to write to. + * @param dstColorSpace color space of the surface + * @param left left edge of the rectangle to write (inclusive) + * @param top top edge of the rectangle to write (inclusive) + * @param width width of rectangle to write in pixels. + * @param height height of rectangle to write in pixels. + * @param config the pixel config of the source buffer + * @param srcColorSpace color space of the source buffer + * @param buffer memory to read pixels from + * @param rowBytes number of bytes between consecutive rows. Zero + * means rows are tightly packed. + * @param pixelOpsFlags see PixelOpsFlags enum above. + * @return true if the write succeeded, false if not. The write can fail because of an + * unsupported combination of surface and src configs. + */ + bool writeSurfacePixels(GrSurfaceProxy* src, SkColorSpace* dstColorSpace, + int left, int top, int width, int height, + GrPixelConfig config, SkColorSpace* srcColorSpace, const void* buffer, + size_t rowBytes, + uint32_t pixelOpsFlags = 0); + private: explicit GrContextPriv(GrContext* context) : fContext(context) {} GrContextPriv(const GrContextPriv&); // unimpl diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 8ef09a4a3c..76a67c083e 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -8,6 +8,7 @@ #include "GrRenderTargetContext.h" #include "GrAppliedClip.h" #include "GrColor.h" +#include "GrContextPriv.h" #include "GrDrawingManager.h" #include "GrFixedClip.h" #include "GrGpuResourcePriv.h" @@ -162,18 +163,14 @@ bool GrRenderTargetContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBu // TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { - flags |= GrContext::kUnpremul_PixelOpsFlag; + flags |= GrContextPriv::kUnpremul_PixelOpsFlag; } - // Deferral of the VRAM resources must end in this instance anyway - sk_sp<GrRenderTarget> rt( - sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider()))); - if (!rt) { - return false; - } - - return rt->readPixels(this->getColorSpace(), x, y, dstInfo.width(), dstInfo.height(), - config, dstInfo.colorSpace(), dstBuffer, dstRowBytes, flags); + return fContext->contextPriv().readSurfacePixels(fRenderTargetProxy.get(), + this->getColorSpace(), x, y, + dstInfo.width(), dstInfo.height(), config, + dstInfo.colorSpace(), + dstBuffer, dstRowBytes, flags); } // TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext? @@ -185,18 +182,14 @@ bool GrRenderTargetContext::onWritePixels(const SkImageInfo& srcInfo, const void return false; } if (kUnpremul_SkAlphaType == srcInfo.alphaType()) { - flags |= GrContext::kUnpremul_PixelOpsFlag; - } - - // Deferral of the VRAM resources must end in this instance anyway - sk_sp<GrRenderTarget> rt( - sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider()))); - if (!rt) { - return false; + flags |= GrContextPriv::kUnpremul_PixelOpsFlag; } - return rt->writePixels(this->getColorSpace(), x, y, srcInfo.width(), srcInfo.height(), - config, srcInfo.colorSpace(), srcBuffer, srcRowBytes, flags); + return fContext->contextPriv().writeSurfacePixels(fRenderTargetProxy.get(), + this->getColorSpace(), x, y, + srcInfo.width(), srcInfo.height(), + config, srcInfo.colorSpace(), + srcBuffer, srcRowBytes, flags); } @@ -1787,7 +1780,7 @@ void GrRenderTargetContext::setupDstTexture(GrRenderTarget* rt, const GrClip& cl desc.fHeight = rt->height(); dstPoint = {copyRect.fLeft, copyRect.fTop}; dstOffset = {0, 0}; - copy.reset(fContext->resourceProvider()->createTexture(desc, SkBudgeted::kYes, kFlags)); + copy = fContext->resourceProvider()->createTexture(desc, SkBudgeted::kYes, kFlags); } else { desc.fWidth = copyRect.width(); desc.fHeight = copyRect.height(); diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp index 42f5e29d71..0cb71c50ef 100644 --- a/src/gpu/GrResourceProvider.cpp +++ b/src/gpu/GrResourceProvider.cpp @@ -10,6 +10,7 @@ #include "GrBuffer.h" #include "GrCaps.h" #include "GrContext.h" +#include "GrContextPriv.h" #include "GrGpu.h" #include "GrPathRendering.h" #include "GrRenderTarget.h" @@ -47,9 +48,13 @@ bool GrResourceProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) { return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height())); } -GrTexture* GrResourceProvider::createMipMappedTexture(const GrSurfaceDesc& desc, - SkBudgeted budgeted, const GrMipLevel* texels, - int mipLevelCount, uint32_t flags, +// MDB TODO: this should probably be a factory on GrSurfaceProxy +sk_sp<GrTextureProxy> GrResourceProvider::createMipMappedTexture( + const GrSurfaceDesc& desc, + SkBudgeted budgeted, + const GrMipLevel* texels, + int mipLevelCount, + uint32_t flags, SkDestinationSurfaceColorMode mipColorMode) { ASSERT_SINGLE_OWNER @@ -74,17 +79,19 @@ GrTexture* GrResourceProvider::createMipMappedTexture(const GrSurfaceDesc& desc, if (!GrPixelConfigIsCompressed(desc.fConfig)) { if (mipLevelCount < 2) { flags |= kExact_Flag | kNoCreate_Flag; - if (GrTexture* texture = this->refScratchTexture(desc, flags)) { + sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags)); + if (tex) { + sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(tex); if (!mipLevelCount || - texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, - texels[0].fPixels, texels[0].fRowBytes)) { + fGpu->getContext()->contextPriv().writeSurfacePixels( + proxy.get(), nullptr, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, + nullptr, texels[0].fPixels, texels[0].fRowBytes)) { if (SkBudgeted::kNo == budgeted) { - texture->resourcePriv().makeUnbudgeted(); + tex->resourcePriv().makeUnbudgeted(); } - texture->texturePriv().setMipColorMode(mipColorMode); - return texture; + tex->texturePriv().setMipColorMode(mipColorMode); + return proxy; } - texture->unref(); } } } @@ -93,25 +100,34 @@ GrTexture* GrResourceProvider::createMipMappedTexture(const GrSurfaceDesc& desc, for (int i = 0; i < mipLevelCount; ++i) { texelsShallowCopy.push_back(texels[i]); } - GrTexture* texture = fGpu->createTexture(desc, budgeted, texelsShallowCopy); - if (texture) { - texture->texturePriv().setMipColorMode(mipColorMode); + sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texelsShallowCopy)); + if (tex) { + tex->texturePriv().setMipColorMode(mipColorMode); } - return texture; + + return GrSurfaceProxy::MakeWrapped(std::move(tex)); } -GrTexture* GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, - const void* srcData, size_t rowBytes, uint32_t flags) { - GrMipLevel tempTexels; - GrMipLevel* texels = nullptr; - int levelCount = 0; - if (srcData) { - tempTexels.fPixels = srcData; - tempTexels.fRowBytes = rowBytes; - texels = &tempTexels; - levelCount = 1; - } - return this->createMipMappedTexture(desc, budgeted, texels, levelCount, flags); +sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, + uint32_t flags) { + if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) && + !fGpu->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { + return nullptr; + } + + if (!GrPixelConfigIsCompressed(desc.fConfig)) { + flags |= kExact_Flag | kNoCreate_Flag; + sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags)); + if (tex) { + if (SkBudgeted::kNo == budgeted) { + tex->resourcePriv().makeUnbudgeted(); + } + return tex; + } + } + + sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted)); + return tex; } GrTexture* GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc, uint32_t flags) { diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h index a4abd723ea..5cb64e092e 100644 --- a/src/gpu/GrResourceProvider.h +++ b/src/gpu/GrResourceProvider.h @@ -47,29 +47,12 @@ public: * @param texels A contiguous array of mipmap levels * @param mipLevelCount The amount of elements in the texels array */ - GrTexture* createMipMappedTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, - const GrMipLevel* texels, int mipLevelCount, - uint32_t flags = 0, - SkDestinationSurfaceColorMode mipColorMode = + sk_sp<GrTextureProxy> createMipMappedTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, + const GrMipLevel* texels, int mipLevelCount, + uint32_t flags = 0, + SkDestinationSurfaceColorMode mipColorMode = SkDestinationSurfaceColorMode::kLegacy); - /** - * This function is a shim which creates a SkTArray<GrMipLevel> of size 1. - * It then calls createTexture with that SkTArray. - * - * @param srcData Pointer to the pixel values (optional). - * @param rowBytes The number of bytes between rows of the texture. Zero - * implies tightly packed rows. For compressed pixel configs, this - * field is ignored. - */ - GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, const void* srcData, - size_t rowBytes, uint32_t flags = 0); - - /** Shortcut for creating a texture with no initial data to upload. */ - GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, uint32_t flags = 0) { - return this->createTexture(desc, budgeted, nullptr, 0, flags); - } - /** Assigns a unique key to the texture. The texture will be findable via this key using findTextureByUniqueKey(). If an existing texture has this key, it's key will be removed. */ void assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy*); @@ -86,6 +69,11 @@ public: */ GrTexture* createApproxTexture(const GrSurfaceDesc&, uint32_t flags); + /** Create an exact fit texture with no initial data to upload. + */ + sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, + uint32_t flags = 0); + /////////////////////////////////////////////////////////////////////////// // Wrapped Backend Surfaces diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp index 49753af8f9..4c9e3b4c1e 100644 --- a/src/gpu/GrSurface.cpp +++ b/src/gpu/GrSurface.cpp @@ -139,30 +139,6 @@ bool GrSurfacePriv::AdjustWritePixelParams(int surfaceWidth, ////////////////////////////////////////////////////////////////////////////// -bool GrSurface::writePixels(SkColorSpace* dstColorSpace, int left, int top, int width, int height, - GrPixelConfig config, SkColorSpace* srcColorSpace, const void* buffer, - size_t rowBytes, uint32_t pixelOpsFlags) { - // go through context so that all necessary flushing occurs - GrContext* context = this->getContext(); - if (nullptr == context) { - return false; - } - return context->writeSurfacePixels(this, dstColorSpace, left, top, width, height, config, - srcColorSpace, buffer, rowBytes, pixelOpsFlags); -} - -bool GrSurface::readPixels(SkColorSpace* srcColorSpace, int left, int top, int width, int height, - GrPixelConfig config, SkColorSpace* dstColorSpace, void* buffer, - size_t rowBytes, uint32_t pixelOpsFlags) { - // go through context so that all necessary flushing occurs - GrContext* context = this->getContext(); - if (nullptr == context) { - return false; - } - return context->readSurfacePixels(this, srcColorSpace, left, top, width, height, config, - dstColorSpace, buffer, rowBytes, pixelOpsFlags); -} - bool GrSurface::hasPendingRead() const { const GrTexture* thisTex = this->asTexture(); if (thisTex && thisTex->internalHasPendingRead()) { diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 2506540bf8..c243086f47 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -46,7 +46,7 @@ GrSurface* GrSurfaceProxy::instantiate(GrResourceProvider* resourceProvider) { if (SkBackingFit::kApprox == fFit) { fTarget = resourceProvider->createApproxTexture(fDesc, fFlags); } else { - fTarget = resourceProvider->createTexture(fDesc, fBudgeted, fFlags); + fTarget = resourceProvider->createTexture(fDesc, fBudgeted, fFlags).release(); } if (!fTarget) { return nullptr; @@ -216,9 +216,16 @@ sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferred(GrResourceProvider* resourceP const void* srcData, size_t rowBytes) { if (srcData) { - // If we have srcData, for now, we create a wrapped GrTextureProxy - sk_sp<GrTexture> tex(resourceProvider->createTexture(desc, budgeted, srcData, rowBytes)); - return GrSurfaceProxy::MakeWrapped(std::move(tex)); + GrMipLevel tempTexels; + GrMipLevel* texels = nullptr; + int levelCount = 0; + if (srcData) { + tempTexels.fPixels = srcData; + tempTexels.fRowBytes = rowBytes; + texels = &tempTexels; + levelCount = 1; + } + return resourceProvider->createMipMappedTexture(desc, budgeted, texels, levelCount); } return GrSurfaceProxy::MakeDeferred(resourceProvider, desc, SkBackingFit::kExact, budgeted); diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp index 00cc97cf53..f946290795 100644 --- a/src/gpu/GrTextureContext.cpp +++ b/src/gpu/GrTextureContext.cpp @@ -120,17 +120,14 @@ bool GrTextureContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, // TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels if (kUnpremul_SkAlphaType == dstInfo.alphaType()) { - flags |= GrContext::kUnpremul_PixelOpsFlag; + flags |= GrContextPriv::kUnpremul_PixelOpsFlag; } - // Deferral of the VRAM resources must end in this instance anyway - sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider()))); - if (!tex) { - return false; - } - - return tex->readPixels(this->getColorSpace(), x, y, dstInfo.width(), dstInfo.height(), - config, dstInfo.colorSpace(), dstBuffer, dstRowBytes, flags); + return fContext->contextPriv().readSurfacePixels(fTextureProxy.get(), this->getColorSpace(), + x, y, dstInfo.width(), dstInfo.height(), + config, + dstInfo.colorSpace(), dstBuffer, dstRowBytes, + flags); } // TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext? @@ -143,15 +140,12 @@ bool GrTextureContext::onWritePixels(const SkImageInfo& srcInfo, const void* src return false; } if (kUnpremul_SkAlphaType == srcInfo.alphaType()) { - flags |= GrContext::kUnpremul_PixelOpsFlag; - } - - // Deferral of the VRAM resources must end in this instance anyway - sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->resourceProvider()))); - if (!tex) { - return false; + flags |= GrContextPriv::kUnpremul_PixelOpsFlag; } - return tex->writePixels(this->getColorSpace(), x, y, srcInfo.width(), srcInfo.height(), - config, srcInfo.colorSpace(), srcBuffer, srcRowBytes, flags); + return fContext->contextPriv().writeSurfacePixels(fTextureProxy.get(), this->getColorSpace(), + x, y, srcInfo.width(), srcInfo.height(), + config, + srcInfo.colorSpace(), srcBuffer, srcRowBytes, + flags); } diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 56ce5455a7..5f21e1d479 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -241,13 +241,11 @@ sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext* ctx, texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes(); } - sk_sp<GrTexture> tex(ctx->resourceProvider()->createMipMappedTexture(desc, - SkBudgeted::kYes, - texels.get(), - mipLevelCount, - 0, colorMode)); - - return GrSurfaceProxy::MakeWrapped(std::move(tex)); + return ctx->resourceProvider()->createMipMappedTexture(desc, + SkBudgeted::kYes, + texels.get(), + mipLevelCount, + 0, colorMode); } sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext* ctx, const SkImageInfo& info, @@ -259,11 +257,9 @@ sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext* ctx, const SkImage } const GrCaps* caps = ctx->caps(); - sk_sp<GrTexture> tex(ctx->resourceProvider()->createMipMappedTexture( - GrImageInfoToSurfaceDesc(info, *caps), + return ctx->resourceProvider()->createMipMappedTexture(GrImageInfoToSurfaceDesc(info, *caps), SkBudgeted::kYes, texels, - mipLevelCount, 0, colorMode)); - return GrSurfaceProxy::MakeWrapped(std::move(tex)); + mipLevelCount, 0, colorMode); } sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext* ctx, diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp index 5785be2a26..26ef5963c1 100644 --- a/src/gpu/effects/GrTextureStripAtlas.cpp +++ b/src/gpu/effects/GrTextureStripAtlas.cpp @@ -162,7 +162,7 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& bitmap) { // that is not currently in use fTexContext->writePixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), 0, rowNumber * fDesc.fRowHeight, - GrContext::kDontFlush_PixelOpsFlag); + GrContextPriv::kDontFlush_PixelOpsFlag); } SkASSERT(rowNumber >= 0); diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 9c9aaa79b3..08c2e0d0ca 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -191,7 +191,7 @@ bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size uint32_t flags = 0; if (kUnpremul_SkAlphaType == rec.fInfo.alphaType() && kPremul_SkAlphaType == fAlphaType) { // let the GPU perform this transformation for us - flags = GrContext::kUnpremul_PixelOpsFlag; + flags = GrContextPriv::kUnpremul_PixelOpsFlag; } sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext( |