aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-01-17 10:52:04 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-17 16:27:17 +0000
commite728f676d6dfcaaa1b9727a85985b52eed7cf911 (patch)
tree082e217153eaf47f16d8c0b545c232333eb34b5c
parent2e0fadb06c6aa7e74118694a30727f6e3ea45573 (diff)
Update to GrBackendTexutreImageGenerator to support lazy texture proxies
Bug: skia: Change-Id: I7cce869894e274250f49328550a0ae2d8e04de74 Reviewed-on: https://skia-review.googlesource.com/95022 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
-rw-r--r--include/gpu/GrBackendSurface.h1
-rw-r--r--src/gpu/GrBackendTextureImageGenerator.cpp97
-rw-r--r--src/gpu/GrBackendTextureImageGenerator.h3
-rw-r--r--src/gpu/GrTextureProxy.cpp1
-rw-r--r--tests/GrMipMappedTest.cpp4
5 files changed, 74 insertions, 32 deletions
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
index f2381c2d0d..4cc6da3566 100644
--- a/include/gpu/GrBackendSurface.h
+++ b/include/gpu/GrBackendSurface.h
@@ -85,6 +85,7 @@ private:
// Friending for access to the GrPixelConfig
friend class SkImage;
friend class SkSurface;
+ friend class GrBackendTextureImageGenerator;
friend class GrGpu;
friend class GrGLGpu;
friend class GrVkGpu;
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 36dc139cab..efd366e63d 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -13,6 +13,7 @@
#include "GrRenderTargetContext.h"
#include "GrResourceCache.h"
#include "GrResourceProvider.h"
+#include "GrResourceProviderPriv.h"
#include "GrSemaphore.h"
#include "GrTexture.h"
#include "GrTexturePriv.h"
@@ -63,6 +64,7 @@ GrBackendTextureImageGenerator::GrBackendTextureImageGenerator(const SkImageInfo
, fRefHelper(new RefHelper(texture, owningContextID))
, fSemaphore(std::move(semaphore))
, fBackendTexture(backendTex)
+ , fConfig(backendTex.config())
, fSurfaceOrigin(origin) { }
GrBackendTextureImageGenerator::~GrBackendTextureImageGenerator() {
@@ -89,46 +91,81 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
return nullptr;
}
- sk_sp<GrTexture> tex;
-
uint32_t expectedID = SK_InvalidGenID;
if (!fRefHelper->fBorrowingContextID.compare_exchange(&expectedID, context->uniqueID())) {
if (fRefHelper->fBorrowingContextID != context->uniqueID()) {
// Some other context is currently borrowing the texture. We aren't allowed to use it.
return nullptr;
}
- } else {
- if (fSemaphore && !fSemaphore->hasSubmittedWait()) {
- context->getGpu()->waitSemaphore(fSemaphore);
- }
- }
-
- if (fRefHelper->fBorrowedTexture) {
- // If a client re-draws the same image multiple times, the texture we return will be cached
- // and re-used. If they draw a subset, though, we may be re-called. In that case, we want
- // to re-use the borrowed texture we've previously created.
- tex = sk_ref_sp(fRefHelper->fBorrowedTexture);
- SkASSERT(tex);
- } else {
- // We just gained access to the texture. If we're on the original context, we could use the
- // original texture, but we'd have no way of detecting that it's no longer in-use. So we
- // always make a wrapped copy, where the release proc informs us that the context is done
- // with it. This is unfortunate - we'll have two texture objects referencing the same GPU
- // object. However, no client can ever see the original texture, so this should be safe.
- tex = context->contextPriv().resourceProvider()->wrapBackendTexture(
- fBackendTexture, kBorrow_GrWrapOwnership);
- if (!tex) {
- return nullptr;
- }
- fRefHelper->fBorrowedTexture = tex.get();
-
- tex->setRelease(ReleaseRefHelper_TextureReleaseProc, fRefHelper);
- fRefHelper->ref();
}
SkASSERT(fRefHelper->fBorrowingContextID == context->uniqueID());
- sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), fSurfaceOrigin);
+ GrSurfaceDesc desc;
+ desc.fOrigin = fSurfaceOrigin;
+ desc.fWidth = fBackendTexture.width();
+ desc.fHeight = fBackendTexture.height();
+ desc.fConfig = fConfig;
+ GrMipMapped mipMapped = fBackendTexture.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo;
+
+ // Must make copies of member variables to capture in the lambda since this image generator may
+ // be deleted before we actuallly execute the lambda.
+ GrSurfaceOrigin surfaceOrigin = fSurfaceOrigin;
+ sk_sp<GrSemaphore> semaphore = fSemaphore;
+ GrBackendTexture backendTexture = fBackendTexture;
+ RefHelper* refHelper = fRefHelper;
+ refHelper->ref();
+
+ sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeLazy(
+ [refHelper, semaphore, backendTexture, surfaceOrigin]
+ (GrResourceProvider* resourceProvider, GrSurfaceOrigin* outOrigin) {
+ if (!resourceProvider) {
+ // If we get here then we never created a texture to pass the refHelper ref off
+ // to. Thus we must unref it ourselves.
+ refHelper->unref();
+ return sk_sp<GrTexture>();
+ }
+
+ if (semaphore && !semaphore->hasSubmittedWait()) {
+ resourceProvider->priv().gpu()->waitSemaphore(semaphore);
+ }
+
+ sk_sp<GrTexture> tex;
+ if (refHelper->fBorrowedTexture) {
+ // If a client re-draws the same image multiple times, the texture we return
+ // will be cached and re-used. If they draw a subset, though, we may be
+ // re-called. In that case, we want to re-use the borrowed texture we've
+ // previously created.
+ tex = sk_ref_sp(refHelper->fBorrowedTexture);
+ SkASSERT(tex);
+ // The texture is holding onto a ref to the refHelper so since we have a ref to
+ // the texture we don't need to hold a ref to the refHelper. This unref's the
+ // ref we grabbed on refHelper in the lambda capture for this proxy.
+ refHelper->unref();
+ } else {
+ // We just gained access to the texture. If we're on the original context, we
+ // could use the original texture, but we'd have no way of detecting that it's
+ // no longer in-use. So we always make a wrapped copy, where the release proc
+ // informs us that the context is done with it. This is unfortunate - we'll have
+ // two texture objects referencing the same GPU object. However, no client can
+ // ever see the original texture, so this should be safe.
+ tex = resourceProvider->wrapBackendTexture(backendTexture,
+ kBorrow_GrWrapOwnership);
+ if (!tex) {
+ refHelper->unref();
+ return sk_sp<GrTexture>();
+ }
+ refHelper->fBorrowedTexture = tex.get();
+
+ // By setting this release proc on the texture we are passing our ref on the
+ // refHelper to the texture.
+ tex->setRelease(ReleaseRefHelper_TextureReleaseProc, refHelper);
+ }
+
+ *outOrigin = surfaceOrigin;
+ return tex;
+
+ }, desc, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
if (0 == origin.fX && 0 == origin.fY &&
info.width() == fBackendTexture.width() && info.height() == fBackendTexture.height() &&
diff --git a/src/gpu/GrBackendTextureImageGenerator.h b/src/gpu/GrBackendTextureImageGenerator.h
index ef96e6a238..f13a59345a 100644
--- a/src/gpu/GrBackendTextureImageGenerator.h
+++ b/src/gpu/GrBackendTextureImageGenerator.h
@@ -54,7 +54,7 @@ private:
: fOriginalTexture(texture)
, fOwningContextID(owningContextID)
, fBorrowedTexture(nullptr)
- , fBorrowingContextID(SK_InvalidGenID) { }
+ , fBorrowingContextID(SK_InvalidGenID) {}
~RefHelper();
@@ -73,6 +73,7 @@ private:
sk_sp<GrSemaphore> fSemaphore;
GrBackendTexture fBackendTexture;
+ GrPixelConfig fConfig;
GrSurfaceOrigin fSurfaceOrigin;
typedef SkImageGenerator INHERITED;
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index 68153dd50b..9eca5d9876 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -148,7 +148,6 @@ void GrTextureProxy::clearUniqueKey() {
#ifdef SK_DEBUG
void GrTextureProxy::validateLazyTexture(const GrTexture* texture) {
SkASSERT(!texture->asRenderTarget());
- SkASSERT(GrMipMapped::kNo == this->mipMapped());
}
#endif
diff --git a/tests/GrMipMappedTest.cpp b/tests/GrMipMappedTest.cpp
index 04bcca7c4d..df1e8ee901 100644
--- a/tests/GrMipMappedTest.cpp
+++ b/tests/GrMipMappedTest.cpp
@@ -155,6 +155,10 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter,
return;
}
+ if (GrSurfaceProxy::LazyState::kNot != genProxy->lazyInstantiationState()) {
+ genProxy->priv().doLazyInstantiation(context->contextPriv().resourceProvider());
+ }
+
REPORTER_ASSERT(reporter, genProxy->priv().isInstantiated());
GrTexture* genTexture = genProxy->priv().peekTexture();