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,
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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*));
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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*));
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user