aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-02-23 17:06:10 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-24 16:09:33 +0000
commit9ad1f92e2fceea33215c0f13cee42a679fb88d44 (patch)
treef44afa1066b401ae5e3cf189078ff6fceaccca78 /include
parent20de615e3d02ff52c9a3c319ce35bcaace97be25 (diff)
Add GrExternalTextureData and SkCrossContextImageData
GrExternalTextureData is an API for exporting the backend-specific information about a texture in a type-safe way, and without pointing into the GrTexture. The new detachBackendTexture API lets us release ownership of a texture to the client. SkCrossContextImageData is the public API that lets clients upload textures on one thread/GrContext, then safely transfer ownership to another thread and GrContext for rendering. Only GL is implemented/supported right now. Vulkan support requires that we add thread-safe memory pools, or otherwise transfer the actual memory block containing the texture to the new context. BUG=skia: Change-Id: I784a3a74be69807df038c7d192eaed002c7e45ca Reviewed-on: https://skia-review.googlesource.com/8529 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'include')
-rw-r--r--include/core/SkCrossContextImageData.h68
-rw-r--r--include/core/SkImage.h9
-rw-r--r--include/gpu/GrContext.h6
-rw-r--r--include/gpu/GrExternalTextureData.h30
-rw-r--r--include/gpu/GrGpuResource.h5
-rw-r--r--include/gpu/GrTexture.h2
-rw-r--r--include/gpu/gl/GrGLTypes.h18
-rw-r--r--include/gpu/vk/GrVkTypes.h18
8 files changed, 156 insertions, 0 deletions
diff --git a/include/core/SkCrossContextImageData.h b/include/core/SkCrossContextImageData.h
new file mode 100644
index 0000000000..bbee6e742b
--- /dev/null
+++ b/include/core/SkCrossContextImageData.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef SkCrossContextImageData_DEFINED
+#define SkCrossContextImageData_DEFINED
+
+#include "SkImage.h"
+
+#if SK_SUPPORT_GPU
+#include "GrExternalTextureData.h"
+#endif
+
+class SK_API SkCrossContextImageData : SkNoncopyable {
+public:
+ /**
+ * Decodes and uploads the encoded data to a texture using the supplied GrContext, then
+ * returns an instance of SkCrossContextImageData that can be used to transport that texture
+ * to a different GrContext, across thread boundaries. The GrContext used here, and the one
+ * used to reconstruct the texture-backed image later must be in the same GL share group,
+ * or otherwise be able to share resources. After calling this, you *must* construct exactly
+ * one SkImage from the returned value, using SkImage::MakeFromCrossContextImageData.
+ *
+ * The texture will be decoded and uploaded to be suitable for use with surfaces that have the
+ * supplied destination color space. The color space of the texture itself will be determined
+ * from the encoded data.
+ */
+ static std::unique_ptr<SkCrossContextImageData> MakeFromEncoded(
+ GrContext*, sk_sp<SkData>, SkColorSpace* dstColorSpace);
+
+private:
+ SkCrossContextImageData(sk_sp<SkImage> image) : fImage(std::move(image)) {
+ SkASSERT(!fImage->isTextureBacked());
+ }
+
+#if SK_SUPPORT_GPU
+ SkCrossContextImageData(const GrBackendTextureDesc& desc,
+ std::unique_ptr<GrExternalTextureData> textureData,
+ SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace)
+ : fAlphaType(alphaType)
+ , fColorSpace(std::move(colorSpace))
+ , fDesc(desc)
+ , fTextureData(std::move(textureData)) {
+ // Point our texture desc at our copy of the backend information
+ fDesc.fTextureHandle = fTextureData->getBackendObject();
+ }
+#endif
+
+ // For non-GPU backed images
+ sk_sp<SkImage> fImage;
+
+#if SK_SUPPORT_GPU
+ // GPU-backed images store some generic information (needed to reconstruct the SkImage),
+ // and some backend-specific info (to reconstruct the texture).
+ SkAlphaType fAlphaType;
+ sk_sp<SkColorSpace> fColorSpace;
+ GrBackendTextureDesc fDesc;
+ std::unique_ptr<GrExternalTextureData> fTextureData;
+#endif
+
+ friend class SkImage;
+};
+
+#endif
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index cbd1b29c8a..93d8564192 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -18,6 +18,7 @@
class SkData;
class SkCanvas;
class SkColorTable;
+class SkCrossContextImageData;
class SkImageGenerator;
class SkPaint;
class SkPicture;
@@ -324,6 +325,14 @@ public:
sk_sp<SkImage> makeTextureImage(GrContext*, SkColorSpace* dstColorSpace) const;
/**
+ * Constructs a texture backed image from data that was previously uploaded on another thread
+ * and GrContext. The GrContext used to upload the data must be in the same GL share group as
+ * the one passed in here, or otherwise be able to share resources with the passed in context.
+ */
+ static sk_sp<SkImage> MakeFromCrossContextImageData(GrContext*,
+ std::unique_ptr<SkCrossContextImageData>);
+
+ /**
* If the image is texture-backed this will make a raster copy of it (or nullptr if reading back
* the pixels fails). Otherwise, it returns the original image.
*/
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index f268b8817a..2c24050084 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -325,6 +325,12 @@ public:
void prepareSurfaceForExternalIO(GrSurface*);
/**
+ * As above, but additionally flushes the backend API (eg calls glFlush), and returns a fence
+ * that can be used to determine if the surface is safe to use on another context or thread.
+ */
+ GrFence SK_WARN_UNUSED_RESULT prepareSurfaceForExternalIOAndFlush(GrSurface*);
+
+ /**
* An ID associated with this context, guaranteed to be unique.
*/
uint32_t uniqueID() { return fUniqueID; }
diff --git a/include/gpu/GrExternalTextureData.h b/include/gpu/GrExternalTextureData.h
new file mode 100644
index 0000000000..9ab819ce70
--- /dev/null
+++ b/include/gpu/GrExternalTextureData.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrExternalTextureData_DEFINED
+#define GrExternalTextureData_DEFINED
+
+#include "GrTypes.h"
+#include "GrTypesPriv.h"
+
+class SK_API GrExternalTextureData : SkNoncopyable {
+public:
+ GrExternalTextureData(GrFence fence) : fFence(fence) {}
+ virtual ~GrExternalTextureData() {}
+ virtual GrBackend getBackend() const = 0;
+ GrFence getFence() const { return fFence; }
+
+protected:
+ virtual GrBackendObject getBackendObject() const = 0;
+
+ GrFence fFence;
+
+ friend class SkCrossContextImageData;
+};
+
+#endif
diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h
index cc7e7aaa20..e0a7903f1d 100644
--- a/include/gpu/GrGpuResource.h
+++ b/include/gpu/GrGpuResource.h
@@ -260,6 +260,11 @@ protected:
// final class).
void registerWithCacheWrapped();
+ // This is only called by resources that are being exported from Ganesh to client code. It
+ // ensures that the cache can no longer reach this resource, and that it no longer counts
+ // against the budget.
+ void detachFromCache();
+
GrGpuResource(GrGpu*);
virtual ~GrGpuResource();
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index c032cbea29..1f63958d28 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -14,6 +14,7 @@
#include "SkPoint.h"
#include "SkRefCnt.h"
+class GrExternalTextureData;
class GrTexturePriv;
class GrTexture : virtual public GrSurface {
@@ -49,6 +50,7 @@ protected:
GrSamplerParams::FilterMode highestFilterMode, bool wasMipMapDataProvided);
void validateDesc() const;
+ virtual std::unique_ptr<GrExternalTextureData> detachBackendTexture() = 0;
private:
void computeScratchKey(GrScratchKey*) const override;
diff --git a/include/gpu/gl/GrGLTypes.h b/include/gpu/gl/GrGLTypes.h
index 5b9e31de1a..d03363c75e 100644
--- a/include/gpu/gl/GrGLTypes.h
+++ b/include/gpu/gl/GrGLTypes.h
@@ -9,6 +9,7 @@
#ifndef GrGLTypes_DEFINED
#define GrGLTypes_DEFINED
+#include "GrExternalTextureData.h"
#include "GrGLConfig.h"
/**
@@ -112,6 +113,23 @@ struct GrGLTextureInfo {
GrGLuint fID;
};
+class GrGLExternalTextureData : public GrExternalTextureData {
+public:
+ GrGLExternalTextureData(const GrGLTextureInfo& info, GrFence fence)
+ : INHERITED(fence)
+ , fInfo(info) {}
+ GrBackend getBackend() const override { return kOpenGL_GrBackend; }
+
+protected:
+ GrBackendObject getBackendObject() const override {
+ return reinterpret_cast<GrBackendObject>(&fInfo);
+ }
+
+ GrGLTextureInfo fInfo;
+
+ typedef GrExternalTextureData INHERITED;
+};
+
GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrGLTextureInfo*));
#endif
diff --git a/include/gpu/vk/GrVkTypes.h b/include/gpu/vk/GrVkTypes.h
index aa1334adca..e9a312160d 100644
--- a/include/gpu/vk/GrVkTypes.h
+++ b/include/gpu/vk/GrVkTypes.h
@@ -9,6 +9,7 @@
#ifndef GrVkTypes_DEFINED
#define GrVkTypes_DEFINED
+#include "GrExternalTextureData.h"
#include "GrTypes.h"
#include "vk/GrVkDefines.h"
@@ -59,6 +60,23 @@ struct GrVkImageInfo {
void updateImageLayout(VkImageLayout layout) { fImageLayout = layout; }
};
+class GrVkExternalTextureData : public GrExternalTextureData {
+public:
+ GrVkExternalTextureData(const GrVkImageInfo& info, GrFence fence)
+ : INHERITED(fence)
+ , fInfo(info) {}
+ GrBackend getBackend() const override { return kVulkan_GrBackend; }
+
+protected:
+ GrBackendObject getBackendObject() const override {
+ return reinterpret_cast<GrBackendObject>(&fInfo);
+ }
+
+ GrVkImageInfo fInfo;
+
+ typedef GrExternalTextureData INHERITED;
+};
+
GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrVkImageInfo*));
#endif