Commit d1405e51 by Jamie Madill

Share FBO state with object and Impl.

This patch introduces a new Framebuffer::Data class, which stores attachment related state. This will eliminate the need to store duplicated state between the classes. BUG=angleproject:930 Change-Id: I80de4db39ab99d623b0ad8306bf3cbb794cd8bd5 Reviewed-on: https://chromium-review.googlesource.com/254100Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 0af26e10
......@@ -184,10 +184,8 @@ void Context::makeCurrent(egl::Surface *surface)
mHasBeenCurrent = true;
}
Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer->createFramebuffer(),
mRenderer->createDefaultAttachment(GL_BACK, surface),
mRenderer->createDefaultAttachment(GL_DEPTH, surface),
mRenderer->createDefaultAttachment(GL_STENCIL, surface));
// TODO(jmadill): do not allocate new pointers here
Framebuffer *framebufferZero = new DefaultFramebuffer(mCaps, mRenderer, surface);
setFramebufferZero(framebufferZero);
......@@ -523,7 +521,7 @@ void Context::bindReadFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
mFramebufferMap[framebuffer] = new Framebuffer(mRenderer->createFramebuffer(), framebuffer);
mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
}
mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
......@@ -533,7 +531,7 @@ void Context::bindDrawFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
mFramebufferMap[framebuffer] = new Framebuffer(mRenderer->createFramebuffer(), framebuffer);
mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
}
mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
......
......@@ -23,118 +23,103 @@
namespace gl
{
Framebuffer::Framebuffer(rx::FramebufferImpl *impl, GLuint id)
: mImpl(impl),
mId(id),
mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
mDepthbuffer(NULL),
mStencilbuffer(NULL)
namespace
{
ASSERT(mImpl != nullptr);
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
void DeleteMatchingAttachment(FramebufferAttachment *&attachment, GLenum matchType, GLuint matchId)
{
if (attachment && attachment->type() == matchType && attachment->id() == matchId)
{
mColorbuffers[colorAttachment] = NULL;
mDrawBufferStates[colorAttachment] = GL_NONE;
SafeDelete(attachment);
}
}
}
Framebuffer::Data::Data(const Caps &caps)
: mColorAttachments(caps.maxColorAttachments, nullptr),
mDepthAttachment(nullptr),
mStencilAttachment(nullptr),
mDrawBufferStates(caps.maxDrawBuffers, GL_NONE),
mReadBufferState(GL_COLOR_ATTACHMENT0_EXT)
{
mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
}
Framebuffer::~Framebuffer()
Framebuffer::Data::~Data()
{
SafeDelete(mImpl);
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
for (auto &colorAttachment : mColorAttachments)
{
SafeDelete(mColorbuffers[colorAttachment]);
SafeDelete(colorAttachment);
}
SafeDelete(mDepthbuffer);
SafeDelete(mStencilbuffer);
SafeDelete(mDepthAttachment);
SafeDelete(mStencilAttachment);
}
void Framebuffer::detachTexture(GLuint textureId)
Framebuffer::Framebuffer(const Caps &caps, rx::Renderer *renderer, GLuint id)
: mData(caps),
mImpl(renderer->createFramebuffer(mData)),
mId(id)
{
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
if (attachment && attachment->isTextureWithId(textureId))
{
SafeDelete(mColorbuffers[colorAttachment]);
}
}
ASSERT(mImpl != nullptr);
}
if (mDepthbuffer && mDepthbuffer->isTextureWithId(textureId))
{
SafeDelete(mDepthbuffer);
}
Framebuffer::~Framebuffer()
{
SafeDelete(mImpl);
}
if (mStencilbuffer && mStencilbuffer->isTextureWithId(textureId))
{
SafeDelete(mStencilbuffer);
}
void Framebuffer::detachTexture(GLuint textureId)
{
detachResourceById(GL_TEXTURE, textureId);
}
void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
{
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
if (attachment && attachment->isRenderbufferWithId(renderbufferId))
{
SafeDelete(mColorbuffers[colorAttachment]);
}
}
detachResourceById(GL_RENDERBUFFER, renderbufferId);
}
if (mDepthbuffer && mDepthbuffer->isRenderbufferWithId(renderbufferId))
void Framebuffer::detachResourceById(GLenum resourceType, GLuint resourceId)
{
for (auto &colorAttachment : mData.mColorAttachments)
{
SafeDelete(mDepthbuffer);
DeleteMatchingAttachment(colorAttachment, resourceType, resourceId);
}
if (mStencilbuffer && mStencilbuffer->isRenderbufferWithId(renderbufferId))
{
SafeDelete(mStencilbuffer);
}
DeleteMatchingAttachment(mData.mDepthAttachment, resourceType, resourceId);
DeleteMatchingAttachment(mData.mStencilAttachment, resourceType, resourceId);
}
FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
{
ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
return mColorbuffers[colorAttachment];
ASSERT(colorAttachment < mData.mColorAttachments.size());
return mData.mColorAttachments[colorAttachment];
}
FramebufferAttachment *Framebuffer::getDepthbuffer() const
{
return mDepthbuffer;
return mData.mDepthAttachment;
}
FramebufferAttachment *Framebuffer::getStencilbuffer() const
{
return mStencilbuffer;
return mData.mStencilAttachment;
}
FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
{
return (hasValidDepthStencil() ? mDepthbuffer : NULL);
return (hasValidDepthStencil() ? mData.mDepthAttachment : NULL);
}
FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
{
FramebufferAttachment *depthstencilbuffer = mDepthbuffer;
if (!depthstencilbuffer)
{
depthstencilbuffer = mStencilbuffer;
}
return depthstencilbuffer;
return (mData.mDepthAttachment != nullptr ? mData.mDepthAttachment : mData.mStencilAttachment);
}
FramebufferAttachment *Framebuffer::getReadColorbuffer() const
{
size_t readIndex = (mReadBufferState == GL_BACK ? 0 : static_cast<size_t>(mReadBufferState - GL_COLOR_ATTACHMENT0));
ASSERT(readIndex < IMPLEMENTATION_MAX_DRAW_BUFFERS);
return mColorbuffers[readIndex];
size_t readIndex = (mData.mReadBufferState == GL_BACK ? 0 :
static_cast<size_t>(mData.mReadBufferState - GL_COLOR_ATTACHMENT0));
ASSERT(readIndex < mData.mColorAttachments.size());
return mData.mColorAttachments[readIndex];
}
GLenum Framebuffer::getReadColorbufferType() const
......@@ -145,15 +130,15 @@ GLenum Framebuffer::getReadColorbufferType() const
FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
{
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
for (FramebufferAttachment *colorAttachment : mData.mColorAttachments)
{
if (mColorbuffers[colorAttachment])
if (colorAttachment != nullptr)
{
return mColorbuffers[colorAttachment];
return colorAttachment;
}
}
return NULL;
return nullptr;
}
FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
......@@ -187,39 +172,44 @@ FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
{
return mDrawBufferStates[colorAttachment];
ASSERT(colorAttachment < mData.mDrawBufferStates.size());
return mData.mDrawBufferStates[colorAttachment];
}
void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers)
{
ASSERT(count <= ArraySize(mDrawBufferStates));
std::copy(buffers, buffers + count, mDrawBufferStates);
std::fill(mDrawBufferStates + count, mDrawBufferStates + ArraySize(mDrawBufferStates), GL_NONE);
auto &drawStates = mData.mDrawBufferStates;
ASSERT(count <= drawStates.size());
std::copy(buffers, buffers + count, drawStates.begin());
std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE);
mImpl->setDrawBuffers(count, buffers);
}
GLenum Framebuffer::getReadBufferState() const
{
return mReadBufferState;
return mData.mReadBufferState;
}
void Framebuffer::setReadBuffer(GLenum buffer)
{
ASSERT(buffer == GL_BACK || buffer == GL_NONE ||
(buffer >= GL_COLOR_ATTACHMENT0 &&
(buffer - GL_COLOR_ATTACHMENT0) < IMPLEMENTATION_MAX_DRAW_BUFFERS));
mReadBufferState = buffer;
(buffer - GL_COLOR_ATTACHMENT0) < mData.mColorAttachments.size()));
mData.mReadBufferState = buffer;
mImpl->setReadBuffer(buffer);
}
bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
{
return (mColorbuffers[colorAttachment] && mDrawBufferStates[colorAttachment] != GL_NONE);
ASSERT(colorAttachment < mData.mColorAttachments.size());
return (mData.mColorAttachments[colorAttachment] &&
mData.mDrawBufferStates[colorAttachment] != GL_NONE);
}
bool Framebuffer::hasEnabledColorAttachment() const
{
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment)
{
if (isEnabledColorAttachment(colorAttachment))
{
......@@ -232,12 +222,12 @@ bool Framebuffer::hasEnabledColorAttachment() const
bool Framebuffer::hasStencil() const
{
return (mStencilbuffer && mStencilbuffer->getStencilSize() > 0);
return (mData.mStencilAttachment && mData.mStencilAttachment->getStencilSize() > 0);
}
bool Framebuffer::usingExtendedDrawBuffers() const
{
for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
for (size_t colorAttachment = 1; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment)
{
if (isEnabledColorAttachment(colorAttachment))
{
......@@ -263,21 +253,19 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
int samples = -1;
bool missingAttachment = true;
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
for (const FramebufferAttachment *colorAttachment : mData.mColorAttachments)
{
const FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
if (colorbuffer)
if (colorAttachment != nullptr)
{
if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
if (colorAttachment->getWidth() == 0 || colorAttachment->getHeight() == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
GLenum internalformat = colorbuffer->getInternalFormat();
GLenum internalformat = colorAttachment->getInternalFormat();
const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (colorbuffer->type() == GL_TEXTURE)
if (colorAttachment->type() == GL_TEXTURE)
{
if (!formatCaps.renderable)
{
......@@ -289,7 +277,7 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else if (colorbuffer->type() == GL_RENDERBUFFER)
else if (colorAttachment->type() == GL_RENDERBUFFER)
{
if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
{
......@@ -300,14 +288,14 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
if (!missingAttachment)
{
// all color attachments must have the same width and height
if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
if (colorAttachment->getWidth() != width || colorAttachment->getHeight() != height)
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
// APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
// all color attachments have the same number of samples for the FBO to be complete.
if (colorbuffer->getSamples() != samples)
if (colorAttachment->getSamples() != samples)
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
}
......@@ -324,26 +312,27 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
}
else
{
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
samples = colorbuffer->getSamples();
width = colorAttachment->getWidth();
height = colorAttachment->getHeight();
samples = colorAttachment->getSamples();
colorbufferSize = formatInfo.pixelBytes;
missingAttachment = false;
}
}
}
if (mDepthbuffer)
const FramebufferAttachment *depthAttachment = mData.mDepthAttachment;
if (depthAttachment != nullptr)
{
if (mDepthbuffer->getWidth() == 0 || mDepthbuffer->getHeight() == 0)
if (depthAttachment->getWidth() == 0 || depthAttachment->getHeight() == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
GLenum internalformat = mDepthbuffer->getInternalFormat();
GLenum internalformat = depthAttachment->getInternalFormat();
const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mDepthbuffer->type() == GL_TEXTURE)
if (depthAttachment->type() == GL_TEXTURE)
{
// depth texture attachments require OES/ANGLE_depth_texture
if (!data.extensions->depthTextures)
......@@ -361,7 +350,7 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else if (mDepthbuffer->type() == GL_RENDERBUFFER)
else if (depthAttachment->type() == GL_RENDERBUFFER)
{
if (!formatCaps.renderable || formatInfo.depthBits == 0)
{
......@@ -371,32 +360,33 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
if (missingAttachment)
{
width = mDepthbuffer->getWidth();
height = mDepthbuffer->getHeight();
samples = mDepthbuffer->getSamples();
width = depthAttachment->getWidth();
height = depthAttachment->getHeight();
samples = depthAttachment->getSamples();
missingAttachment = false;
}
else if (width != mDepthbuffer->getWidth() || height != mDepthbuffer->getHeight())
else if (width != depthAttachment->getWidth() || height != depthAttachment->getHeight())
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
else if (samples != mDepthbuffer->getSamples())
else if (samples != depthAttachment->getSamples())
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
}
}
if (mStencilbuffer)
const FramebufferAttachment *stencilAttachment = mData.mStencilAttachment;
if (stencilAttachment)
{
if (mStencilbuffer->getWidth() == 0 || mStencilbuffer->getHeight() == 0)
if (stencilAttachment->getWidth() == 0 || stencilAttachment->getHeight() == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
GLenum internalformat = mStencilbuffer->getInternalFormat();
GLenum internalformat = stencilAttachment->getInternalFormat();
const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mStencilbuffer->type() == GL_TEXTURE)
if (stencilAttachment->type() == GL_TEXTURE)
{
// texture stencil attachments come along as part
// of OES_packed_depth_stencil + OES/ANGLE_depth_texture
......@@ -415,7 +405,7 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else if (mStencilbuffer->type() == GL_RENDERBUFFER)
else if (stencilAttachment->type() == GL_RENDERBUFFER)
{
if (!formatCaps.renderable || formatInfo.stencilBits == 0)
{
......@@ -425,16 +415,16 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
if (missingAttachment)
{
width = mStencilbuffer->getWidth();
height = mStencilbuffer->getHeight();
samples = mStencilbuffer->getSamples();
width = stencilAttachment->getWidth();
height = stencilAttachment->getHeight();
samples = stencilAttachment->getSamples();
missingAttachment = false;
}
else if (width != mStencilbuffer->getWidth() || height != mStencilbuffer->getHeight())
else if (width != stencilAttachment->getWidth() || height != stencilAttachment->getHeight())
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
else if (samples != mStencilbuffer->getSamples())
else if (samples != stencilAttachment->getSamples())
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
}
......@@ -442,7 +432,7 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
// if we have both a depth and stencil buffer, they must refer to the same object
// since we only support packed_depth_stencil and not separate depth and stencil
if (mDepthbuffer && mStencilbuffer && !hasValidDepthStencil())
if (depthAttachment && stencilAttachment && !hasValidDepthStencil())
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
......@@ -518,11 +508,11 @@ int Framebuffer::getSamples(const gl::Data &data) const
{
// for a complete framebuffer, all attachments must have the same sample count
// in this case return the first nonzero sample size
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
for (const FramebufferAttachment *colorAttachment : mData.mColorAttachments)
{
if (mColorbuffers[colorAttachment])
if (colorAttachment != nullptr)
{
return mColorbuffers[colorAttachment]->getSamples();
return colorAttachment->getSamples();
}
}
}
......@@ -534,28 +524,28 @@ bool Framebuffer::hasValidDepthStencil() const
{
// A valid depth-stencil attachment has the same resource bound to both the
// depth and stencil attachment points.
return (mDepthbuffer && mStencilbuffer &&
mDepthbuffer->type() == mStencilbuffer->type() &&
mDepthbuffer->id() == mStencilbuffer->id());
return (mData.mDepthAttachment && mData.mStencilAttachment &&
mData.mDepthAttachment->type() == mData.mStencilAttachment->type() &&
mData.mDepthAttachment->id() == mData.mStencilAttachment->id());
}
ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &workarounds) const
{
ColorbufferInfo colorbuffersForRender;
for (size_t colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorAttachment)
for (size_t attachmentIndex = 0; attachmentIndex < mData.mColorAttachments.size(); ++attachmentIndex)
{
GLenum drawBufferState = mDrawBufferStates[colorAttachment];
FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
GLenum drawBufferState = mData.mDrawBufferStates[attachmentIndex];
FramebufferAttachment *colorAttachment = mData.mColorAttachments[attachmentIndex];
if (colorbuffer != NULL && drawBufferState != GL_NONE)
if (colorAttachment != nullptr && drawBufferState != GL_NONE)
{
ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
colorbuffersForRender.push_back(colorbuffer);
ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
colorbuffersForRender.push_back(colorAttachment);
}
else if (!workarounds.mrtPerfWorkaround)
{
colorbuffersForRender.push_back(NULL);
colorbuffersForRender.push_back(nullptr);
}
}
......@@ -579,54 +569,54 @@ void Framebuffer::setNULLAttachment(GLenum attachment)
void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj)
{
if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + IMPLEMENTATION_MAX_DRAW_BUFFERS))
if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + mData.mColorAttachments.size()))
{
size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0;
SafeDelete(mColorbuffers[colorAttachment]);
mColorbuffers[colorAttachment] = attachmentObj;
SafeDelete(mData.mColorAttachments[colorAttachment]);
mData.mColorAttachments[colorAttachment] = attachmentObj;
mImpl->setColorAttachment(colorAttachment, attachmentObj);
}
else if (attachment == GL_BACK)
{
SafeDelete(mColorbuffers[0]);
mColorbuffers[0] = attachmentObj;
SafeDelete(mData.mColorAttachments[0]);
mData.mColorAttachments[0] = attachmentObj;
mImpl->setColorAttachment(0, attachmentObj);
}
else if (attachment == GL_DEPTH_ATTACHMENT || attachment == GL_DEPTH)
{
SafeDelete(mDepthbuffer);
mDepthbuffer = attachmentObj;
SafeDelete(mData.mDepthAttachment);
mData.mDepthAttachment = attachmentObj;
mImpl->setDepthttachment(attachmentObj);
}
else if (attachment == GL_STENCIL_ATTACHMENT || attachment == GL_STENCIL)
{
SafeDelete(mStencilbuffer);
mStencilbuffer = attachmentObj;
SafeDelete(mData.mStencilAttachment);
mData.mStencilAttachment = attachmentObj;
mImpl->setStencilAttachment(attachmentObj);
}
else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT || attachment == GL_DEPTH_STENCIL)
{
SafeDelete(mDepthbuffer);
SafeDelete(mStencilbuffer);
SafeDelete(mData.mDepthAttachment);
SafeDelete(mData.mStencilAttachment);
// ensure this is a legitimate depth+stencil format
if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0)
{
mDepthbuffer = attachmentObj;
mData.mDepthAttachment = attachmentObj;
mImpl->setDepthttachment(attachmentObj);
// Make a new attachment object to ensure we do not double-delete
// See angle issue 686
if (attachmentObj->type() == GL_TEXTURE)
{
mStencilbuffer = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(),
*attachmentObj->getTextureImageIndex());
mImpl->setStencilAttachment(mStencilbuffer);
mData.mStencilAttachment = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(),
*attachmentObj->getTextureImageIndex());
mImpl->setStencilAttachment(mData.mStencilAttachment);
}
else if (attachmentObj->type() == GL_RENDERBUFFER)
{
mStencilbuffer = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer());
mImpl->setStencilAttachment(mStencilbuffer);
mData.mStencilAttachment = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer());
mImpl->setStencilAttachment(mData.mStencilAttachment);
}
else
{
......@@ -640,10 +630,13 @@ void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attach
}
}
DefaultFramebuffer::DefaultFramebuffer(rx::FramebufferImpl *impl, rx::DefaultAttachmentImpl *colorAttachment,
rx::DefaultAttachmentImpl *depthAttachment, rx::DefaultAttachmentImpl *stencilAttachment)
: Framebuffer(impl, 0)
DefaultFramebuffer::DefaultFramebuffer(const Caps &caps, rx::Renderer *renderer, egl::Surface *surface)
: Framebuffer(caps, renderer, 0)
{
rx::DefaultAttachmentImpl *colorAttachment = renderer->createDefaultAttachment(GL_BACK, surface);
rx::DefaultAttachmentImpl *depthAttachment = renderer->createDefaultAttachment(GL_DEPTH, surface);
rx::DefaultAttachmentImpl *stencilAttachment = renderer->createDefaultAttachment(GL_STENCIL, surface);
ASSERT(colorAttachment);
setAttachment(GL_BACK, new DefaultAttachment(GL_BACK, colorAttachment));
......
......@@ -20,23 +20,29 @@
namespace rx
{
class RenderbufferImpl;
struct Workarounds;
class DefaultAttachmentImpl;
class FramebufferImpl;
class RenderbufferImpl;
class Renderer;
struct Workarounds;
}
namespace egl
{
class Surface;
}
namespace gl
{
class FramebufferAttachment;
class Texture;
class Renderbuffer;
struct ImageIndex;
struct Caps;
struct Extensions;
class State;
class Texture;
class TextureCapsMap;
struct Caps;
struct Data;
class State;
struct Extensions;
struct ImageIndex;
struct Rectangle;
typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
......@@ -44,7 +50,25 @@ typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
class Framebuffer
{
public:
Framebuffer(rx::FramebufferImpl *impl, GLuint id);
class Data final
{
public:
Data(const Caps &caps);
~Data();
std::vector<FramebufferAttachment *> mColorAttachments;
FramebufferAttachment *mDepthAttachment;
FramebufferAttachment *mStencilAttachment;
std::vector<GLenum> mDrawBufferStates;
GLenum mReadBufferState;
private:
DISALLOW_COPY_AND_ASSIGN(Data);
};
Framebuffer(const Caps &caps, rx::Renderer *renderer, GLuint id);
virtual ~Framebuffer();
const rx::FramebufferImpl *getImplementation() const { return mImpl; }
......@@ -108,17 +132,12 @@ class Framebuffer
protected:
void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj);
void detachResourceById(GLenum resourceType, GLuint resourceId);
Data mData;
rx::FramebufferImpl *mImpl;
GLuint mId;
FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
GLenum mDrawBufferStates[IMPLEMENTATION_MAX_DRAW_BUFFERS];
GLenum mReadBufferState;
FramebufferAttachment *mDepthbuffer;
FramebufferAttachment *mStencilbuffer;
private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
};
......@@ -126,8 +145,7 @@ class Framebuffer
class DefaultFramebuffer : public Framebuffer
{
public:
DefaultFramebuffer(rx::FramebufferImpl *impl, rx::DefaultAttachmentImpl *colorAttachment,
rx::DefaultAttachmentImpl *depthAttachment, rx::DefaultAttachmentImpl *stencilAttachment);
DefaultFramebuffer(const gl::Caps &caps, rx::Renderer *renderer, egl::Surface *surface);
private:
DISALLOW_COPY_AND_ASSIGN(DefaultFramebuffer);
......
......@@ -12,6 +12,7 @@
#include "angle_gl.h"
#include "common/angleutils.h"
#include "libANGLE/Error.h"
#include "libANGLE/Framebuffer.h"
namespace gl
{
......@@ -27,8 +28,8 @@ namespace rx
class FramebufferImpl
{
public:
FramebufferImpl() {}
virtual ~FramebufferImpl() {};
FramebufferImpl(const gl::Framebuffer::Data &data) : mData(data) { }
virtual ~FramebufferImpl() { }
virtual void setColorAttachment(size_t index, const gl::FramebufferAttachment *attachment) = 0;
virtual void setDepthttachment(const gl::FramebufferAttachment *attachment) = 0;
......@@ -56,6 +57,11 @@ class FramebufferImpl
virtual GLenum checkStatus() const = 0;
const gl::Framebuffer::Data &getData() const { return mData; }
protected:
const gl::Framebuffer::Data &mData;
private:
DISALLOW_COPY_AND_ASSIGN(FramebufferImpl);
};
......
......@@ -12,6 +12,7 @@
#include "libANGLE/Caps.h"
#include "libANGLE/Error.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/Uniform.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/Workarounds.h"
......@@ -31,7 +32,6 @@ class Surface;
namespace gl
{
class Buffer;
class Framebuffer;
struct Data;
}
......@@ -76,7 +76,7 @@ class Renderer
// Framebuffer creation
virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) = 0;
virtual FramebufferImpl *createFramebuffer() = 0;
virtual FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) = 0;
// Texture creation
virtual TextureImpl *createTexture(GLenum target) = 0;
......
......@@ -61,8 +61,9 @@ RenderTargetD3D *DefaultAttachmentD3D::getRenderTarget() const
}
FramebufferD3D::FramebufferD3D(RendererD3D *renderer)
: mRenderer(renderer),
FramebufferD3D::FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer)
: FramebufferImpl(data),
mRenderer(renderer),
mColorBuffers(renderer->getRendererCaps().maxColorAttachments),
mDepthbuffer(nullptr),
mStencilbuffer(nullptr),
......
......@@ -51,7 +51,7 @@ class DefaultAttachmentD3D : public DefaultAttachmentImpl
class FramebufferD3D : public FramebufferImpl
{
public:
FramebufferD3D(RendererD3D *renderer);
FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer);
virtual ~FramebufferD3D();
void setColorAttachment(size_t index, const gl::FramebufferAttachment *attachment) override;
......
......@@ -24,8 +24,8 @@
namespace rx
{
Framebuffer11::Framebuffer11(Renderer11 *renderer)
: FramebufferD3D(renderer),
Framebuffer11::Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer)
: FramebufferD3D(data, renderer),
mRenderer(renderer)
{
ASSERT(mRenderer != nullptr);
......
......@@ -18,7 +18,7 @@ class Renderer11;
class Framebuffer11 : public FramebufferD3D
{
public:
Framebuffer11(Renderer11 *renderer);
Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer);
virtual ~Framebuffer11();
// Invalidate the cached swizzles of all bound texture attachments.
......
......@@ -2626,9 +2626,9 @@ DefaultAttachmentImpl *Renderer11::createDefaultAttachment(GLenum type, egl::Sur
}
}
FramebufferImpl *Renderer11::createFramebuffer()
FramebufferImpl *Renderer11::createFramebuffer(const gl::Framebuffer::Data &data)
{
return new Framebuffer11(this);
return new Framebuffer11(data, this);
}
CompilerImpl *Renderer11::createCompiler(const gl::Data &data)
......
......@@ -149,8 +149,8 @@ class Renderer11 : public RendererD3D
virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT);
// Framebuffer creation
virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) override;
virtual FramebufferImpl *createFramebuffer() override;
DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) override;
FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override;
// Shader creation
virtual CompilerImpl *createCompiler(const gl::Data &data);
......
......@@ -21,8 +21,8 @@
namespace rx
{
Framebuffer9::Framebuffer9(Renderer9 *renderer)
: FramebufferD3D(renderer),
Framebuffer9::Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer)
: FramebufferD3D(data, renderer),
mRenderer(renderer)
{
ASSERT(mRenderer != nullptr);
......
......@@ -18,7 +18,7 @@ class Renderer9;
class Framebuffer9 : public FramebufferD3D
{
public:
Framebuffer9(Renderer9 *renderer);
Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer);
virtual ~Framebuffer9();
private:
......
......@@ -2650,9 +2650,9 @@ DefaultAttachmentImpl *Renderer9::createDefaultAttachment(GLenum type, egl::Surf
}
}
FramebufferImpl *Renderer9::createFramebuffer()
FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data)
{
return new Framebuffer9(this);
return new Framebuffer9(data, this);
}
CompilerImpl *Renderer9::createCompiler(const gl::Data &data)
......
......@@ -158,8 +158,8 @@ class Renderer9 : public RendererD3D
virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT);
// Framebuffer creation
virtual DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) override;
virtual FramebufferImpl *createFramebuffer() override;
DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) override;
FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override;
// Shader creation
virtual CompilerImpl *createCompiler(const gl::Data &data);
......
......@@ -13,8 +13,8 @@
namespace rx
{
FramebufferGL::FramebufferGL()
: FramebufferImpl()
FramebufferGL::FramebufferGL(const gl::Framebuffer::Data &data)
: FramebufferImpl(data)
{}
FramebufferGL::~FramebufferGL()
......
......@@ -17,7 +17,7 @@ namespace rx
class FramebufferGL : public FramebufferImpl
{
public:
FramebufferGL();
FramebufferGL(const gl::Framebuffer::Data &data);
~FramebufferGL() override;
void setColorAttachment(size_t index, const gl::FramebufferAttachment *attachment) override;
......
......@@ -100,9 +100,9 @@ DefaultAttachmentImpl *RendererGL::createDefaultAttachment(GLenum type, egl::Sur
return new DefaultAttachmentGL();
}
FramebufferImpl *RendererGL::createFramebuffer()
FramebufferImpl *RendererGL::createFramebuffer(const gl::Framebuffer::Data &data)
{
return new FramebufferGL();
return new FramebufferGL(data);
}
TextureImpl *RendererGL::createTexture(GLenum target)
......
......@@ -38,7 +38,7 @@ class RendererGL : public Renderer
// Framebuffer creation
DefaultAttachmentImpl *createDefaultAttachment(GLenum type, egl::Surface *surface) override;
FramebufferImpl *createFramebuffer() override;
FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override;
// Texture creation
TextureImpl *createTexture(GLenum target) override;
......
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