Commit ab75a056 by Geoff Lang

Refactor Framebuffer attachment application.

Instead of passing texture and renderbufer IDs which requires a call to gl::getNonLostContext to resolve the objects, pass the Texture and Renderbuffer objects directly. BUG=angleproject:733 Change-Id: Ia500a781643e43a17c8e9cea9f95847a7ff7b25d Reviewed-on: https://chromium-review.googlesource.com/228280Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent de8892b4
...@@ -96,124 +96,6 @@ Framebuffer::~Framebuffer() ...@@ -96,124 +96,6 @@ Framebuffer::~Framebuffer()
SafeDelete(mStencilbuffer); SafeDelete(mStencilbuffer);
} }
FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
{
if (handle == 0)
{
return NULL;
}
gl::Context *context = gl::getContext();
switch (type)
{
case GL_NONE:
return NULL;
case GL_RENDERBUFFER:
return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
case GL_TEXTURE_2D:
{
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_2D)
{
return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
}
else
{
return NULL;
}
}
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
{
return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
}
else
{
return NULL;
}
}
case GL_TEXTURE_3D:
{
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_3D)
{
return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
}
else
{
return NULL;
}
}
case GL_TEXTURE_2D_ARRAY:
{
Texture *texture = context->getTexture(handle);
if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
{
return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
}
else
{
return NULL;
}
}
default:
UNREACHABLE();
return NULL;
}
}
void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
{
ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
SafeDelete(mColorbuffers[colorAttachment]);
GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
{
SafeDelete(mDepthbuffer);
mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
}
void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
{
SafeDelete(mStencilbuffer);
mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
}
void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
{
FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
SafeDelete(mDepthbuffer);
SafeDelete(mStencilbuffer);
// ensure this is a legitimate depth+stencil format
if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
{
mDepthbuffer = attachment;
// Make a new attachment object to ensure we do not double-delete
// See angle issue 686
mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
}
}
void Framebuffer::detachTexture(GLuint textureId) void Framebuffer::detachTexture(GLuint textureId)
{ {
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
...@@ -699,6 +581,68 @@ ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &wor ...@@ -699,6 +581,68 @@ ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &wor
return colorbuffersForRender; return colorbuffersForRender;
} }
void Framebuffer::setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex)
{
setAttachment(attachment, new TextureAttachment(attachment, texture, imageIndex));
}
void Framebuffer::setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer)
{
setAttachment(attachment, new RenderbufferAttachment(attachment, renderbuffer));
}
void Framebuffer::setNULLAttachment(GLenum attachment)
{
setAttachment(attachment, NULL);
}
void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj)
{
if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + IMPLEMENTATION_MAX_DRAW_BUFFERS))
{
size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0;
SafeDelete(mColorbuffers[colorAttachment]);
mColorbuffers[colorAttachment] = attachmentObj;
}
else if (attachment == GL_DEPTH_ATTACHMENT)
{
SafeDelete(mDepthbuffer);
mDepthbuffer = attachmentObj;
}
else if (attachment == GL_STENCIL_ATTACHMENT)
{
SafeDelete(mStencilbuffer);
mStencilbuffer = attachmentObj;
}
else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
{
SafeDelete(mDepthbuffer);
SafeDelete(mStencilbuffer);
// ensure this is a legitimate depth+stencil format
if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0)
{
mDepthbuffer = attachmentObj;
// Make a new attachment object to ensure we do not double-delete
// See angle issue 686
if (attachmentObj->isTexture())
{
mStencilbuffer = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(),
*attachmentObj->getTextureImageIndex());
}
else
{
mStencilbuffer = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer());
}
}
}
else
{
UNREACHABLE();
}
}
GLenum DefaultFramebuffer::completeness(const gl::Data &) const GLenum DefaultFramebuffer::completeness(const gl::Data &) const
{ {
// The default framebuffer *must* always be complete, though it may not be // The default framebuffer *must* always be complete, though it may not be
......
...@@ -27,6 +27,9 @@ struct Workarounds; ...@@ -27,6 +27,9 @@ struct Workarounds;
namespace gl namespace gl
{ {
class FramebufferAttachment; class FramebufferAttachment;
class Texture;
class Renderbuffer;
struct ImageIndex;
struct Caps; struct Caps;
struct Extensions; struct Extensions;
class TextureCapsMap; class TextureCapsMap;
...@@ -42,10 +45,9 @@ class Framebuffer ...@@ -42,10 +45,9 @@ class Framebuffer
GLuint id() const { return mId; } GLuint id() const { return mId; }
void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer); void setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex);
void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer); void setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer);
void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer); void setNULLAttachment(GLenum attachment);
void setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer);
void detachTexture(GLuint texture); void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer); void detachRenderbuffer(GLuint renderbuffer);
...@@ -94,7 +96,7 @@ class Framebuffer ...@@ -94,7 +96,7 @@ class Framebuffer
private: private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer); DISALLOW_COPY_AND_ASSIGN(Framebuffer);
FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const; void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj);
}; };
class DefaultFramebuffer : public Framebuffer class DefaultFramebuffer : public Framebuffer
......
...@@ -1595,28 +1595,14 @@ void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLe ...@@ -1595,28 +1595,14 @@ void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLe
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
ASSERT(framebuffer); ASSERT(framebuffer);
if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) if (renderbuffer != 0)
{ {
unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0); framebuffer->setRenderbufferAttachment(attachment, renderbufferObject);
} }
else else
{ {
switch (attachment) framebuffer->setNULLAttachment(attachment);
{
case GL_DEPTH_ATTACHMENT:
framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
break;
case GL_STENCIL_ATTACHMENT:
framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
break;
case GL_DEPTH_STENCIL_ATTACHMENT:
framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
break;
default:
UNREACHABLE();
break;
}
} }
} }
} }
...@@ -1634,27 +1620,18 @@ void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum ...@@ -1634,27 +1620,18 @@ void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum
return; return;
} }
if (texture == 0)
{
textarget = GL_NONE;
}
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
ASSERT(framebuffer); ASSERT(framebuffer);
if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) if (texture != 0)
{ {
const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); gl::Texture *textureObj = context->getTexture(texture);
framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0); gl::ImageIndex index(textarget, level, gl::ImageIndex::ENTIRE_LEVEL);
framebuffer->setTextureAttachment(attachment, textureObj, index);
} }
else else
{ {
switch (attachment) framebuffer->setNULLAttachment(attachment);
{
case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, 0); break;
case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, 0); break;
case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break;
}
} }
} }
} }
...@@ -5853,22 +5830,15 @@ void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLu ...@@ -5853,22 +5830,15 @@ void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLu
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
ASSERT(framebuffer); ASSERT(framebuffer);
gl::Texture *textureObject = context->getTexture(texture); if (texture != 0)
GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE;
if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
{ {
const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); gl::Texture *textureObject = context->getTexture(texture);
framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer); gl::ImageIndex index(textureObject->getTarget(), level, layer);
framebuffer->setTextureAttachment(attachment, textureObject, index);
} }
else else
{ {
switch (attachment) framebuffer->setNULLAttachment(attachment);
{
case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, layer); break;
case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, layer); break;
case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break;
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment