Implement support for framebufferOnly render targets.
This reflects Dawn and Metal functionality. Implement a FramebufferOnly flag on GrSurface and GrBackendRenderTarget. Forward the state from GrBackendRenderTarget to GrSurface. Check the GrSurface flag in GrGpu::readPixels() and GrGpu::writePixels() and early-return. Change-Id: I27d3c9c912b366791bfd0e1db49638d8925742f3 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/262802 Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
4cb293392c
commit
3c0a50f038
@ -49,6 +49,7 @@ public:
|
||||
GrBackendRenderTarget() {}
|
||||
|
||||
bool isValid() const { return false; }
|
||||
bool isFramebufferOnly() const { return false; }
|
||||
};
|
||||
#else
|
||||
|
||||
@ -371,6 +372,7 @@ public:
|
||||
int sampleCnt() const { return fSampleCnt; }
|
||||
int stencilBits() const { return fStencilBits; }
|
||||
GrBackendApi backend() const {return fBackend; }
|
||||
bool isFramebufferOnly() const { return fFramebufferOnly; }
|
||||
|
||||
// If the backend API is GL, copies a snapshot of the GrGLFramebufferInfo struct into the passed
|
||||
// in pointer and returns true. Otherwise returns false if the backend API is not GL.
|
||||
@ -427,6 +429,7 @@ private:
|
||||
void cleanup();
|
||||
|
||||
bool fIsValid;
|
||||
bool fFramebufferOnly = false;
|
||||
int fWidth; //<! width in pixels
|
||||
int fHeight; //<! height in pixels
|
||||
|
||||
|
@ -81,9 +81,18 @@ public:
|
||||
*/
|
||||
bool readOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kReadOnly; }
|
||||
|
||||
bool framebufferOnly() const {
|
||||
return fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly;
|
||||
}
|
||||
|
||||
// Returns true if we are working with protected content.
|
||||
bool isProtected() const { return fIsProtected == GrProtected::kYes; }
|
||||
|
||||
void setFramebufferOnly() {
|
||||
SkASSERT(this->asRenderTarget());
|
||||
fSurfaceFlags |= GrInternalSurfaceFlags::kFramebufferOnly;
|
||||
}
|
||||
|
||||
protected:
|
||||
void setGLRTFBOIDIs0() {
|
||||
SkASSERT(!this->requiresManualMSAAResolve());
|
||||
|
@ -701,6 +701,10 @@ enum class GrInternalSurfaceFlags {
|
||||
// (asTexture() might or might not return the internal texture, but if it does, we always
|
||||
// resolve the render target before accessing this texture's data.)
|
||||
kRequiresManualMSAAResolve = 1 << 2,
|
||||
|
||||
// This means the pixels in the render target are write-only. This is used for Dawn and Metal
|
||||
// swap chain targets which can be rendered to, but not read or copied.
|
||||
kFramebufferOnly = 1 << 3,
|
||||
};
|
||||
|
||||
GR_MAKE_BITFIELD_CLASS_OPS(GrInternalSurfaceFlags)
|
||||
|
@ -665,6 +665,7 @@ GrBackendRenderTarget::GrBackendRenderTarget(int width,
|
||||
int stencilBits,
|
||||
const GrDawnImageInfo& dawnInfo)
|
||||
: fIsValid(true)
|
||||
, fFramebufferOnly(true)
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fSampleCnt(sampleCnt)
|
||||
@ -715,6 +716,7 @@ GrBackendRenderTarget::GrBackendRenderTarget(int width,
|
||||
int sampleCnt,
|
||||
const GrMtlTextureInfo& mtlInfo)
|
||||
: fIsValid(true)
|
||||
, fFramebufferOnly(false) // TODO: set this from mtlInfo.fTexture->framebufferOnly
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fSampleCnt(SkTMax(1, sampleCnt))
|
||||
|
@ -380,7 +380,11 @@ sk_sp<GrRenderTarget> GrGpu::wrapBackendRenderTarget(const GrBackendRenderTarget
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return this->onWrapBackendRenderTarget(backendRT, colorType);
|
||||
sk_sp<GrRenderTarget> rt = this->onWrapBackendRenderTarget(backendRT, colorType);
|
||||
if (backendRT.isFramebufferOnly()) {
|
||||
rt->setFramebufferOnly();
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
sk_sp<GrRenderTarget> GrGpu::wrapBackendTextureAsRenderTarget(const GrBackendTexture& backendTex,
|
||||
@ -432,6 +436,7 @@ bool GrGpu::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint) {
|
||||
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
|
||||
SkASSERT(dst && src);
|
||||
SkASSERT(!src->framebufferOnly());
|
||||
|
||||
if (dst->readOnly()) {
|
||||
return false;
|
||||
@ -447,6 +452,7 @@ bool GrGpu::readPixels(GrSurface* surface, int left, int top, int width, int hei
|
||||
size_t rowBytes) {
|
||||
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
|
||||
SkASSERT(surface);
|
||||
SkASSERT(!surface->framebufferOnly());
|
||||
SkASSERT(this->caps()->isFormatTexturable(surface->backendFormat()));
|
||||
|
||||
auto subRect = SkIRect::MakeXYWH(left, top, width, height);
|
||||
@ -480,6 +486,7 @@ bool GrGpu::writePixels(GrSurface* surface, int left, int top, int width, int he
|
||||
const GrMipLevel texels[], int mipLevelCount, bool prepForTexSampling) {
|
||||
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
|
||||
SkASSERT(surface);
|
||||
SkASSERT(!surface->framebufferOnly());
|
||||
SkASSERT(this->caps()->isFormatTexturableAndUploadable(surfaceColorType,
|
||||
surface->backendFormat()));
|
||||
|
||||
|
@ -1688,6 +1688,10 @@ void GrRenderTargetContext::asyncRescaleAndReadPixels(
|
||||
callback(context, nullptr);
|
||||
return;
|
||||
}
|
||||
if (this->asRenderTargetProxy()->framebufferOnly()) {
|
||||
callback(context, nullptr);
|
||||
return;
|
||||
}
|
||||
auto dstCT = SkColorTypeToGrColorType(info.colorType());
|
||||
if (dstCT == GrColorType::kUnknown) {
|
||||
callback(context, nullptr);
|
||||
@ -1933,6 +1937,10 @@ void GrRenderTargetContext::asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvC
|
||||
callback(context, nullptr);
|
||||
return;
|
||||
}
|
||||
if (this->asRenderTargetProxy()->framebufferOnly()) {
|
||||
callback(context, nullptr);
|
||||
return;
|
||||
}
|
||||
if (this->asSurfaceProxy()->isProtected() == GrProtected::kYes) {
|
||||
callback(context, nullptr);
|
||||
return;
|
||||
|
@ -157,6 +157,10 @@ bool GrSurfaceContext::readPixels(const GrImageInfo& origDstInfo, void* dst, siz
|
||||
|
||||
GrSurfaceProxy* srcProxy = this->asSurfaceProxy();
|
||||
|
||||
if (srcProxy->framebufferOnly()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// MDB TODO: delay this instantiation until later in the method
|
||||
if (!srcProxy->instantiate(direct->priv().resourceProvider())) {
|
||||
return false;
|
||||
@ -315,6 +319,11 @@ bool GrSurfaceContext::writePixels(const GrImageInfo& origSrcInfo, const void* s
|
||||
}
|
||||
|
||||
GrSurfaceProxy* dstProxy = this->asSurfaceProxy();
|
||||
|
||||
if (dstProxy->framebufferOnly()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dstProxy->instantiate(direct->priv().resourceProvider())) {
|
||||
return false;
|
||||
}
|
||||
@ -484,6 +493,10 @@ bool GrSurfaceContext::copy(GrSurfaceProxy* src, const SkIRect& srcRect, const S
|
||||
SkASSERT(src->textureSwizzle() == this->asSurfaceProxy()->textureSwizzle());
|
||||
SkASSERT(src->backendFormat() == this->asSurfaceProxy()->backendFormat());
|
||||
|
||||
if (this->asSurfaceProxy()->framebufferOnly()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!caps->canCopySurface(this->asSurfaceProxy(), src, srcRect, dstPoint)) {
|
||||
return false;
|
||||
}
|
||||
@ -508,6 +521,10 @@ std::unique_ptr<GrRenderTargetContext> GrSurfaceContext::rescale(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (this->asSurfaceProxy()->framebufferOnly()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We rescale by drawing and don't currently support drawing to a kUnpremul destination.
|
||||
if (info.alphaType() == kUnpremul_SkAlphaType) {
|
||||
return nullptr;
|
||||
|
@ -245,6 +245,9 @@ public:
|
||||
* assignment in GrResourceAllocator.
|
||||
*/
|
||||
bool readOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kReadOnly; }
|
||||
bool framebufferOnly() const {
|
||||
return fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* This means surface is a multisampled render target, and internally holds a non-msaa texture
|
||||
|
@ -32,7 +32,9 @@ GrTextureProxy::GrTextureProxy(const GrBackendFormat& format,
|
||||
, fMipMapped(mipMapped)
|
||||
, fMipMapsStatus(mipMapsStatus) SkDEBUGCODE(, fInitialMipMapsStatus(fMipMapsStatus))
|
||||
, fProxyProvider(nullptr)
|
||||
, fDeferredUploader(nullptr) {}
|
||||
, fDeferredUploader(nullptr) {
|
||||
SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly));
|
||||
}
|
||||
|
||||
// Lazy-callback version
|
||||
GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback,
|
||||
@ -52,7 +54,9 @@ GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback,
|
||||
, fMipMapped(mipMapped)
|
||||
, fMipMapsStatus(mipMapsStatus) SkDEBUGCODE(, fInitialMipMapsStatus(fMipMapsStatus))
|
||||
, fProxyProvider(nullptr)
|
||||
, fDeferredUploader(nullptr) {}
|
||||
, fDeferredUploader(nullptr) {
|
||||
SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly));
|
||||
}
|
||||
|
||||
// Wrapped version
|
||||
GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf,
|
||||
|
Loading…
Reference in New Issue
Block a user