Fix GrGLGpu::createTestingOnlyBackendRenderTarget()

The format field wasn't being set.

Make GrContext_colorTypeSupportedAsSurface test that surfaces can be
created from GrBackendRenderTargets.

Change-Id: Ib5ae4671faa3f44102c6436593c7a987a05b3b88
Reviewed-on: https://skia-review.googlesource.com/150134
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Brian Salomon 2018-08-29 12:56:23 -04:00 committed by Skia Commit-Bot
parent 9f85b5116e
commit 93348dddac
4 changed files with 88 additions and 29 deletions

View File

@ -1185,9 +1185,12 @@ bool GrGLCaps::getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig ex
return true;
}
bool GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
void GrGLCaps::getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
*internalFormat = fConfigTable[config].fFormats.fInternalFormatRenderbuffer;
return true;
}
void GrGLCaps::getSizedInternalFormat(GrPixelConfig config, GrGLenum* internalFormat) const {
*internalFormat = fConfigTable[config].fFormats.fSizedInternalFormat;
}
bool GrGLCaps::getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,

View File

@ -149,7 +149,8 @@ public:
bool getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
GrGLenum* externalFormat, GrGLenum* externalType) const;
bool getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const;
void getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const;
void getSizedInternalFormat(GrPixelConfig config, GrGLenum* internalFormat) const;
/** The format to use read/write a texture as an image in a shader */
GrGLenum getImageFormat(GrPixelConfig config) const {

View File

@ -1177,9 +1177,7 @@ bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
!idDesc->fMSColorRenderbufferID) {
goto FAILED;
}
if (!this->glCaps().getRenderbufferFormat(desc.fConfig, &colorRenderbufferFormat)) {
return false;
}
this->glCaps().getRenderbufferFormat(desc.fConfig, &colorRenderbufferFormat);
} else {
idDesc->fRTFBOID = idDesc->fTexFBOID;
}
@ -4009,57 +4007,93 @@ GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(int w, int h
}
this->handleDirtyContext();
auto config = GrColorTypeToPixelConfig(colorType, GrSRGBEncoded::kNo);
GrGLenum colorBufferFormat;
if (!this->glCaps().getRenderbufferFormat(config, &colorBufferFormat)) {
if (!this->glCaps().isConfigRenderable(config)) {
return {};
}
bool useTexture = false;
GrGLenum colorBufferFormat;
GrGLenum externalFormat = 0, externalType = 0;
if (config == kBGRA_8888_GrPixelConfig && this->glCaps().bgraIsInternalFormat()) {
// BGRA render buffers are not supported.
this->glCaps().getTexImageFormats(config, config, &colorBufferFormat, &externalFormat,
&externalType);
useTexture = true;
} else {
this->glCaps().getRenderbufferFormat(config, &colorBufferFormat);
}
int sFormatIdx = this->getCompatibleStencilIndex(config);
if (sFormatIdx < 0) {
return {};
}
GrGLuint rbIDs[] = {0, 0};
GL_CALL(GenRenderbuffers(2, rbIDs));
if (!rbIDs[0] || !rbIDs[1]) {
if (!rbIDs[0]) {
GL_CALL(DeleteRenderbuffers(1, &rbIDs[0]));
GrGLuint colorID = 0;
GrGLuint stencilID = 0;
auto deleteIDs = [&] {
if (colorID) {
if (useTexture) {
GL_CALL(DeleteTextures(1, &colorID));
} else {
GL_CALL(DeleteRenderbuffers(1, &colorID));
}
}
if (!rbIDs[1]) {
GL_CALL(DeleteRenderbuffers(1, &rbIDs[1]));
if (stencilID) {
GL_CALL(DeleteRenderbuffers(1, &stencilID));
}
};
if (useTexture) {
GL_CALL(GenTextures(1, &colorID));
} else {
GL_CALL(GenRenderbuffers(1, &colorID));
}
GL_CALL(GenRenderbuffers(1, &stencilID));
if (!stencilID || !colorID) {
deleteIDs();
return {};
}
GrGLFramebufferInfo info;
info.fFBOID = 0;
this->glCaps().getSizedInternalFormat(config, &info.fFormat);
GL_CALL(GenFramebuffers(1, &info.fFBOID));
if (!info.fFBOID) {
GL_CALL(DeleteRenderbuffers(2, rbIDs));
return GrBackendRenderTarget();
deleteIDs();
return {};
}
this->invalidateBoundRenderTarget();
this->bindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID);
GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbIDs[0]));
GL_ALLOC_CALL(this->glInterface(),
RenderbufferStorage(GR_GL_RENDERBUFFER, colorBufferFormat, w, h));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_RENDERBUFFER,
rbIDs[0]));
GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbIDs[1]));
if (useTexture) {
this->setScratchTextureUnit();
GL_CALL(BindTexture(GR_GL_TEXTURE_2D, colorID));
GL_CALL(TexImage2D(GR_GL_TEXTURE_2D, 0, colorBufferFormat, w, h, 0, externalFormat,
externalType, nullptr));
GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_TEXTURE_2D,
colorID, 0));
} else {
GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, colorID));
GL_ALLOC_CALL(this->glInterface(),
RenderbufferStorage(GR_GL_RENDERBUFFER, colorBufferFormat, w, h));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0,
GR_GL_RENDERBUFFER, colorID));
}
GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, stencilID));
auto stencilBufferFormat = this->glCaps().stencilFormats()[sFormatIdx].fInternalFormat;
GL_ALLOC_CALL(this->glInterface(),
RenderbufferStorage(GR_GL_RENDERBUFFER, stencilBufferFormat, w, h));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT, GR_GL_RENDERBUFFER,
rbIDs[1]));
stencilID));
if (this->glCaps().stencilFormats()[sFormatIdx].fPacked) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_DEPTH_ATTACHMENT,
GR_GL_RENDERBUFFER, rbIDs[1]));
GR_GL_RENDERBUFFER, stencilID));
}
// We don't want to have to recover the renderbuffer IDs later to delete them. OpenGL has this
// rule that if a renderbuffer is deleted and a FBO other than the current FBO has the RB
// attached then deletion is delayed. So we unbind the FBO here and delete the renderbuffers.
// We don't want to have to recover the renderbuffer/texture IDs later to delete them. OpenGL
// has this rule that if a renderbuffer/texture is deleted and a FBO other than the current FBO
// has the RB attached then deletion is delayed. So we unbind the FBO here and delete the
// renderbuffers/texture.
this->bindFramebuffer(GR_GL_FRAMEBUFFER, 0);
GL_CALL(DeleteRenderbuffers(2, rbIDs));
deleteIDs();
this->bindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID);
GrGLenum status;
@ -4073,6 +4107,13 @@ GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(int w, int h
// Lots of tests don't go through Skia's public interface which will set the config so for
// testing we make sure we set a config here.
beRT.setPixelConfig(config);
#ifdef SK_DEBUG
SkColorType skColorType = GrColorTypeToSkColorType(colorType);
if (skColorType != kUnknown_SkColorType) {
SkASSERT(this->caps()->validateBackendRenderTarget(
beRT, GrColorTypeToSkColorType(colorType), &config));
}
#endif
return beRT;
}

View File

@ -168,6 +168,20 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrContext_colorTypeSupportedAsSurface, report
if (backendTex.isValid()) {
gpu->deleteTestingOnlyBackendTexture(backendTex);
}
GrBackendRenderTarget backendRenderTarget = gpu->createTestingOnlyBackendRenderTarget(
16, 16, SkColorTypeToGrColorType(colorType));
can = ctxInfo.grContext()->colorTypeSupportedAsSurface(colorType);
surf = SkSurface::MakeFromBackendRenderTarget(ctxInfo.grContext(), backendRenderTarget,
kTopLeft_GrSurfaceOrigin, colorType, nullptr,
nullptr);
REPORTER_ASSERT(reporter, can == SkToBool(surf), "ct: %d, can: %d, surf: %d", colorType,
can, SkToBool(surf));
surf.reset();
ctxInfo.grContext()->flush();
if (backendRenderTarget.isValid()) {
gpu->deleteTestingOnlyBackendRenderTarget(backendRenderTarget);
}
}
}