Add a deferred copy surface (take 3)
This CL forces all GrSurface copies to go through a GrSurfaceContext (rather than GrContext).
There is a bit of goofiness going on here until read/writePixels is also consolidated in GrSurfaceContext and a proxy-backed SkImage/SkSurface is added.
This is a reland of https://skia-review.googlesource.com/c/5773/ (Add a deferred copy surface)
Change-Id: Ib8fd96d0569274ef781366eb900ed8ee839ae9bd
Reviewed-on: https://skia-review.googlesource.com/6109
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 2567bf1..4f48f78 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -17,6 +17,7 @@
#if SK_SUPPORT_GPU
#include "GrContext.h"
+#include "GrSurfaceContext.h"
#include "GrTexture.h"
#include "GrSamplerParams.h"
#include "GrTextureProxy.h"
@@ -346,6 +347,20 @@
#include "GrTexture.h"
#include "SkImage_Gpu.h"
+static sk_sp<SkImage> wrap_proxy_in_image(GrContext* context, GrSurfaceProxy* proxy,
+ SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace) {
+ // TODO: add GrTextureProxy-backed SkImage_Gpus
+ GrSurface* surf = proxy->instantiate(context->textureProvider());
+ if (!surf) {
+ return nullptr;
+ }
+
+ return sk_make_sp<SkImage_Gpu>(proxy->width(), proxy->height(),
+ kNeedNewImageUniqueID, alphaType,
+ sk_ref_sp(surf->asTexture()),
+ std::move(colorSpace), SkBudgeted::kYes);
+}
+
class SkSpecialImage_Gpu : public SkSpecialImage_Base {
public:
SkSpecialImage_Gpu(const SkIRect& subset,
@@ -478,34 +493,21 @@
fAlphaType);
}
+ // TODO: move all the logic here into the subset-flavor GrSurfaceProxy::copy?
sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override {
- // TODO: add GrTextureProxy-backed SkImage_Gpus
- GrSurface* surf = fSurfaceProxy->instantiate(fContext->textureProvider());
- if (!surf) {
- return nullptr;
- }
-
+ // TODO: this is problematic since the surfaceProxy could be loose
if (0 == subset.fLeft && 0 == subset.fTop &&
fSurfaceProxy->width() == subset.width() &&
fSurfaceProxy->height() == subset.height()) {
// The existing GrTexture is already tight so reuse it in the SkImage
- return sk_make_sp<SkImage_Gpu>(surf->width(), surf->height(),
- kNeedNewImageUniqueID, fAlphaType,
- sk_ref_sp(surf->asTexture()),
- fColorSpace, SkBudgeted::kYes);
+ return wrap_proxy_in_image(fContext, fSurfaceProxy.get(),
+ fAlphaType, fColorSpace);
}
- GrSurfaceDesc desc = fSurfaceProxy->desc();
- desc.fWidth = subset.width();
- desc.fHeight = subset.height();
+ sk_sp<GrSurfaceProxy> subsetProxy(GrSurfaceProxy::Copy(fContext, fSurfaceProxy.get(),
+ subset, SkBudgeted::kYes));
- sk_sp<GrTexture> subTx(fContext->textureProvider()->createTexture(desc, SkBudgeted::kYes));
- if (!subTx) {
- return nullptr;
- }
- fContext->copySurface(subTx.get(), surf, subset, SkIPoint::Make(0, 0));
- return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
- fAlphaType, std::move(subTx), fColorSpace, SkBudgeted::kYes);
+ return wrap_proxy_in_image(fContext, subsetProxy.get(), fAlphaType, fColorSpace);
}
sk_sp<SkSurface> onMakeTightSurface(const SkImageFilter::OutputProperties& outProps,