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>
This commit is contained in:
parent
1fda0247a7
commit
c5509955b9
@ -1326,7 +1326,7 @@ drawImage(textureImage, "backEndTexture");
|
|||||||
Retrieves the back-end API handle of texture. If flushPendingGrContextIO is true,
|
Retrieves the back-end API handle of texture. If flushPendingGrContextIO is true,
|
||||||
complete deferred I/O operations.
|
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 flushPendingGrContextIO flag to flush outstanding requests ##
|
||||||
#Param origin storage for one of: kTopLeft_GrSurfaceOrigin,
|
#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
|
#Enum CachingHint
|
||||||
|
|
||||||
#Code
|
#Code
|
||||||
|
@ -533,7 +533,7 @@ public:
|
|||||||
/** Retrieves the back-end API handle of texture. If flushPendingGrContextIO is true,
|
/** Retrieves the back-end API handle of texture. If flushPendingGrContextIO is true,
|
||||||
complete deferred I/O operations.
|
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 flushPendingGrContextIO flag to flush outstanding requests
|
||||||
@param origin storage for one of: kTopLeft_GrSurfaceOrigin,
|
@param origin storage for one of: kTopLeft_GrSurfaceOrigin,
|
||||||
@ -543,6 +543,21 @@ public:
|
|||||||
GrBackendObject getTextureHandle(bool flushPendingGrContextIO,
|
GrBackendObject getTextureHandle(bool flushPendingGrContextIO,
|
||||||
GrSurfaceOrigin* origin = nullptr) const;
|
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
|
/** \enum SkImage::CachingHint
|
||||||
CachingHint selects whether Skia may internally cache SkBitmap generated by
|
CachingHint selects whether Skia may internally cache SkBitmap generated by
|
||||||
decoding SkImage, or by copying SkImage from GPU to CPU. The default behavior
|
decoding SkImage, or by copying SkImage from GPU to CPU. The default behavior
|
||||||
|
@ -145,7 +145,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
GrBackendFormat format() const;
|
GrBackendFormat format() const;
|
||||||
|
|
||||||
|
#if GR_TEST_UTILS
|
||||||
GrPixelConfig testingOnly_getPixelConfig() const;
|
GrPixelConfig testingOnly_getPixelConfig() const;
|
||||||
|
static bool TestingOnly_Equals(const GrBackendTexture& , const GrBackendTexture&);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Friending for access to the GrPixelConfig
|
// Friending for access to the GrPixelConfig
|
||||||
@ -158,6 +161,7 @@ private:
|
|||||||
friend class GrGLGpu;
|
friend class GrGLGpu;
|
||||||
friend class GrVkGpu;
|
friend class GrVkGpu;
|
||||||
friend class PromiseImageHelper;
|
friend class PromiseImageHelper;
|
||||||
|
|
||||||
GrPixelConfig config() const { return fConfig; }
|
GrPixelConfig config() const { return fConfig; }
|
||||||
|
|
||||||
int fWidth; //<! width in pixels
|
int fWidth; //<! width in pixels
|
||||||
|
@ -113,6 +113,10 @@ struct GrGLTextureInfo {
|
|||||||
GrGLenum fTarget;
|
GrGLenum fTarget;
|
||||||
GrGLuint fID;
|
GrGLuint fID;
|
||||||
GrGLenum fFormat = 0;
|
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*));
|
GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrGLTextureInfo*));
|
||||||
|
@ -14,11 +14,19 @@
|
|||||||
struct GrMockTextureInfo {
|
struct GrMockTextureInfo {
|
||||||
GrPixelConfig fConfig;
|
GrPixelConfig fConfig;
|
||||||
int fID;
|
int fID;
|
||||||
|
|
||||||
|
bool operator==(const GrMockTextureInfo& that) const {
|
||||||
|
return fConfig == that.fConfig && fID == that.fID;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GrMockRenderTargetInfo {
|
struct GrMockRenderTargetInfo {
|
||||||
GrPixelConfig fConfig;
|
GrPixelConfig fConfig;
|
||||||
int fID;
|
int fID;
|
||||||
|
|
||||||
|
bool operator==(const GrMockRenderTargetInfo& that) const {
|
||||||
|
return fConfig == that.fConfig && fID == that.fID;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,6 +53,12 @@ struct GrVkAlloc {
|
|||||||
enum Flag {
|
enum Flag {
|
||||||
kNoncoherent_Flag = 0x1, // memory must be flushed to device after mapping
|
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:
|
private:
|
||||||
friend class GrVkHeap; // For access to usesSystemHeap
|
friend class GrVkHeap; // For access to usesSystemHeap
|
||||||
bool fUsesSystemHeap;
|
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
|
// 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.
|
// to our internal GrVkImageInfo by calling getTextureHandle on a GrVkTexture.
|
||||||
void updateImageLayout(VkImageLayout layout) { fImageLayout = layout; }
|
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*));
|
GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrVkImageInfo*));
|
||||||
|
@ -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
|
#ifdef SK_VULKAN
|
||||||
|
@ -167,6 +167,13 @@ GrBackendObject SkImage::getTextureHandle(bool flushPendingGrContextIO,
|
|||||||
return as_IB(this)->onGetTextureHandle(flushPendingGrContextIO, origin);
|
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 {
|
bool SkImage::isValid(GrContext* context) const {
|
||||||
if (context && context->contextPriv().abandoned()) {
|
if (context && context->contextPriv().abandoned()) {
|
||||||
return false;
|
return false;
|
||||||
@ -182,6 +189,11 @@ bool SkImage::isTextureBacked() const { return false; }
|
|||||||
|
|
||||||
GrBackendObject SkImage::getTextureHandle(bool, GrSurfaceOrigin*) const { return 0; }
|
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 {
|
bool SkImage::isValid(GrContext* context) const {
|
||||||
if (context) {
|
if (context) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -13,9 +13,17 @@
|
|||||||
#include "SkSurface.h"
|
#include "SkSurface.h"
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
|
#include "GrBackendSurface.h"
|
||||||
#include "GrTextureProxy.h"
|
#include "GrTextureProxy.h"
|
||||||
|
|
||||||
class GrTexture;
|
class GrTexture;
|
||||||
|
#else
|
||||||
|
class SK_API GrBackendTexture {
|
||||||
|
public:
|
||||||
|
GrBackendTexture() {}
|
||||||
|
|
||||||
|
bool isValid() const { return false; }
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
@ -59,6 +67,11 @@ public:
|
|||||||
GrSurfaceOrigin* origin) const {
|
GrSurfaceOrigin* origin) const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
virtual GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
|
||||||
|
GrSurfaceOrigin* origin) const {
|
||||||
|
return GrBackendTexture(); // invalid
|
||||||
|
}
|
||||||
|
|
||||||
virtual GrTexture* onGetTexture() const { return nullptr; }
|
virtual GrTexture* onGetTexture() const { return nullptr; }
|
||||||
#endif
|
#endif
|
||||||
virtual SkImageCacherator* peekCacherator() const { return nullptr; }
|
virtual SkImageCacherator* peekCacherator() const { return nullptr; }
|
||||||
|
@ -198,6 +198,28 @@ GrBackendObject SkImage_Gpu::onGetTextureHandle(bool flushPendingGrContextIO,
|
|||||||
return 0;
|
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 {
|
GrTexture* SkImage_Gpu::onGetTexture() const {
|
||||||
GrTextureProxy* proxy = this->peekProxy();
|
GrTextureProxy* proxy = this->peekProxy();
|
||||||
if (!proxy) {
|
if (!proxy) {
|
||||||
|
@ -51,6 +51,9 @@ public:
|
|||||||
}
|
}
|
||||||
GrBackendObject onGetTextureHandle(bool flushPendingGrContextIO,
|
GrBackendObject onGetTextureHandle(bool flushPendingGrContextIO,
|
||||||
GrSurfaceOrigin* origin) const override;
|
GrSurfaceOrigin* origin) const override;
|
||||||
|
GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
|
||||||
|
GrSurfaceOrigin* origin) const override;
|
||||||
|
|
||||||
GrTexture* onGetTexture() const override;
|
GrTexture* onGetTexture() const override;
|
||||||
|
|
||||||
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
|
||||||
|
@ -227,17 +227,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_ImageBackedGPU, reporter, ct
|
|||||||
}
|
}
|
||||||
|
|
||||||
GrSurfaceOrigin readBackOrigin;
|
GrSurfaceOrigin readBackOrigin;
|
||||||
GrBackendObject readBackHandle = srcImage->getTextureHandle(false, &readBackOrigin);
|
GrBackendTexture readBackBackendTex = srcImage->getBackendTexture(false, &readBackOrigin);
|
||||||
// TODO: Make it so we can check this (see skbug.com/5019)
|
if (!GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex)) {
|
||||||
#if 0
|
ERRORF(reporter, "backend mismatch\n");
|
||||||
if (readBackHandle != tex->getTextureHandle()) {
|
|
||||||
ERRORF(reporter, "backend mismatch %d %d\n",
|
|
||||||
(int)readBackHandle, (int)tex->getTextureHandle());
|
|
||||||
}
|
}
|
||||||
REPORTER_ASSERT(reporter, readBackHandle == tex->getTextureHandle());
|
REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex));
|
||||||
#else
|
|
||||||
REPORTER_ASSERT(reporter, SkToBool(readBackHandle));
|
|
||||||
#endif
|
|
||||||
if (readBackOrigin != texOrigin) {
|
if (readBackOrigin != texOrigin) {
|
||||||
ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, texOrigin);
|
ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, texOrigin);
|
||||||
}
|
}
|
||||||
|
@ -817,17 +817,11 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkImage_NewFromTextureRelease, reporter, c
|
|||||||
TextureReleaseChecker::Release, &releaseChecker));
|
TextureReleaseChecker::Release, &releaseChecker));
|
||||||
|
|
||||||
GrSurfaceOrigin readBackOrigin;
|
GrSurfaceOrigin readBackOrigin;
|
||||||
GrBackendObject readBackHandle = refImg->getTextureHandle(false, &readBackOrigin);
|
GrBackendTexture readBackBackendTex = refImg->getBackendTexture(false, &readBackOrigin);
|
||||||
// TODO: Make it so we can check this (see skbug.com/5019)
|
if (!GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex)) {
|
||||||
#if 0
|
ERRORF(reporter, "backend mismatch\n");
|
||||||
if (*readBackHandle != *(backendTexHandle)) {
|
|
||||||
ERRORF(reporter, "backend mismatch %d %d\n",
|
|
||||||
(int)readBackHandle, (int)backendTexHandle);
|
|
||||||
}
|
}
|
||||||
REPORTER_ASSERT(reporter, readBackHandle == backendTexHandle);
|
REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(readBackBackendTex, backendTex));
|
||||||
#else
|
|
||||||
REPORTER_ASSERT(reporter, SkToBool(readBackHandle));
|
|
||||||
#endif
|
|
||||||
if (readBackOrigin != texOrigin) {
|
if (readBackOrigin != texOrigin) {
|
||||||
ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, texOrigin);
|
ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, texOrigin);
|
||||||
}
|
}
|
||||||
|
@ -551,11 +551,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacepeekTexture_Gpu, reporter, ctxInfo) {
|
|||||||
sk_sp<SkImage> image(surface->makeImageSnapshot());
|
sk_sp<SkImage> image(surface->makeImageSnapshot());
|
||||||
|
|
||||||
REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
|
REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
|
||||||
GrBackendObject textureHandle = image->getTextureHandle(false);
|
GrBackendTexture backendTex = image->getBackendTexture(false);
|
||||||
REPORTER_ASSERT(reporter, 0 != textureHandle);
|
REPORTER_ASSERT(reporter, backendTex.isValid());
|
||||||
surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
|
surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
|
||||||
REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
|
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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user