Allow GrSurfaceProxy-derived classes to use flags when instantiating (take 2)
In some instances proxies must be created that, when instantiated, have no pending IO.
This is split out of:
https://skia-review.googlesource.com/c/8679/ (Add per-Flush callback to GrDrawingManager)
and is a reland of:
https://skia-review.googlesource.com/c/8988/ ( Allow GrSurfaceProxy-derived classes to use flags when instantiating)
Change-Id: I36f52a6d249e762bdfc1f0d7528aba6d4071e492
Reviewed-on: https://skia-review.googlesource.com/9070
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/gn/tests.gni b/gn/tests.gni
index 6646f3d..0df16d7 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -94,7 +94,6 @@
"$_tests/GrShapeTest.cpp",
"$_tests/GrSurfaceTest.cpp",
"$_tests/GrTextureMipMapInvalidationTest.cpp",
- "$_tests/GrTextureStripAtlasTest.cpp",
"$_tests/GrTRecorderTest.cpp",
"$_tests/HashTest.cpp",
"$_tests/HighContrastFilterTest.cpp",
diff --git a/include/gpu/GrTextureProvider.h b/include/gpu/GrTextureProvider.h
index cda42a8..b8d1856 100644
--- a/include/gpu/GrTextureProvider.h
+++ b/include/gpu/GrTextureProvider.h
@@ -28,7 +28,8 @@
* @param mipLevelCount The amount of elements in the texels array
*/
GrTexture* createMipMappedTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const GrMipLevel* texels, int mipLevelCount);
+ const GrMipLevel* texels, int mipLevelCount,
+ uint32_t flags = 0);
/**
* This function is a shim which creates a SkTArray<GrMipLevel> of size 1.
@@ -40,11 +41,11 @@
* field is ignored.
*/
GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, const void* srcData,
- size_t rowBytes);
+ 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) {
- return this->createTexture(desc, budgeted, nullptr, 0);
+ 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
@@ -72,18 +73,18 @@
* 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&);
+ GrTexture* createApproxTexture(const GrSurfaceDesc&, uint32_t flags = 0);
/** Legacy function that no longer should be used. */
enum ScratchTexMatch {
kExact_ScratchTexMatch,
kApprox_ScratchTexMatch
};
- GrTexture* refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match) {
+ GrTexture* refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match, uint32_t flags) {
if (kApprox_ScratchTexMatch == match) {
- return this->createApproxTexture(desc);
+ return this->createApproxTexture(desc, flags);
} else {
- return this->createTexture(desc, SkBudgeted::kYes);
+ return this->createTexture(desc, SkBudgeted::kYes, flags);
}
}
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h
index 7f026ba..63f0c21 100644
--- a/include/private/GrRenderTargetProxy.h
+++ b/include/private/GrRenderTargetProxy.h
@@ -60,7 +60,8 @@
friend class GrSurfaceProxy; // for ctors
// Deferred version
- GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, SkBackingFit, SkBudgeted);
+ GrRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&,
+ SkBackingFit, SkBudgeted, uint32_t flags);
// Wrapped version
GrRenderTargetProxy(sk_sp<GrSurface>);
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 16220e0..29e39d9 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -171,7 +171,7 @@
static sk_sp<GrTextureProxy> MakeWrapped(sk_sp<GrTexture>);
static sk_sp<GrSurfaceProxy> MakeDeferred(const GrCaps&, const GrSurfaceDesc&,
- SkBackingFit, SkBudgeted);
+ SkBackingFit, SkBudgeted, uint32_t flags = 0);
// TODO: need to refine ownership semantics of 'srcData' if we're in completely
// deferred mode
@@ -304,10 +304,11 @@
protected:
// Deferred version
- GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted)
+ GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags)
: fDesc(desc)
, fFit(fit)
, fBudgeted(budgeted)
+ , fFlags(flags)
, fGpuMemorySize(kInvalidGpuMemorySize)
, fLastOpList(nullptr) {
// Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources
@@ -329,6 +330,7 @@
const GrSurfaceDesc fDesc;
const SkBackingFit fFit; // always exact for wrapped resources
const SkBudgeted fBudgeted; // set from the backing resource for wrapped resources
+ const uint32_t fFlags;
const UniqueID fUniqueID; // set from the backing resource for wrapped resources
static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h
index 5eb3066..f4c52fb 100644
--- a/include/private/GrTextureProxy.h
+++ b/include/private/GrTextureProxy.h
@@ -29,7 +29,7 @@
// Deferred version
GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit, SkBudgeted,
- const void* srcData, size_t srcRowBytes);
+ const void* srcData, size_t srcRowBytes, uint32_t flags);
// Wrapped version
GrTextureProxy(sk_sp<GrSurface>);
diff --git a/include/private/GrTextureRenderTargetProxy.h b/include/private/GrTextureRenderTargetProxy.h
index b3a9a23..09aef75 100644
--- a/include/private/GrTextureRenderTargetProxy.h
+++ b/include/private/GrTextureRenderTargetProxy.h
@@ -26,7 +26,8 @@
friend class GrSurfaceProxy; // for ctors
// Deferred version
- GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&, SkBackingFit, SkBudgeted);
+ GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&,
+ SkBackingFit, SkBudgeted, uint32_t flags);
// Wrapped version
GrTextureRenderTargetProxy(sk_sp<GrSurface>);
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index e3f30b0..38bde0d 100644
--- a/src/gpu/GrBufferAllocPool.cpp
+++ b/src/gpu/GrBufferAllocPool.cpp
@@ -334,7 +334,7 @@
SkASSERT(buffer);
SkASSERT(startVertex);
- size_t offset = 0; // assign to suppress warning
+ size_t offset SK_INIT_TO_AVOID_WARNING;
void* ptr = INHERITED::makeSpace(vertexSize * vertexCount,
vertexSize,
buffer,
@@ -359,7 +359,7 @@
SkASSERT(buffer);
SkASSERT(startIndex);
- size_t offset = 0; // assign to suppress warning
+ size_t offset SK_INIT_TO_AVOID_WARNING;
void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t),
sizeof(uint16_t),
buffer,
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index 882acf6..b3328ab 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -18,8 +18,8 @@
// TODO: we can probably munge the 'desc' in both the wrapped and deferred
// cases to make the sampleConfig/numSamples stuff more rational.
GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
- SkBackingFit fit, SkBudgeted budgeted)
- : INHERITED(desc, fit, budgeted)
+ SkBackingFit fit, SkBudgeted budgeted, uint32_t flags)
+ : INHERITED(desc, fit, budgeted, flags)
, fFlags(GrRenderTarget::Flags::kNone) {
// Since we know the newly created render target will be internal, we are able to precompute
// what the flags will ultimately end up being.
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index bd60aa9..3cac43b 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -23,6 +23,7 @@
, fDesc(fTarget->desc())
, fFit(fit)
, fBudgeted(fTarget->resourcePriv().isBudgeted())
+ , fFlags(0)
, fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID!
, fGpuMemorySize(kInvalidGpuMemorySize)
, fLastOpList(nullptr) {
@@ -41,9 +42,9 @@
}
if (SkBackingFit::kApprox == fFit) {
- fTarget = texProvider->createApproxTexture(fDesc);
+ fTarget = texProvider->createApproxTexture(fDesc, fFlags);
} else {
- fTarget = texProvider->createTexture(fDesc, fBudgeted);
+ fTarget = texProvider->createTexture(fDesc, fBudgeted, fFlags);
}
if (!fTarget) {
return nullptr;
@@ -143,10 +144,15 @@
}
}
+#include "GrResourceProvider.h"
+
sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps,
const GrSurfaceDesc& desc,
SkBackingFit fit,
- SkBudgeted budgeted) {
+ SkBudgeted budgeted,
+ uint32_t flags) {
+ SkASSERT(0 == flags || GrResourceProvider::kNoPendingIO_Flag == flags);
+
// TODO: share this testing code with check_texture_creation_params
if (GrPixelConfigIsCompressed(desc.fConfig)) {
if (SkBackingFit::kApprox == fit || kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
@@ -191,10 +197,11 @@
if (willBeRT) {
// We know anything we instantiate later from this deferred path will be
// both texturable and renderable
- return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(caps, copyDesc, fit, budgeted));
+ return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(caps, copyDesc, fit,
+ budgeted, flags));
}
- return sk_sp<GrSurfaceProxy>(new GrTextureProxy(copyDesc, fit, budgeted, nullptr, 0));
+ return sk_sp<GrSurfaceProxy>(new GrTextureProxy(copyDesc, fit, budgeted, nullptr, 0, flags));
}
sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeDeferred(const GrCaps& caps,
@@ -205,8 +212,8 @@
size_t rowBytes) {
if (srcData) {
// If we have srcData, for now, we create a wrapped GrTextureProxy
- sk_sp<GrSurface> surf(texProvider->createTexture(desc, budgeted, srcData, rowBytes));
- return GrSurfaceProxy::MakeWrapped(std::move(surf));
+ sk_sp<GrTexture> tex(texProvider->createTexture(desc, budgeted, srcData, rowBytes));
+ return GrSurfaceProxy::MakeWrapped(std::move(tex));
}
return GrSurfaceProxy::MakeDeferred(caps, desc, SkBackingFit::kExact, budgeted);
diff --git a/src/gpu/GrTextureProvider.cpp b/src/gpu/GrTextureProvider.cpp
index 993f4b8..3790f27 100644
--- a/src/gpu/GrTextureProvider.cpp
+++ b/src/gpu/GrTextureProvider.cpp
@@ -31,7 +31,8 @@
}
GrTexture* GrTextureProvider::createMipMappedTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const GrMipLevel* texels, int mipLevelCount) {
+ const GrMipLevel* texels, int mipLevelCount,
+ uint32_t flags) {
ASSERT_SINGLE_OWNER
if (this->isAbandoned()) {
@@ -54,9 +55,8 @@
}
if (!GrPixelConfigIsCompressed(desc.fConfig)) {
if (mipLevelCount < 2) {
- static const uint32_t kFlags = kExact_ScratchTextureFlag |
- kNoCreate_ScratchTextureFlag;
- if (GrTexture* texture = this->refScratchTexture(desc, kFlags)) {
+ flags |= kExact_ScratchTextureFlag | kNoCreate_ScratchTextureFlag;
+ if (GrTexture* texture = this->refScratchTexture(desc, flags)) {
if (!mipLevelCount ||
texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
texels[0].fPixels, texels[0].fRowBytes)) {
@@ -78,7 +78,7 @@
}
GrTexture* GrTextureProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
- const void* srcData, size_t rowBytes) {
+ const void* srcData, size_t rowBytes, uint32_t flags) {
GrMipLevel tempTexels;
GrMipLevel* texels = nullptr;
int levelCount = 0;
@@ -88,12 +88,12 @@
texels = &tempTexels;
levelCount = 1;
}
- return this->createMipMappedTexture(desc, budgeted, texels, levelCount);
+ return this->createMipMappedTexture(desc, budgeted, texels, levelCount, flags);
}
-GrTexture* GrTextureProvider::createApproxTexture(const GrSurfaceDesc& desc) {
+GrTexture* GrTextureProvider::createApproxTexture(const GrSurfaceDesc& desc, uint32_t flags) {
ASSERT_SINGLE_OWNER
- return this->internalCreateApproxTexture(desc, 0);
+ return this->internalCreateApproxTexture(desc, flags);
}
GrTexture* GrTextureProvider::internalCreateApproxTexture(const GrSurfaceDesc& desc,
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index 77a8402..9a65140 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -10,8 +10,8 @@
#include "GrTextureProvider.h"
GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit fit, SkBudgeted budgeted,
- const void* srcData, size_t /*rowBytes*/)
- : INHERITED(srcDesc, fit, budgeted) {
+ const void* srcData, size_t /*rowBytes*/, uint32_t flags)
+ : INHERITED(srcDesc, fit, budgeted, flags) {
SkASSERT(!srcData); // currently handled in Make()
}
diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp
index 212ea0a..432d008 100644
--- a/src/gpu/GrTextureRenderTargetProxy.cpp
+++ b/src/gpu/GrTextureRenderTargetProxy.cpp
@@ -8,19 +8,21 @@
#include "GrTextureRenderTargetProxy.h"
// Deferred version
-// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
+// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
// GrRenderTargetProxy) so its constructor must be explicitly called.
GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
const GrSurfaceDesc& desc,
SkBackingFit fit,
- SkBudgeted budgeted)
- : GrSurfaceProxy(desc, fit, budgeted)
- , GrTextureProxy(desc, fit, budgeted, nullptr, 0) // 4 now textures w/ data are always wrapped
- , GrRenderTargetProxy(caps, desc, fit, budgeted) {
+ SkBudgeted budgeted,
+ uint32_t flags)
+ : GrSurfaceProxy(desc, fit, budgeted, flags)
+ // for now textures w/ data are always wrapped
+ , GrTextureProxy(desc, fit, budgeted, nullptr, 0, flags)
+ , GrRenderTargetProxy(caps, desc, fit, budgeted, flags) {
}
// Wrapped version
-// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
+// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
// GrRenderTargetProxy) so its constructor must be explicitly called.
GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(sk_sp<GrSurface> surf)
: GrSurfaceProxy(surf, SkBackingFit::kExact)
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index 6bc7ec0..f498304 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -8,6 +8,7 @@
#include "GrTextureStripAtlas.h"
#include "GrContext.h"
#include "GrContextPriv.h"
+#include "GrResourceProvider.h"
#include "GrSurfaceContext.h"
#include "SkGr.h"
#include "SkPixelRef.h"
@@ -209,15 +210,14 @@
// MDB TODO (caching): this side-steps the issue of proxies with unique IDs
sk_sp<GrTexture> texture(fDesc.fContext->textureProvider()->findAndRefTextureByUniqueKey(key));
if (!texture) {
- texture.reset(fDesc.fContext->textureProvider()->createTexture(texDesc, SkBudgeted::kYes,
- nullptr, 0));
+ texture.reset(fDesc.fContext->textureProvider()->createTexture(
+ texDesc, SkBudgeted::kYes,
+ nullptr, 0,
+ GrResourceProvider::kNoPendingIO_Flag));
if (!texture) {
return;
}
- // We will be issuing writes to the surface using kDontFlush_PixelOpsFlag, so we
- // need to make sure any existing IO is flushed
- fDesc.fContext->flushSurfaceIO(texture.get());
fDesc.fContext->textureProvider()->assignUniqueKeyToTexture(key, texture.get());
// This is a new texture, so all of our cache info is now invalid
this->initLRU();
diff --git a/tests/GrTextureStripAtlasTest.cpp b/tests/GrTextureStripAtlasTest.cpp
deleted file mode 100644
index 13d5d92..0000000
--- a/tests/GrTextureStripAtlasTest.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "Test.h"
-#if SK_SUPPORT_GPU
-
-#include "GrContext.h"
-#include "GrContextPriv.h"
-#include "GrGpu.h"
-#include "GrTextureStripAtlas.h"
-#include "GrTypes.h"
-
-// This tests that GrTextureStripAtlas flushes pending IO on the texture it acquires.
-DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) {
- GrContext* context = ctxInfo.grContext();
- GrSurfaceDesc desc;
- desc.fWidth = 32;
- desc.fHeight = 32;
- desc.fConfig = kRGBA_8888_GrPixelConfig;
-
- sk_sp<GrSurfaceProxy> srcProxy;
-
- {
- SkAutoTMalloc<uint32_t> pixels(desc.fWidth * desc.fHeight);
- memset(pixels.get(), 0xFF, sizeof(uint32_t) * desc.fWidth * desc.fHeight);
-
- srcProxy = GrSurfaceProxy::MakeDeferred(*context->caps(), context->textureProvider(),
- desc, SkBudgeted::kYes,
- pixels.get(), 0);
- }
-
- // Add a pending read to the src texture, and then make it available for reuse.
- sk_sp<GrSurfaceContext> dstContext;
- GrSurface* srcSurface;
-
- {
- GrSurfaceDesc targetDesc = desc;
- targetDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-
- // We can't use GrSurfaceProxy::Copy bc we may be changing the dst proxy type
- dstContext = context->contextPriv().makeDeferredSurfaceContext(targetDesc,
- SkBackingFit::kExact,
- SkBudgeted::kYes);
- REPORTER_ASSERT(reporter, dstContext);
-
- if (!dstContext->copy(srcProxy.get())) {
- return;
- }
-
- srcSurface = srcProxy->instantiate(context->textureProvider());
- // TODO: maybe add an assert here on srcSurface's ref state to ensure it is what we
- // expect.
- srcProxy.reset();
- }
-
- // Create an atlas with parameters that allow it to reuse the texture.
- GrTextureStripAtlas* atlas;
-
- {
- GrTextureStripAtlas::Desc atlasDesc;
- atlasDesc.fContext = context;
- atlasDesc.fConfig = desc.fConfig;
- atlasDesc.fWidth = desc.fWidth;
- atlasDesc.fHeight = desc.fHeight;
- atlasDesc.fRowHeight = desc.fHeight;
- atlas = GrTextureStripAtlas::GetAtlas(atlasDesc);
- }
-
- // Write to the atlas' texture.
- int lockedRow;
-
- {
- SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType);
- SkBitmap bitmap;
- bitmap.allocPixels(info);
- bitmap.eraseColor(SK_ColorBLACK);
- lockedRow = atlas->lockRow(bitmap);
- }
-
- // The atlas' use of its texture shouldn't change which pixels got copied to the target.
- {
- SkAutoTMalloc<uint8_t> actualPixels(sizeof(uint32_t) * desc.fWidth * desc.fHeight);
-
- SkImageInfo ii = SkImageInfo::Make(desc.fWidth, desc.fHeight,
- kRGBA_8888_SkColorType, kPremul_SkAlphaType);
- bool success = dstContext->readPixels(ii, actualPixels.get(), 0, 0, 0);
- REPORTER_ASSERT(reporter, success);
-
- bool good = true;
-
- const uint8_t* bytes = actualPixels.get();
- for (size_t i = 0; i < sizeof(uint32_t) * desc.fWidth * desc.fHeight; ++i, ++bytes) {
- if (0xFF != *bytes) {
- good = false;
- break;
- }
- }
-
- REPORTER_ASSERT(reporter, good);
- }
-
- if (!context->caps()->preferVRAMUseOverFlushes()) {
- sk_sp<GrTextureProxy> proxy = atlas->asTextureProxyRef();
- GrTexture* tex = proxy->instantiate(context->textureProvider());
-
- // This is kindof dodgy since we released it!
- REPORTER_ASSERT(reporter, srcSurface == tex);
- }
-
- atlas->unlockRow(lockedRow);
-}
-
-#endif