aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2018-04-04 15:54:55 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-04 20:34:28 +0000
commitc5509955b98daa0643da7fcd7ad356a9aa5a42da (patch)
treeb8f9628b518b8efb5c4de5fd566ca4cc10be7b07
parent1fda0247a77e5c7af57163750a3f7a04fddffdd5 (diff)
Add GrBackendTexture accessor to SkImage (take 2)
This makes accessing the GPU resource behind an SkImage a lot more typesafe. Additionally, the GrBackendObject is being deprecated so this is the path forward. I split the controversial stuff off into https://skia-review.googlesource.com/c/skia/+/118575 (Add SkImage::setLayout call). Change-Id: I297e72770e8fb360fac7c7cd74f050ae759ae133 Reviewed-on: https://skia-review.googlesource.com/118571 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r--docs/SkImage_Reference.bmh28
-rw-r--r--include/core/SkImage.h17
-rw-r--r--include/gpu/GrBackendSurface.h4
-rw-r--r--include/gpu/gl/GrGLTypes.h4
-rw-r--r--include/gpu/mock/GrMockTypes.h8
-rw-r--r--include/gpu/vk/GrVkTypes.h12
-rw-r--r--src/gpu/GrBackendSurface.cpp35
-rw-r--r--src/image/SkImage.cpp12
-rw-r--r--src/image/SkImage_Base.h13
-rw-r--r--src/image/SkImage_Gpu.cpp22
-rw-r--r--src/image/SkImage_Gpu.h3
-rw-r--r--tests/ImageFilterCacheTest.cpp15
-rw-r--r--tests/ImageTest.cpp14
-rw-r--r--tests/SurfaceTest.cpp7
14 files changed, 169 insertions, 25 deletions
diff --git a/docs/SkImage_Reference.bmh b/docs/SkImage_Reference.bmh
index 781ad71c1d..7aad9ae893 100644
--- a/docs/SkImage_Reference.bmh
+++ b/docs/SkImage_Reference.bmh
@@ -1326,7 +1326,7 @@ drawImage(textureImage, "backEndTexture");
Retrieves the back-end API handle of texture. If flushPendingGrContextIO is true,
complete deferred I/O operations.
-If origin in not nullptr, copies location of content drawn into Image.
+If origin is not nullptr, copies location of content drawn into Image.
#Param flushPendingGrContextIO flag to flush outstanding requests ##
#Param origin storage for one of: kTopLeft_GrSurfaceOrigin,
@@ -1390,6 +1390,32 @@ for (auto origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
# ------------------------------------------------------------------------------
+#Method GrBackendTexture getBackendTexture(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin = nullptr) const
+#In Property
+#Line # returns GPU reference to Image as texture ##
+
+Retrieves the backend texture. If there is none an invalid object will be returned.
+If flushPendingGrContextIO is true, complete deferred I/O operations.
+
+If origin in not nullptr, copies location of content drawn into Image.
+
+#Param flushPendingGrContextIO flag to flush outstanding requests ##
+#Param origin storage for one of: kTopLeft_GrSurfaceOrigin,
+ kBottomLeft_GrSurfaceOrigin; or nullptr
+##
+
+#Return back-end API texture handle. Invalid on failure. ##
+
+#NoExample
+##
+
+#SeeAlso MakeFromTexture isTextureBacked
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
#Enum CachingHint
#Code
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index aed0843e06..216844bc7c 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -533,7 +533,7 @@ public:
/** Retrieves the back-end API handle of texture. If flushPendingGrContextIO is true,
complete deferred I/O operations.
- If origin in not nullptr, copies location of content drawn into SkImage.
+ If origin is not nullptr, copies location of content drawn into SkImage.
@param flushPendingGrContextIO flag to flush outstanding requests
@param origin storage for one of: kTopLeft_GrSurfaceOrigin,
@@ -543,6 +543,21 @@ public:
GrBackendObject getTextureHandle(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin = nullptr) const;
+#if GR_TEST_UTILS
+ /** Retrieves the backend texture. If there is none an invalid object will be returned.
+ If flushPendingGrContextIO is true, complete deferred I/O operations.
+
+ If origin is not nullptr, copies location of content drawn into SkImage.
+
+ @param flushPendingGrContextIO flag to flush outstanding requests
+ @param origin storage for one of: kTopLeft_GrSurfaceOrigin,
+ kBottomLeft_GrSurfaceOrigin; or nullptr
+ @return back-end API texture handle. Invalid on failure.
+ */
+ GrBackendTexture getBackendTexture(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin = nullptr) const;
+#endif
+
/** \enum SkImage::CachingHint
CachingHint selects whether Skia may internally cache SkBitmap generated by
decoding SkImage, or by copying SkImage from GPU to CPU. The default behavior
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
index 02fd1621ca..106edb751e 100644
--- a/include/gpu/GrBackendSurface.h
+++ b/include/gpu/GrBackendSurface.h
@@ -145,7 +145,10 @@ public:
*/
GrBackendFormat format() const;
+#if GR_TEST_UTILS
GrPixelConfig testingOnly_getPixelConfig() const;
+ static bool TestingOnly_Equals(const GrBackendTexture& , const GrBackendTexture&);
+#endif
private:
// Friending for access to the GrPixelConfig
@@ -158,6 +161,7 @@ private:
friend class GrGLGpu;
friend class GrVkGpu;
friend class PromiseImageHelper;
+
GrPixelConfig config() const { return fConfig; }
int fWidth; //<! width in pixels
diff --git a/include/gpu/gl/GrGLTypes.h b/include/gpu/gl/GrGLTypes.h
index aecba3cb8e..c152e42d32 100644
--- a/include/gpu/gl/GrGLTypes.h
+++ b/include/gpu/gl/GrGLTypes.h
@@ -113,6 +113,10 @@ struct GrGLTextureInfo {
GrGLenum fTarget;
GrGLuint fID;
GrGLenum fFormat = 0;
+
+ bool operator==(const GrGLTextureInfo& that) const {
+ return fTarget == that.fTarget && fID == that.fID && fFormat == that.fFormat;
+ }
};
GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrGLTextureInfo*));
diff --git a/include/gpu/mock/GrMockTypes.h b/include/gpu/mock/GrMockTypes.h
index 6e38175838..5ca0730956 100644
--- a/include/gpu/mock/GrMockTypes.h
+++ b/include/gpu/mock/GrMockTypes.h
@@ -14,11 +14,19 @@
struct GrMockTextureInfo {
GrPixelConfig fConfig;
int fID;
+
+ bool operator==(const GrMockTextureInfo& that) const {
+ return fConfig == that.fConfig && fID == that.fID;
+ }
};
struct GrMockRenderTargetInfo {
GrPixelConfig fConfig;
int fID;
+
+ bool operator==(const GrMockRenderTargetInfo& that) const {
+ return fConfig == that.fConfig && fID == that.fID;
+ }
};
/**
diff --git a/include/gpu/vk/GrVkTypes.h b/include/gpu/vk/GrVkTypes.h
index 70571981b6..bfc3d5ac3e 100644
--- a/include/gpu/vk/GrVkTypes.h
+++ b/include/gpu/vk/GrVkTypes.h
@@ -53,6 +53,12 @@ struct GrVkAlloc {
enum Flag {
kNoncoherent_Flag = 0x1, // memory must be flushed to device after mapping
};
+
+ bool operator==(const GrVkAlloc& that) const {
+ return fMemory == that.fMemory && fOffset == that.fOffset && fSize == that.fSize &&
+ fFlags == that.fFlags && fUsesSystemHeap == that.fUsesSystemHeap;
+ }
+
private:
friend class GrVkHeap; // For access to usesSystemHeap
bool fUsesSystemHeap;
@@ -73,6 +79,12 @@ struct GrVkImageInfo {
// while we're still holding onto the wrapped texture. They will first need to get a handle
// to our internal GrVkImageInfo by calling getTextureHandle on a GrVkTexture.
void updateImageLayout(VkImageLayout layout) { fImageLayout = layout; }
+
+ bool operator==(const GrVkImageInfo& that) const {
+ return fImage == that.fImage && fAlloc == that.fAlloc &&
+ fImageTiling == that.fImageTiling && fImageLayout == that.fImageLayout &&
+ fFormat == that.fFormat && fLevelCount == that.fLevelCount;
+ }
};
GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrVkImageInfo*));
diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp
index 6f48a758a8..978e66db0b 100644
--- a/src/gpu/GrBackendSurface.cpp
+++ b/src/gpu/GrBackendSurface.cpp
@@ -165,6 +165,41 @@ GrBackendFormat GrBackendTexture::format() const {
}
}
+#if GR_TEST_UTILS
+bool GrBackendTexture::TestingOnly_Equals(const GrBackendTexture& t0, const GrBackendTexture& t1) {
+ if (!t0.isValid() || !t1.isValid()) {
+ return false; // two invalid backend textures are not considered equal
+ }
+
+ if (t0.fWidth != t1.fWidth ||
+ t0.fHeight != t1.fHeight ||
+ t0.fConfig != t1.fConfig ||
+ t0.fMipMapped != t1.fMipMapped ||
+ t0.fBackend != t1.fBackend) {
+ return false;
+ }
+
+ switch (t0.fBackend) {
+ case kOpenGL_GrBackend:
+ return t0.fGLInfo == t1.fGLInfo;
+ case kMock_GrBackend:
+ return t0.fMockInfo == t1.fMockInfo;
+ case kVulkan_GrBackend:
+#ifdef SK_VULKAN
+ return t0.fVkInfo == t1.fVkInfo;
+#else
+ // fall through
+#endif
+ case kMetal_GrBackend: // fall through
+ default:
+ return false;
+ }
+
+ SkASSERT(0);
+ return false;
+}
+#endif
+
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef SK_VULKAN
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 40daa6fbc3..4f8fe74d30 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -167,6 +167,13 @@ GrBackendObject SkImage::getTextureHandle(bool flushPendingGrContextIO,
return as_IB(this)->onGetTextureHandle(flushPendingGrContextIO, origin);
}
+#if GR_TEST_UTILS
+GrBackendTexture SkImage::getBackendTexture(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin) const {
+ return as_IB(this)->onGetBackendTexture(flushPendingGrContextIO, origin);
+}
+#endif
+
bool SkImage::isValid(GrContext* context) const {
if (context && context->contextPriv().abandoned()) {
return false;
@@ -182,6 +189,11 @@ bool SkImage::isTextureBacked() const { return false; }
GrBackendObject SkImage::getTextureHandle(bool, GrSurfaceOrigin*) const { return 0; }
+GrBackendTexture SkImage::getBackendTexture(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin) const {
+ return GrBackendTexture(); // invalid
+}
+
bool SkImage::isValid(GrContext* context) const {
if (context) {
return false;
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index b3bbbc4080..950163a079 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -13,9 +13,17 @@
#include "SkSurface.h"
#if SK_SUPPORT_GPU
+ #include "GrBackendSurface.h"
#include "GrTextureProxy.h"
class GrTexture;
+#else
+class SK_API GrBackendTexture {
+public:
+ GrBackendTexture() {}
+
+ bool isValid() const { return false; }
+};
#endif
#include <new>
@@ -59,6 +67,11 @@ public:
GrSurfaceOrigin* origin) const {
return 0;
}
+ virtual GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin) const {
+ return GrBackendTexture(); // invalid
+ }
+
virtual GrTexture* onGetTexture() const { return nullptr; }
#endif
virtual SkImageCacherator* peekCacherator() const { return nullptr; }
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 3c05f1d219..0dd7e95843 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -198,6 +198,28 @@ GrBackendObject SkImage_Gpu::onGetTextureHandle(bool flushPendingGrContextIO,
return 0;
}
+GrBackendTexture SkImage_Gpu::onGetBackendTexture(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin) const {
+ SkASSERT(fProxy);
+
+ if (!fProxy->instantiate(fContext->contextPriv().resourceProvider())) {
+ return GrBackendTexture(); // invalid
+ }
+
+ GrTexture* texture = fProxy->priv().peekTexture();
+
+ if (texture) {
+ if (flushPendingGrContextIO) {
+ fContext->contextPriv().prepareSurfaceForExternalIO(fProxy.get());
+ }
+ if (origin) {
+ *origin = fProxy->origin();
+ }
+ return texture->getBackendTexture();
+ }
+ return GrBackendTexture(); // invalid
+}
+
GrTexture* SkImage_Gpu::onGetTexture() const {
GrTextureProxy* proxy = this->peekProxy();
if (!proxy) {
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index 7a4fa9751a..af7c1fac6a 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -51,6 +51,9 @@ public:
}
GrBackendObject onGetTextureHandle(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin) const override;
+ GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin) const override;
+
GrTexture* onGetTexture() const override;
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
diff --git a/tests/ImageFilterCacheTest.cpp b/tests/ImageFilterCacheTest.cpp
index a541c1c546..e9c9f0b14e 100644
--- a/tests/ImageFilterCacheTest.cpp
+++ b/tests/ImageFilterCacheTest.cpp
@@ -227,17 +227,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_ImageBackedGPU, reporter, ct
}
GrSurfaceOrigin readBackOrigin;
- GrBackendObject readBackHandle = srcImage->getTextureHandle(false, &readBackOrigin);
- // TODO: Make it so we can check this (see skbug.com/5019)
-#if 0
- if (readBackHandle != tex->getTextureHandle()) {
- ERRORF(reporter, "backend mismatch %d %d\n",
- (int)readBackHandle, (int)tex->getTextureHandle());
+ GrBackendTexture readBackBackendTex = srcImage->getBackendTexture(false, &readBackOrigin);
+ if (!GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex)) {
+ ERRORF(reporter, "backend mismatch\n");
}
- REPORTER_ASSERT(reporter, readBackHandle == tex->getTextureHandle());
-#else
- REPORTER_ASSERT(reporter, SkToBool(readBackHandle));
-#endif
+ REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex));
+
if (readBackOrigin != texOrigin) {
ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, texOrigin);
}
diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp
index 98c2f03c2e..fd9baecd4b 100644
--- a/tests/ImageTest.cpp
+++ b/tests/ImageTest.cpp
@@ -817,17 +817,11 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkImage_NewFromTextureRelease, reporter, c
TextureReleaseChecker::Release, &releaseChecker));
GrSurfaceOrigin readBackOrigin;
- GrBackendObject readBackHandle = refImg->getTextureHandle(false, &readBackOrigin);
- // TODO: Make it so we can check this (see skbug.com/5019)
-#if 0
- if (*readBackHandle != *(backendTexHandle)) {
- ERRORF(reporter, "backend mismatch %d %d\n",
- (int)readBackHandle, (int)backendTexHandle);
+ GrBackendTexture readBackBackendTex = refImg->getBackendTexture(false, &readBackOrigin);
+ if (!GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex)) {
+ ERRORF(reporter, "backend mismatch\n");
}
- REPORTER_ASSERT(reporter, readBackHandle == backendTexHandle);
-#else
- REPORTER_ASSERT(reporter, SkToBool(readBackHandle));
-#endif
+ REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex));
if (readBackOrigin != texOrigin) {
ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, texOrigin);
}
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index e74dcc915c..744dd63a42 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -551,11 +551,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacepeekTexture_Gpu, reporter, ctxInfo) {
sk_sp<SkImage> image(surface->makeImageSnapshot());
REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
- GrBackendObject textureHandle = image->getTextureHandle(false);
- REPORTER_ASSERT(reporter, 0 != textureHandle);
+ GrBackendTexture backendTex = image->getBackendTexture(false);
+ REPORTER_ASSERT(reporter, backendTex.isValid());
surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
- REPORTER_ASSERT(reporter, textureHandle == image->getTextureHandle(false));
+ GrBackendTexture backendTex2 = image->getBackendTexture(false);
+ REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(backendTex, backendTex2));
}
}
#endif