Add wrapBackendTextureAsRenderTarget API
Skia's GrTextureProvider currently exposes two APIs for wrapping backend objects: * wrapBackendTexture - wraps a texture into a GrTexture. Depending on flags, this GrTexture can be converted to a GrRenderTarget. Skia manages the render target objects it may create to provide a render target for the texture. This allows Skia to create stencil buffers if needed and manager MSAA resolves. * wrapBackendRenderTarget - wraps a FBO into a GrRenderTarget. This object cannot be converted to a GrTexture. Skia does not manage the render target objects for such a GrRenderTarget, and as such cannot attach stencil buffers or perform MSAA resolves on the created GrRenderTarget. Given these two options, wrapBackendTexture provides more versatility and allows Skia more room for optimization. Chrome currently uses wrapBackendTexture for this reason. While these two functions cover most cases, they do not provide a way for Skia to wrap a texture into a render target (and gain the MSAA and stencil buffer management), without also creating a GrTexture. This is problematic in cases where a texture can be bound to a render target, but cannot be textured from, as is the case in Chrome's limited support for GL_TEXTURE_RECTANGLE. To address this, a new function is created: * wrapBackendTextureAsRenderTarget - wraps a texture into a GrRenderTarget. As with wrapBackendTexture, the created render target objects are fully managed by Skia. Unlike wrapBackendTexture no GrTexture is created, and the created object will never be textured from. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1709163003 Review URL: https://codereview.chromium.org/1709163003
This commit is contained in:
parent
0cc2f85a19
commit
f7b8b8affe
@ -108,7 +108,6 @@ public:
|
|||||||
return NewFromBackendTexture(ctx, desc, props);
|
return NewFromBackendTexture(ctx, desc, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to wrap a pre-existing 3D API rendering target as a SkSurface. Skia will not assume
|
* Used to wrap a pre-existing 3D API rendering target as a SkSurface. Skia will not assume
|
||||||
* ownership of the render target and the client must ensure the render target is valid for the
|
* ownership of the render target and the client must ensure the render target is valid for the
|
||||||
@ -117,6 +116,17 @@ public:
|
|||||||
static SkSurface* NewFromBackendRenderTarget(GrContext*, const GrBackendRenderTargetDesc&,
|
static SkSurface* NewFromBackendRenderTarget(GrContext*, const GrBackendRenderTargetDesc&,
|
||||||
const SkSurfaceProps*);
|
const SkSurfaceProps*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to wrap a pre-existing 3D API texture as a SkSurface. Skia will treat the texture as
|
||||||
|
* a rendering target only, but unlike NewFromBackendRenderTarget, Skia will manage and own
|
||||||
|
* the associated render target objects (but not the provided texture). The kRenderTarget flag
|
||||||
|
* must be set on GrBackendTextureDesc for this to succeed. Skia will not assume ownership
|
||||||
|
* of the texture and the client must ensure the texture is valid for the lifetime of the
|
||||||
|
* SkSurface.
|
||||||
|
*/
|
||||||
|
static SkSurface* NewFromBackendTextureAsRenderTarget(
|
||||||
|
GrContext*, const GrBackendTextureDesc&, const SkSurfaceProps*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new surface whose contents will be drawn to an offscreen
|
* Return a new surface whose contents will be drawn to an offscreen
|
||||||
* render target, allocated by the surface.
|
* render target, allocated by the surface.
|
||||||
@ -292,6 +302,11 @@ public:
|
|||||||
|
|
||||||
const SkSurfaceProps& props() const { return fProps; }
|
const SkSurfaceProps& props() const { return fProps; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issue any pending surface IO to the current backend 3D API and resolve any surface MSAA.
|
||||||
|
*/
|
||||||
|
void prepareForExternalIO();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkSurface(int width, int height, const SkSurfaceProps*);
|
SkSurface(int width, int height, const SkSurfaceProps*);
|
||||||
SkSurface(const SkImageInfo&, const SkSurfaceProps*);
|
SkSurface(const SkImageInfo&, const SkSurfaceProps*);
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
* the client will resolve to a texture). Currently wrapped render targets
|
* the client will resolve to a texture). Currently wrapped render targets
|
||||||
* always use the kBorrow_GrWrapOwnership semantics.
|
* always use the kBorrow_GrWrapOwnership semantics.
|
||||||
*
|
*
|
||||||
* @return GrTexture object or NULL on failure.
|
* @return GrRenderTarget object or NULL on failure.
|
||||||
*/
|
*/
|
||||||
GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
|
GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
|
||||||
|
|
||||||
|
@ -166,6 +166,10 @@ GrTexture* GrGpu::wrapBackendTexture(const GrBackendTextureDesc& desc, GrWrapOwn
|
|||||||
!this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
|
!this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
int maxSize = this->caps()->maxTextureSize();
|
||||||
|
if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
GrTexture* tex = this->onWrapBackendTexture(desc, ownership);
|
GrTexture* tex = this->onWrapBackendTexture(desc, ownership);
|
||||||
if (nullptr == tex) {
|
if (nullptr == tex) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -189,6 +193,22 @@ GrRenderTarget* GrGpu::wrapBackendRenderTarget(const GrBackendRenderTargetDesc&
|
|||||||
return this->onWrapBackendRenderTarget(desc, ownership);
|
return this->onWrapBackendRenderTarget(desc, ownership);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrRenderTarget* GrGpu::wrapBackendTextureAsRenderTarget(const GrBackendTextureDesc& desc,
|
||||||
|
GrWrapOwnership ownership) {
|
||||||
|
this->handleDirtyContext();
|
||||||
|
if (!(desc.fFlags & kRenderTarget_GrBackendTextureFlag)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (!this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
int maxSize = this->caps()->maxTextureSize();
|
||||||
|
if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return this->onWrapBackendTextureAsRenderTarget(desc, ownership);
|
||||||
|
}
|
||||||
|
|
||||||
GrVertexBuffer* GrGpu::createVertexBuffer(size_t size, bool dynamic) {
|
GrVertexBuffer* GrGpu::createVertexBuffer(size_t size, bool dynamic) {
|
||||||
this->handleDirtyContext();
|
this->handleDirtyContext();
|
||||||
GrVertexBuffer* vb = this->onCreateVertexBuffer(size, dynamic);
|
GrVertexBuffer* vb = this->onCreateVertexBuffer(size, dynamic);
|
||||||
|
@ -97,15 +97,20 @@ public:
|
|||||||
const void* srcData, size_t rowBytes);
|
const void* srcData, size_t rowBytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements GrContext::wrapBackendTexture
|
* Implements GrTextureProvider::wrapBackendTexture
|
||||||
*/
|
*/
|
||||||
GrTexture* wrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership);
|
GrTexture* wrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements GrContext::wrapBackendTexture
|
* Implements GrTextureProvider::wrapBackendTexture
|
||||||
*/
|
*/
|
||||||
GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc&, GrWrapOwnership);
|
GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc&, GrWrapOwnership);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements GrTextureProvider::wrapBackendTextureAsRenderTarget
|
||||||
|
*/
|
||||||
|
GrRenderTarget* wrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&, GrWrapOwnership);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a vertex buffer.
|
* Creates a vertex buffer.
|
||||||
*
|
*
|
||||||
@ -512,6 +517,8 @@ private:
|
|||||||
virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) = 0;
|
virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) = 0;
|
||||||
virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
|
virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
|
||||||
GrWrapOwnership) = 0;
|
GrWrapOwnership) = 0;
|
||||||
|
virtual GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&,
|
||||||
|
GrWrapOwnership) = 0;
|
||||||
virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0;
|
virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0;
|
||||||
virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0;
|
virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0;
|
||||||
virtual GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) = 0;
|
virtual GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) = 0;
|
||||||
|
@ -227,4 +227,11 @@ GrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget*
|
|||||||
return rt->renderTargetPriv().getStencilAttachment();
|
return rt->renderTargetPriv().getStencilAttachment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrRenderTarget* GrResourceProvider::wrapBackendTextureAsRenderTarget(
|
||||||
|
const GrBackendTextureDesc& desc, GrWrapOwnership ownership) {
|
||||||
|
if (this->isAbandoned()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return this->gpu()->wrapBackendTextureAsRenderTarget(desc, ownership);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -147,6 +147,15 @@ public:
|
|||||||
|
|
||||||
const GrCaps* caps() { return this->gpu()->caps(); }
|
const GrCaps* caps() { return this->gpu()->caps(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps an existing texture with a GrRenderTarget object. This is useful when the provided
|
||||||
|
* texture has a format that cannot be textured from by Skia, but we want to raster to it.
|
||||||
|
*
|
||||||
|
* @return GrRenderTarget object or NULL on failure.
|
||||||
|
*/
|
||||||
|
GrRenderTarget* wrapBackendTextureAsRenderTarget(const GrBackendTextureDesc& desc,
|
||||||
|
GrWrapOwnership = kBorrow_GrWrapOwnership);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const GrIndexBuffer* createInstancedIndexBuffer(const uint16_t* pattern,
|
const GrIndexBuffer* createInstancedIndexBuffer(const uint16_t* pattern,
|
||||||
int patternSize,
|
int patternSize,
|
||||||
|
@ -345,6 +345,11 @@ private:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&,
|
||||||
|
GrWrapOwnership) override {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override { return nullptr; }
|
GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override { return nullptr; }
|
||||||
|
|
||||||
GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override { return nullptr; }
|
GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override { return nullptr; }
|
||||||
|
@ -547,11 +547,6 @@ GrTexture* GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int maxSize = this->caps()->maxTextureSize();
|
|
||||||
if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// next line relies on GrBackendTextureDesc's flags matching GrTexture's
|
// next line relies on GrBackendTextureDesc's flags matching GrTexture's
|
||||||
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
|
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
|
||||||
|
|
||||||
@ -657,7 +652,72 @@ GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
|
|||||||
return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencilBits);
|
return GrGLRenderTarget::CreateWrapped(this, desc, idDesc, wrapDesc.fStencilBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrRenderTarget* GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc& desc,
|
||||||
|
GrWrapOwnership ownership) {
|
||||||
|
#ifdef SK_IGNORE_GL_TEXTURE_TARGET
|
||||||
|
if (!desc.fTextureHandle) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const GrGLTextureInfo* info = reinterpret_cast<const GrGLTextureInfo*>(desc.fTextureHandle);
|
||||||
|
if (!info || !info->fID) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GrGLTexture::IDDesc idDesc;
|
||||||
|
GrSurfaceDesc surfDesc;
|
||||||
|
|
||||||
|
#ifdef SK_IGNORE_GL_TEXTURE_TARGET
|
||||||
|
idDesc.fInfo.fID = static_cast<GrGLuint>(desc.fTextureHandle);
|
||||||
|
// We only support GL_TEXTURE_2D at the moment.
|
||||||
|
idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D;
|
||||||
|
#else
|
||||||
|
idDesc.fInfo = *info;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (GR_GL_TEXTURE_RECTANGLE != idDesc.fInfo.fTarget &&
|
||||||
|
GR_GL_TEXTURE_2D != idDesc.fInfo.fTarget) {
|
||||||
|
// Only texture rectangle and texture 2d are supported. We do not check whether texture
|
||||||
|
// rectangle is supported by Skia - if the caller provided us with a texture rectangle,
|
||||||
|
// we assume the necessary support exists.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ownership) {
|
||||||
|
case kAdopt_GrWrapOwnership:
|
||||||
|
idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
|
||||||
|
break;
|
||||||
|
case kBorrow_GrWrapOwnership:
|
||||||
|
idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags;
|
||||||
|
surfDesc.fWidth = desc.fWidth;
|
||||||
|
surfDesc.fHeight = desc.fHeight;
|
||||||
|
surfDesc.fConfig = desc.fConfig;
|
||||||
|
surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount());
|
||||||
|
// FIXME: this should be calling resolve_origin(), but Chrome code is currently
|
||||||
|
// assuming the old behaviour, which is that backend textures are always
|
||||||
|
// BottomLeft, even for non-RT's. Once Chrome is fixed, change this to:
|
||||||
|
// glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
|
||||||
|
if (kDefault_GrSurfaceOrigin == desc.fOrigin) {
|
||||||
|
surfDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
||||||
|
} else {
|
||||||
|
surfDesc.fOrigin = desc.fOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrGLRenderTarget::IDDesc rtIDDesc;
|
||||||
|
if (!this->createRenderTargetObjects(surfDesc, GrGpuResource::kUncached_LifeCycle,
|
||||||
|
idDesc.fInfo, &rtIDDesc)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return GrGLRenderTarget::CreateWrapped(this, surfDesc, rtIDDesc, 0);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
|
bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height,
|
||||||
GrPixelConfig srcConfig,
|
GrPixelConfig srcConfig,
|
||||||
DrawPreference* drawPreference,
|
DrawPreference* drawPreference,
|
||||||
@ -1534,9 +1594,6 @@ bool GrGLGpu::createTextureExternalAllocatorImpl(
|
|||||||
GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||||
int width,
|
int width,
|
||||||
int height) {
|
int height) {
|
||||||
// All internally created RTs are also textures. We don't create
|
|
||||||
// SBs for a client's standalone RT (that is a RT that isn't also a texture).
|
|
||||||
SkASSERT(rt->asTexture());
|
|
||||||
SkASSERT(width >= rt->width());
|
SkASSERT(width >= rt->width());
|
||||||
SkASSERT(height >= rt->height());
|
SkASSERT(height >= rt->height());
|
||||||
|
|
||||||
|
@ -155,6 +155,8 @@ private:
|
|||||||
GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
|
GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
|
||||||
GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
|
GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
|
||||||
GrWrapOwnership) override;
|
GrWrapOwnership) override;
|
||||||
|
GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&,
|
||||||
|
GrWrapOwnership) override;
|
||||||
// Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a
|
// Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a
|
||||||
// compatible stencil format, or negative if there is no compatible stencil format.
|
// compatible stencil format, or negative if there is no compatible stencil format.
|
||||||
int getCompatibleStencilIndex(GrPixelConfig config);
|
int getCompatibleStencilIndex(GrPixelConfig config);
|
||||||
|
@ -199,6 +199,10 @@ bool SkSurface::getRenderTargetHandle(GrBackendObject* obj, BackendHandleAccess
|
|||||||
return asSB(this)->onGetRenderTargetHandle(obj, access);
|
return asSB(this)->onGetRenderTargetHandle(obj, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkSurface::prepareForExternalIO() {
|
||||||
|
asSB(this)->onPrepareForExternalIO();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if !SK_SUPPORT_GPU
|
#if !SK_SUPPORT_GPU
|
||||||
@ -222,4 +226,9 @@ SkSurface* SkSurface::NewFromBackendRenderTarget(GrContext*, const GrBackendRend
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkSurface* NewFromBackendTextureAsRenderTarget(GrContext*, const GrBackendTextureDesc&,
|
||||||
|
const SkSurfaceProps*) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,6 +75,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void onRestoreBackingMutability() {}
|
virtual void onRestoreBackingMutability() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issue any pending surface IO to the current backend 3D API and resolve any surface MSAA.
|
||||||
|
*/
|
||||||
|
virtual void onPrepareForExternalIO() {}
|
||||||
|
|
||||||
inline SkCanvas* getCachedCanvas();
|
inline SkCanvas* getCachedCanvas();
|
||||||
inline SkImage* refCachedImage(Budgeted, ForceUnique);
|
inline SkImage* refCachedImage(Budgeted, ForceUnique);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "SkSurface_Gpu.h"
|
#include "SkSurface_Gpu.h"
|
||||||
|
|
||||||
|
#include "GrResourceProvider.h"
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkGpuDevice.h"
|
#include "SkGpuDevice.h"
|
||||||
#include "SkImage_Base.h"
|
#include "SkImage_Base.h"
|
||||||
@ -125,6 +126,10 @@ void SkSurface_Gpu::onDiscard() {
|
|||||||
fDevice->accessRenderTarget()->discard();
|
fDevice->accessRenderTarget()->discard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkSurface_Gpu::onPrepareForExternalIO() {
|
||||||
|
fDevice->accessRenderTarget()->prepareForExternalIO();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
|
SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) {
|
||||||
@ -187,4 +192,23 @@ SkSurface* SkSurface::NewFromBackendRenderTarget(GrContext* context,
|
|||||||
return new SkSurface_Gpu(device);
|
return new SkSurface_Gpu(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkSurface* SkSurface::NewFromBackendTextureAsRenderTarget(GrContext* context,
|
||||||
|
const GrBackendTextureDesc& desc,
|
||||||
|
const SkSurfaceProps* props) {
|
||||||
|
if (nullptr == context) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
SkAutoTUnref<GrRenderTarget> rt(
|
||||||
|
context->resourceProvider()->wrapBackendTextureAsRenderTarget(desc));
|
||||||
|
if (!rt) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(rt, props,
|
||||||
|
SkGpuDevice::kUninit_InitContents));
|
||||||
|
if (!device) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return new SkSurface_Gpu(device);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,7 @@ public:
|
|||||||
SkImage* onNewImageSnapshot(Budgeted, ForceCopyMode) override;
|
SkImage* onNewImageSnapshot(Budgeted, ForceCopyMode) override;
|
||||||
void onCopyOnWrite(ContentChangeMode) override;
|
void onCopyOnWrite(ContentChangeMode) override;
|
||||||
void onDiscard() override;
|
void onDiscard() override;
|
||||||
|
void onPrepareForExternalIO() override;
|
||||||
|
|
||||||
SkGpuDevice* getDevice() { return fDevice; }
|
SkGpuDevice* getDevice() { return fDevice; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user