aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/image/SkImage_Gpu.cpp
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-03-16 14:57:21 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-16 19:27:46 +0000
commit7278d68cac9e39970144909df449113d43fff480 (patch)
tree95c86e6c9676d59e99549ddcd3fa5d727b71ec98 /src/image/SkImage_Gpu.cpp
parent7ba427ef40301d199bcd5c0f9a9d41244c495bd6 (diff)
Add DoneProc to Promise Images
This proc will notify the client when we will no longer call fulfill on their promise image so that can delete any meta data they needed to store to be able to complete the fulfill requests. Bug: skia: Change-Id: Ife1e6845f221c31ce1ae2c0d2ba5e4c8f0203b74 Reviewed-on: https://skia-review.googlesource.com/114092 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/image/SkImage_Gpu.cpp')
-rw-r--r--src/image/SkImage_Gpu.cpp59
1 files changed, 54 insertions, 5 deletions
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 6ab2ddc0b8..5a2b25106f 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -529,17 +529,58 @@ sk_sp<SkImage> SkImage::makeTextureImage(GrContext* context, SkColorSpace* dstCo
return nullptr;
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * This helper holds the normal hard ref for the Release proc as well as a hard ref on the DoneProc.
+ * Thus when a GrTexture is being released, it will unref both the ReleaseProc and DoneProc.
+ */
+class PromiseReleaseProcHelper : public GrReleaseProcHelper {
+public:
+ PromiseReleaseProcHelper(SkImage_Gpu::TextureReleaseProc releaseProc,
+ SkImage_Gpu::TextureContext context,
+ sk_sp<GrReleaseProcHelper> doneHelper)
+ : INHERITED(releaseProc, context)
+ , fDoneProcHelper(std::move(doneHelper)) {}
+
+ void weak_dispose() const override {
+ // Call the inherited weak_dispose first so that we call the ReleaseProc before the DoneProc
+ // if we hold the last ref to the DoneProc.
+ INHERITED::weak_dispose();
+ fDoneProcHelper.reset();
+ }
+
+private:
+ mutable sk_sp<GrReleaseProcHelper> fDoneProcHelper;
+
+ typedef GrReleaseProcHelper INHERITED;
+};
+
+/**
+ * This helper class manages the ref counting for the the ReleaseProc and DoneProc for promise
+ * images. It holds a weak ref on the ReleaseProc (hard refs are owned by GrTextures). The weak ref
+ * allows us to reuse an outstanding ReleaseProc (because we dropped our GrTexture but the GrTexture
+ * isn't done on the GPU) without needing to call FulfillProc again. It also holds a hard ref on the
+ * DoneProc. The idea is that after every flush we may call the ReleaseProc so that the client can
+ * free up their GPU memory if they want to. The life time of the DoneProc matches that of any
+ * outstanding ReleaseProc as well as the PromiseImageHelper. Thus we won't call the DoneProc until
+ * all ReleaseProcs are finished and we are finished with the PromiseImageHelper (i.e. won't call
+ * FulfillProc again).
+ */
class PromiseImageHelper {
public:
PromiseImageHelper(SkImage_Gpu::TextureFulfillProc fulFillProc,
SkImage_Gpu::TextureReleaseProc releaseProc,
+ SkImage_Gpu::PromiseDoneProc doneProc,
SkImage_Gpu::TextureContext context)
: fFulfillProc(fulFillProc)
, fReleaseProc(releaseProc)
- , fContext(context) {}
+ , fContext(context)
+ , fDoneHelper(new GrReleaseProcHelper(doneProc, context)) {}
void reset() {
this->resetReleaseHelper();
+ fDoneHelper.reset();
}
sk_sp<GrTexture> getTexture(GrResourceProvider* resourceProvider, GrPixelConfig config) {
@@ -567,7 +608,7 @@ public:
fReleaseProc(fContext);
return sk_sp<GrTexture>();
}
- fReleaseHelper = new GrReleaseProcHelper(fReleaseProc, fContext);
+ fReleaseHelper = new PromiseReleaseProcHelper(fReleaseProc, fContext, fDoneHelper);
// Take a weak ref
fReleaseHelper->weak_ref();
} else {
@@ -608,7 +649,11 @@ private:
GrBackendTexture fBackendTex;
// The fReleaseHelper is used to track a weak ref on the release proc. This helps us make sure
// we are always pairing fulfill and release proc calls correctly.
- GrReleaseProcHelper* fReleaseHelper = nullptr;
+ PromiseReleaseProcHelper* fReleaseHelper = nullptr;
+ // We don't want to call the fDoneHelper until we are done with the PromiseImageHelper and all
+ // ReleaseHelpers are finished. Thus we hold a hard ref here and we will pass a hard ref to each
+ // fReleaseHelper we make.
+ sk_sp<GrReleaseProcHelper> fDoneHelper;
};
sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
@@ -622,6 +667,7 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
sk_sp<SkColorSpace> colorSpace,
TextureFulfillProc textureFulfillProc,
TextureReleaseProc textureReleaseProc,
+ PromiseDoneProc promiseDoneProc,
TextureContext textureContext) {
if (!context) {
return nullptr;
@@ -631,7 +677,7 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
return nullptr;
}
- if (!textureFulfillProc || !textureReleaseProc) {
+ if (!textureFulfillProc || !textureReleaseProc || !promiseDoneProc) {
return nullptr;
}
@@ -651,7 +697,8 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
desc.fHeight = height;
desc.fConfig = config;
- PromiseImageHelper promiseHelper(textureFulfillProc, textureReleaseProc, textureContext);
+ PromiseImageHelper promiseHelper(textureFulfillProc, textureReleaseProc, promiseDoneProc,
+ textureContext);
sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
[promiseHelper, config] (GrResourceProvider* resourceProvider) mutable {
@@ -672,6 +719,8 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
std::move(colorSpace), SkBudgeted::kNo);
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
sk_sp<SkImage> SkImage::MakeCrossContextFromEncoded(GrContext* context, sk_sp<SkData> encoded,
bool buildMips, SkColorSpace* dstColorSpace) {
sk_sp<SkImage> codecImage = SkImage::MakeFromEncoded(std::move(encoded));