aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-04-05 12:18:58 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-04-05 17:00:10 +0000
commitaaee31f18c0845417103d84285e365575def3c40 (patch)
tree9d0cea264cacdf51f64919ffc8f2b2d5dc83e961 /src
parentbabb101291784b844a99b20b5164b271758f6d33 (diff)
Rm readPixels from GrSurface & move read/writeSurfacePixels to GrContextPriv (take 2)
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. This is a reland of: https://skia-review.googlesource.com/c/11200/ (Rm readPixels from GrSurface & move read/writeSurfacePixels to GrContextPriv) Change-Id: Icd0a90d2beb483dc24ed87c3bace9c817019e148 Reviewed-on: https://skia-review.googlesource.com/11326 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrContext.cpp124
-rw-r--r--src/gpu/GrContextPriv.h62
-rw-r--r--src/gpu/GrRenderTargetContext.cpp35
-rw-r--r--src/gpu/GrResourceProvider.cpp68
-rw-r--r--src/gpu/GrResourceProvider.h30
-rw-r--r--src/gpu/GrSurface.cpp24
-rw-r--r--src/gpu/GrSurfaceProxy.cpp15
-rw-r--r--src/gpu/GrTextureContext.cpp30
-rw-r--r--src/gpu/SkGr.cpp18
-rw-r--r--src/gpu/effects/GrTextureStripAtlas.cpp2
-rw-r--r--src/image/SkImage_Gpu.cpp2
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(