diff options
31 files changed, 324 insertions, 5 deletions
diff --git a/docs/SkImage_Reference.bmh b/docs/SkImage_Reference.bmh index 7f66ccca32..9cf69d7adb 100644 --- a/docs/SkImage_Reference.bmh +++ b/docs/SkImage_Reference.bmh @@ -1322,6 +1322,13 @@ drawImage(textureImage, "backEndTexture"); # ------------------------------------------------------------------------------ +#Method GrBackendObject getTextureHandle(bool flushPendingGrContextIO, + GrSurfaceOrigin* origin = nullptr) const +#Deprecated +#Method ## + +# ------------------------------------------------------------------------------ + #Method GrBackendTexture getBackendTexture(bool flushPendingGrContextIO, GrSurfaceOrigin* origin = nullptr) const #In Property diff --git a/docs/SkSurface_Reference.bmh b/docs/SkSurface_Reference.bmh index 1f09a964b7..0c4b43483b 100644 --- a/docs/SkSurface_Reference.bmh +++ b/docs/SkSurface_Reference.bmh @@ -975,14 +975,14 @@ Caller must overwrite the entire back-end object. int y = 20; SkString str; paint.setTextSize(16); - for (auto access : { SkSurface::kFlushRead_BackendHandleAccess, + for (auto access : { SkSurface::kFlushRead_BackendHandleAccess, SkSurface::kFlushWrite_BackendHandleAccess, SkSurface::kDiscardWrite_BackendHandleAccess } ) { sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); str.printf("uniqueID=%d", image->uniqueID()); canvas->drawString(str, 20, y += 20, paint); - GrBackendTexture backendTex = gpuSurface->getBackendTexture(access); - str.printf("backendTex is %svalid", backendTex.isValid() ? '' : 'not '); + GrBackendObject backendObject = gpuSurface->getTextureHandle(access); + str.printf("backendObject %c= 0", backendObject != 0 ? '!' : '='); canvas->drawString(str, 20, y += 20, paint); } sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); @@ -996,6 +996,19 @@ Caller must overwrite the entire back-end object. # ------------------------------------------------------------------------------ +#Method GrBackendObject getTextureHandle(BackendHandleAccess backendHandleAccess) +#Deprecated +#Method ## + +# ------------------------------------------------------------------------------ + +#Method bool getRenderTargetHandle(GrBackendObject* backendObject, + BackendHandleAccess backendHandleAccess) +#Deprecated +#Method ## + +# ------------------------------------------------------------------------------ + #Method GrBackendTexture getBackendTexture(BackendHandleAccess backendHandleAccess) #In Property #Line # returns the GPU reference to texture ## @@ -1579,8 +1592,8 @@ and the client will still own the semaphores. context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64)); surface->flushAndSignalSemaphores(1, &semaphore); sk_sp<SkImage> image = surface->makeImageSnapshot(); - GrBackendTexture backendTex = image->getBackendTexture(false); // unused - SkASSERT(backendTex.isValid()); + GrBackendObject backendImage = image->getTextureHandle(false); // unused + SkASSERT(backendImage); const SkImageInfo childImageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, kPremul_SkAlphaType); sk_sp<SkSurface> childSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, diff --git a/include/core/SkImage.h b/include/core/SkImage.h index 7e1ffaac66..6d3ae42fa4 100644 --- a/include/core/SkImage.h +++ b/include/core/SkImage.h @@ -534,6 +534,21 @@ public: */ bool isValid(GrContext* context) const; +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + /** Retrieves the back-end API handle of texture. 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, or nullptr + */ + GrBackendObject getTextureHandle(bool flushPendingGrContextIO, + GrSurfaceOrigin* origin = nullptr) const; +#endif + /** Retrieves the backend texture. If SkImage has no backend texture, an invalid object is returned. Call GrBackendTexture::isValid to determine if the result is valid. diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h index 83a59f14fb..fb0a3685d7 100644 --- a/include/core/SkSurface.h +++ b/include/core/SkSurface.h @@ -428,6 +428,39 @@ public: static const BackendHandleAccess kDiscardWrite_TextureHandleAccess = kDiscardWrite_BackendHandleAccess; +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + /** Returns the GPU back-end reference of the texture used by SkSurface, or zero + if SkSurface is not backed by a GPU texture. + + The returned texture handle is only valid until the next draw into SkSurface, + or when SkSurface is deleted. + + @param backendHandleAccess one of: kFlushRead_BackendHandleAccess, + kFlushWrite_BackendHandleAccess, kDiscardWrite_BackendHandleAccess + @return GPU texture reference + */ + GrBackendObject getTextureHandle(BackendHandleAccess backendHandleAccess); + + /** Returns true and stores the GPU back-end reference of the render target used + by SkSurface in backendObject. + + Return false if SkSurface is not backed by a GPU render target, and leaves + backendObject unchanged. + + The returned render target handle is only valid until the next draw into SkSurface, + or when SkSurface is deleted. + + In OpenGL this returns the frame buffer object ID. + + @param backendObject GPU intermediate memory buffer + @param backendHandleAccess one of: kFlushRead_BackendHandleAccess, + kFlushWrite_BackendHandleAccess, kDiscardWrite_BackendHandleAccess + @return true if SkSurface is backed by GPU texture + */ + bool getRenderTargetHandle(GrBackendObject* backendObject, + BackendHandleAccess backendHandleAccess); +#endif + /** Retrieves the backend texture. If Surface has no backend texture, an invalid object is returned. Call GrBackendTexture::isValid to determine if the result is valid. diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h index 784e15f8b0..1c86eaa374 100644 --- a/include/gpu/GrRenderTarget.h +++ b/include/gpu/GrRenderTarget.h @@ -99,6 +99,14 @@ public: }; virtual ResolveType getResolveType() const = 0; +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + /** + * Return the native ID or handle to the rendertarget, depending on the + * platform. e.g. on OpenGL, return the FBO ID. + */ + virtual GrBackendObject getRenderTargetHandle() const = 0; +#endif + virtual GrBackendRenderTarget getBackendRenderTarget() const = 0; // Checked when this object is asked to attach a stencil buffer. diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h index 1f75c1f9be..f7fdb77207 100644 --- a/include/gpu/GrTexture.h +++ b/include/gpu/GrTexture.h @@ -25,6 +25,14 @@ public: GrTexture* asTexture() override { return this; } const GrTexture* asTexture() const override { return this; } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + /** + * Return the native ID or handle to the texture, depending on the + * platform. e.g. on OpenGL, return the texture ID. + */ + virtual GrBackendObject getTextureHandle() const = 0; +#endif + virtual GrBackendTexture getBackendTexture() const = 0; /** diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index f908d1e1f6..d0e977ebc1 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -207,6 +207,14 @@ enum class GrMipMapped : bool { /////////////////////////////////////////////////////////////////////////////// +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +/** + * Opaque type for 3D API object handles. We are moving away from this type and towards type-safe + * GrBackend* classes (e.g. GrBackendTexture). However, not all replacement APIs are in place yet. + */ +typedef intptr_t GrBackendObject; +#endif + /** * GPU SkImage and SkSurfaces can be stored such that (0, 0) in texture space may correspond to * either the top-left or bottom-left content pixel. diff --git a/include/gpu/gl/GrGLTypes.h b/include/gpu/gl/GrGLTypes.h index 5916c69181..75aa87d971 100644 --- a/include/gpu/gl/GrGLTypes.h +++ b/include/gpu/gl/GrGLTypes.h @@ -128,4 +128,9 @@ struct GrGLFramebufferInfo { } }; +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrGLTextureInfo*)); +GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrGLFramebufferInfo*)); +#endif + #endif diff --git a/include/gpu/vk/GrVkTypes.h b/include/gpu/vk/GrVkTypes.h index 0f7ff71d2e..68b7f63064 100644 --- a/include/gpu/vk/GrVkTypes.h +++ b/include/gpu/vk/GrVkTypes.h @@ -112,4 +112,8 @@ struct GrVkImageInfo { } }; +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GR_STATIC_ASSERT(sizeof(GrBackendObject) >= sizeof(const GrVkImageInfo*)); +#endif + #endif diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h index a9ec3c385c..4412dcf425 100644 --- a/src/gpu/gl/GrGLRenderTarget.h +++ b/src/gpu/gl/GrGLRenderTarget.h @@ -61,6 +61,10 @@ public: } } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getRenderTargetHandle() const override { return fRTFBOID; } +#endif + GrBackendRenderTarget getBackendRenderTarget() const override; bool canAttemptStencilAttachment() const override; diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp index 2d674f4756..bf22bdb751 100644 --- a/src/gpu/gl/GrGLTexture.cpp +++ b/src/gpu/gl/GrGLTexture.cpp @@ -97,6 +97,12 @@ void GrGLTexture::onAbandon() { INHERITED::onAbandon(); } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject GrGLTexture::getTextureHandle() const { + return reinterpret_cast<GrBackendObject>(&fInfo); +} +#endif + GrBackendTexture GrGLTexture::getBackendTexture() const { return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), fInfo); } diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h index 67eab4312e..fcc85bc700 100644 --- a/src/gpu/gl/GrGLTexture.h +++ b/src/gpu/gl/GrGLTexture.h @@ -39,6 +39,9 @@ public: SkASSERT(!fReleaseHelper); } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getTextureHandle() const override; +#endif GrBackendTexture getBackendTexture() const override; void textureParamsModified() override { fTexParams.invalidate(); } diff --git a/src/gpu/mock/GrMockTexture.h b/src/gpu/mock/GrMockTexture.h index 24ef009229..071b4f4615 100644 --- a/src/gpu/mock/GrMockTexture.h +++ b/src/gpu/mock/GrMockTexture.h @@ -31,6 +31,11 @@ public: ~GrMockTexture() override {} +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getTextureHandle() const override { + return reinterpret_cast<GrBackendObject>(&fInfo); + } +#endif GrBackendTexture getBackendTexture() const override { return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), fInfo); @@ -115,6 +120,12 @@ public: return {this->width(), this->height(), this->numColorSamples(), numStencilBits, fInfo}; } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getRenderTargetHandle() const override { + return reinterpret_cast<GrBackendObject>(&fInfo); + } +#endif + protected: // constructor for subclasses GrMockRenderTarget(GrMockGpu* gpu, const GrSurfaceDesc& desc, @@ -149,6 +160,10 @@ public: this->registerWithCacheWrapped(); } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getRenderTargetHandle() const override { return 0; } +#endif + GrTexture* asTexture() override { return this; } GrRenderTarget* asRenderTarget() override { return this; } const GrTexture* asTexture() const override { return this; } diff --git a/src/gpu/mtl/GrMtlRenderTarget.h b/src/gpu/mtl/GrMtlRenderTarget.h index c0f0cf57e1..c653952482 100644 --- a/src/gpu/mtl/GrMtlRenderTarget.h +++ b/src/gpu/mtl/GrMtlRenderTarget.h @@ -40,6 +40,10 @@ public: return true; } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getRenderTargetHandle() const override; +#endif + GrBackendRenderTarget getBackendRenderTarget() const override { return GrBackendRenderTarget(); // invalid } diff --git a/src/gpu/mtl/GrMtlRenderTarget.mm b/src/gpu/mtl/GrMtlRenderTarget.mm index c102e6dcfc..c8060cf88c 100644 --- a/src/gpu/mtl/GrMtlRenderTarget.mm +++ b/src/gpu/mtl/GrMtlRenderTarget.mm @@ -63,6 +63,13 @@ GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const { return static_cast<GrMtlGpu*>(this->getGpu()); } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject GrMtlRenderTarget::getRenderTargetHandle() const { + void* voidRT = (__bridge_retained void*)fRenderTexture; + return (GrBackendObject)voidRT; +} +#endif + void GrMtlRenderTarget::onAbandon() { fRenderTexture = nil; fResolveTexture = nil; diff --git a/src/gpu/mtl/GrMtlTexture.h b/src/gpu/mtl/GrMtlTexture.h index f75083272a..21f5e13b19 100644 --- a/src/gpu/mtl/GrMtlTexture.h +++ b/src/gpu/mtl/GrMtlTexture.h @@ -26,6 +26,9 @@ public: id<MTLTexture> mtlTexture() const { return fTexture; } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getTextureHandle() const override; +#endif GrBackendTexture getBackendTexture() const override; void textureParamsModified() override {} diff --git a/src/gpu/mtl/GrMtlTexture.mm b/src/gpu/mtl/GrMtlTexture.mm index e029836b60..534eb6baf7 100644 --- a/src/gpu/mtl/GrMtlTexture.mm +++ b/src/gpu/mtl/GrMtlTexture.mm @@ -71,6 +71,13 @@ GrMtlGpu* GrMtlTexture::getMtlGpu() const { return static_cast<GrMtlGpu*>(this->getGpu()); } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject GrMtlTexture::getTextureHandle() const { + void* voidTex = (__bridge_retained void*)fTexture; + return (GrBackendObject)voidTex; +} +#endif + GrBackendTexture GrMtlTexture::getBackendTexture() const { return GrBackendTexture(); // invalid } diff --git a/src/gpu/vk/GrVkImage.h b/src/gpu/vk/GrVkImage.h index 038b0ee86d..9e99743fe7 100644 --- a/src/gpu/vk/GrVkImage.h +++ b/src/gpu/vk/GrVkImage.h @@ -30,6 +30,7 @@ public: , fLayout(std::move(layout)) , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) { SkASSERT(fLayout->getImageLayout() == fInfo.fImageLayout); + fTempLayoutTracker = fLayout->getImageLayout(); if (fIsBorrowed) { fResource = new BorrowedResource(info.fImage, info.fAlloc, info.fImageTiling); } else { @@ -51,6 +52,23 @@ public: sk_sp<GrVkImageLayout> grVkImageLayout() const { return fLayout; } VkImageLayout currentLayout() const { + // This check and set is temporary since clients can still change the layout using + // the old GrBackendObject call and we need a way to respect those changes. This only works + // if the client isn't using GrBackendObjects and GrBackendTextures to update the layout + // at the same time. This check and set should all be made atomic but the plan is to remove + // the use of fInfo.fImageLayout so ignoring this issue for now. + // TODO: Delete all this ugliness as soon as we get rid of GrBackendObject getters. + if (fInfo.fImageLayout != fLayout->getImageLayout()) { + if (fLayout->getImageLayout() == fTempLayoutTracker) { + fLayout->setImageLayout(fInfo.fImageLayout); + } else { + SkASSERT(fInfo.fImageLayout == fTempLayoutTracker); + *const_cast<VkImageLayout*>(&fInfo.fImageLayout) = fLayout->getImageLayout(); + } + *const_cast<VkImageLayout*>(&fTempLayoutTracker) = fLayout->getImageLayout(); + } + SkASSERT(fInfo.fImageLayout == fTempLayoutTracker && + fLayout->getImageLayout() == fTempLayoutTracker); return fLayout->getImageLayout(); } @@ -65,6 +83,8 @@ public: // blit each layer, and then at the end need to update our tracking. void updateImageLayout(VkImageLayout newLayout) { fLayout->setImageLayout(newLayout); + fInfo.fImageLayout = newLayout; + fTempLayoutTracker = newLayout; } struct ImageDesc { @@ -108,6 +128,11 @@ protected: GrVkImageInfo fInfo; sk_sp<GrVkImageLayout> fLayout; + // This is used while we still have GrBackendObjects around that are able to change our image + // layout without using the ref count method. This helps us determine which value has gotten out + // of sync. + // TODO: Delete this when get rid of a GrBackendObject getters + VkImageLayout fTempLayoutTracker; bool fIsBorrowed; private: diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp index 9ca8a98928..3cab94d7dc 100644 --- a/src/gpu/vk/GrVkRenderTarget.cpp +++ b/src/gpu/vk/GrVkRenderTarget.cpp @@ -352,6 +352,15 @@ void GrVkRenderTarget::onAbandon() { } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject GrVkRenderTarget::getRenderTargetHandle() const { + // If the render target is multisampled, we currently return the ImageInfo for the resolved + // image. If we only wrap the msaa target (currently not implemented) we should return a handle + // to that instead. + return (GrBackendObject)&fInfo; +} +#endif + GrBackendRenderTarget GrVkRenderTarget::getBackendRenderTarget() const { return GrBackendRenderTarget(this->width(), this->height(), this->numColorSamples(), fInfo, this->grVkImageLayout()); diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h index de2317ef06..ed840fc226 100644 --- a/src/gpu/vk/GrVkRenderTarget.h +++ b/src/gpu/vk/GrVkRenderTarget.h @@ -70,6 +70,10 @@ public: return true; } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getRenderTargetHandle() const override; +#endif + GrBackendRenderTarget getBackendRenderTarget() const override; void getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc, diff --git a/src/gpu/vk/GrVkTexture.cpp b/src/gpu/vk/GrVkTexture.cpp index 116b37eddd..c4393fdd36 100644 --- a/src/gpu/vk/GrVkTexture.cpp +++ b/src/gpu/vk/GrVkTexture.cpp @@ -161,6 +161,12 @@ void GrVkTexture::onAbandon() { INHERITED::onAbandon(); } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject GrVkTexture::getTextureHandle() const { + return (GrBackendObject)&fInfo; +} +#endif + GrBackendTexture GrVkTexture::getBackendTexture() const { return GrBackendTexture(this->width(), this->height(), fInfo, this->grVkImageLayout()); } diff --git a/src/gpu/vk/GrVkTexture.h b/src/gpu/vk/GrVkTexture.h index 55239e3903..79506eff9e 100644 --- a/src/gpu/vk/GrVkTexture.h +++ b/src/gpu/vk/GrVkTexture.h @@ -29,6 +29,9 @@ public: ~GrVkTexture() override; +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject getTextureHandle() const override; +#endif GrBackendTexture getBackendTexture() const override; void textureParamsModified() override {} diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 72285bd698..3be804fca8 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -163,6 +163,13 @@ GrTexture* SkImage::getTexture() const { bool SkImage::isTextureBacked() const { return SkToBool(as_IB(this)->peekProxy()); } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject SkImage::getTextureHandle(bool flushPendingGrContextIO, + GrSurfaceOrigin* origin) const { + return as_IB(this)->onGetTextureHandle(flushPendingGrContextIO, origin); +} +#endif + GrBackendTexture SkImage::getBackendTexture(bool flushPendingGrContextIO, GrSurfaceOrigin* origin) const { return as_IB(this)->onGetBackendTexture(flushPendingGrContextIO, origin); @@ -181,6 +188,10 @@ GrTexture* SkImage::getTexture() const { return nullptr; } bool SkImage::isTextureBacked() const { return false; } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject SkImage::getTextureHandle(bool, GrSurfaceOrigin*) const { return 0; } +#endif + GrBackendTexture SkImage::getBackendTexture(bool flushPendingGrContextIO, GrSurfaceOrigin* origin) const { return GrBackendTexture(); // invalid diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h index 9cf70fb1d3..c74a7b97e0 100644 --- a/src/image/SkImage_Base.h +++ b/src/image/SkImage_Base.h @@ -55,6 +55,12 @@ public: virtual sk_sp<GrTextureProxy> refPinnedTextureProxy(uint32_t* uniqueID) const { return nullptr; } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + virtual GrBackendObject onGetTextureHandle(bool flushPendingGrContextIO, + GrSurfaceOrigin* origin) const { + return 0; + } +#endif virtual GrTexture* onGetTexture() const { return nullptr; } #endif diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 08c9010228..17a0a25f5a 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -162,6 +162,46 @@ static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) } } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject SkImage_Gpu::onGetTextureHandle(bool flushPendingGrContextIO, + GrSurfaceOrigin* origin) const { + SkASSERT(fProxy); + + if (!fContext->contextPriv().resourceProvider() && !fProxy->priv().isInstantiated()) { + // This image was created with a DDL context and cannot be instantiated. Thus we return 0 + // here which is considered invalid for all backends. + return 0; + } + + if (GrSurfaceProxy::LazyState::kNot != fProxy->lazyInstantiationState()) { + SkASSERT(fContext->contextPriv().resourceProvider()); + fProxy->priv().doLazyInstantiation(fContext->contextPriv().resourceProvider()); + if (!fProxy->priv().isInstantiated()) { + // We failed to instantiate the lazy proxy. Thus we return 0 here which is considered + // invalid for all backends. + return 0; + } + } + + if (!fProxy->instantiate(fContext->contextPriv().resourceProvider())) { + return 0; + } + + GrTexture* texture = fProxy->priv().peekTexture(); + + if (texture) { + if (flushPendingGrContextIO) { + fContext->contextPriv().prepareSurfaceForExternalIO(fProxy.get()); + } + if (origin) { + *origin = fProxy->origin(); + } + return texture->getTextureHandle(); + } + return 0; +} +#endif + GrBackendTexture SkImage_Gpu::onGetBackendTexture(bool flushPendingGrContextIO, GrSurfaceOrigin* origin) const { SkASSERT(fProxy); diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h index cb9a7c7a9f..1425c875ce 100644 --- a/src/image/SkImage_Gpu.h +++ b/src/image/SkImage_Gpu.h @@ -50,6 +50,10 @@ public: return fProxy; } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject onGetTextureHandle(bool flushPendingGrContextIO, + GrSurfaceOrigin* origin) const override; +#endif GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO, GrSurfaceOrigin* origin) const override; diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp index 1a3eb4312e..73f3175ab9 100644 --- a/src/image/SkSurface.cpp +++ b/src/image/SkSurface.cpp @@ -218,6 +218,16 @@ void SkSurface::writePixels(const SkBitmap& src, int x, int y) { } } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject SkSurface::getTextureHandle(BackendHandleAccess access) { + return asSB(this)->onGetTextureHandle(access); +} + +bool SkSurface::getRenderTargetHandle(GrBackendObject* obj, BackendHandleAccess access) { + return asSB(this)->onGetRenderTargetHandle(obj, access); +} +#endif + GrBackendTexture SkSurface::getBackendTexture(BackendHandleAccess access) { return asSB(this)->onGetBackendTexture(access); } diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h index 67d330f9bb..90bcdff1dd 100644 --- a/src/image/SkSurface_Base.h +++ b/src/image/SkSurface_Base.h @@ -19,6 +19,16 @@ public: SkSurface_Base(const SkImageInfo&, const SkSurfaceProps*); virtual ~SkSurface_Base(); +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + virtual GrBackendObject onGetTextureHandle(BackendHandleAccess) { + return 0; + } + + virtual bool onGetRenderTargetHandle(GrBackendObject*, BackendHandleAccess) { + return false; + } +#endif + virtual GrBackendTexture onGetBackendTexture(BackendHandleAccess); virtual GrBackendRenderTarget onGetBackendRenderTarget(BackendHandleAccess); diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index d86b316ef6..c81fc28417 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -52,6 +52,29 @@ static GrRenderTarget* prepare_rt_for_external_access(SkSurface_Gpu* surface, return rtc->accessRenderTarget(); } +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS +GrBackendObject SkSurface_Gpu::onGetTextureHandle(BackendHandleAccess access) { + GrRenderTarget* rt = prepare_rt_for_external_access(this, access); + if (!rt) { + return 0; + } + GrTexture* texture = rt->asTexture(); + if (texture) { + return texture->getTextureHandle(); + } + return 0; +} + +bool SkSurface_Gpu::onGetRenderTargetHandle(GrBackendObject* obj, BackendHandleAccess access) { + GrRenderTarget* rt = prepare_rt_for_external_access(this, access); + if (!rt) { + return false; + } + *obj = rt->getRenderTargetHandle(); + return true; +} +#endif + GrBackendTexture SkSurface_Gpu::onGetBackendTexture(BackendHandleAccess access) { GrRenderTarget* rt = prepare_rt_for_external_access(this, access); if (!rt) { diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h index 97fe5e5d5a..fc014c2cd2 100644 --- a/src/image/SkSurface_Gpu.h +++ b/src/image/SkSurface_Gpu.h @@ -23,6 +23,11 @@ public: // This is an internal-only factory static sk_sp<SkSurface> MakeWrappedRenderTarget(GrContext*, sk_sp<GrRenderTargetContext>); +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + GrBackendObject onGetTextureHandle(BackendHandleAccess) override; + bool onGetRenderTargetHandle(GrBackendObject*, BackendHandleAccess) override; +#endif + GrBackendTexture onGetBackendTexture(BackendHandleAccess) override; GrBackendRenderTarget onGetBackendRenderTarget(BackendHandleAccess) override; diff --git a/tests/VkBackendSurfaceTest.cpp b/tests/VkBackendSurfaceTest.cpp index 3b3a9cec14..6b442a9725 100644 --- a/tests/VkBackendSurfaceTest.cpp +++ b/tests/VkBackendSurfaceTest.cpp @@ -84,6 +84,19 @@ DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkImageLayoutTest, reporter, ctxInfo) { backendTexImage.setVkImageLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == vkTexture->currentLayout()); +#ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS + // Verify that modifying the layout via the old textureHandle sitll works in is reflected in the + // GrVkTexture and GrBackendTexture. + GrVkImageInfo* backendInfo = (GrVkImageInfo*)wrappedImage->getTextureHandle(false); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == backendInfo->fImageLayout); + + backendInfo->updateImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + REPORTER_ASSERT(reporter, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == vkTexture->currentLayout()); + REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); + REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == info.fImageLayout); +#endif + vkTexture->updateImageLayout(initLayout); REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); |