Skip to content
Snippets Groups Projects
Commit 97872067 authored by apatrick@chromium.org's avatar apatrick@chromium.org
Browse files

Saved offscreen textures are allocated GL_RGB when no alpha channel is requested.

There appears to also be problems in ANGLE which have not been addressed yet, specifically GL_RGB textures are allocated D3DFMT_A8R8G8B8 instead of D3DFMT_X8R8G8B8.

Prevent saved and target offscreen resources from being destroyed if we don't have a context.

TEST=try, run demos locally
BUG=61441

Review URL: http://codereview.chromium.org/4246001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64940 0039d316-1c4b-4281-b951-d872f2087c98
parent a0895fdd
No related merge requests found
...@@ -203,6 +203,10 @@ class Texture { ...@@ -203,6 +203,10 @@ class Texture {
// destroying this object. // destroying this object.
void Destroy(); void Destroy();
// Invalidate the texture. This can be used when a context is lost and it is
// not possible to make it current in order to free the resource.
void Invalidate();
GLuint id() const { GLuint id() const {
return id_; return id_;
} }
...@@ -234,6 +238,10 @@ class RenderBuffer { ...@@ -234,6 +238,10 @@ class RenderBuffer {
// this object. // this object.
void Destroy(); void Destroy();
// Invalidate the render buffer. This can be used when a context is lost and
// it is not possible to make it current in order to free the resource.
void Invalidate();
GLuint id() const { GLuint id() const {
return id_; return id_;
} }
...@@ -267,6 +275,10 @@ class FrameBuffer { ...@@ -267,6 +275,10 @@ class FrameBuffer {
// this object. // this object.
void Destroy(); void Destroy();
// Invalidate the frame buffer. This can be used when a context is lost and it
// is not possible to make it current in order to free the resource.
void Invalidate();
// See glCheckFramebufferStatusEXT. // See glCheckFramebufferStatusEXT.
GLenum CheckStatus(); GLenum CheckStatus();
...@@ -1369,6 +1381,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, ...@@ -1369,6 +1381,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// used as the destination for multi-sample resolves. // used as the destination for multi-sample resolves.
scoped_ptr<FrameBuffer> offscreen_saved_frame_buffer_; scoped_ptr<FrameBuffer> offscreen_saved_frame_buffer_;
scoped_ptr<Texture> offscreen_saved_color_texture_; scoped_ptr<Texture> offscreen_saved_color_texture_;
GLenum offscreen_saved_color_format_;
scoped_ptr<Callback0::Type> swap_buffers_callback_; scoped_ptr<Callback0::Type> swap_buffers_callback_;
...@@ -1540,6 +1553,10 @@ void Texture::Destroy() { ...@@ -1540,6 +1553,10 @@ void Texture::Destroy() {
} }
} }
void Texture::Invalidate() {
id_ = 0;
}
RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder) RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder)
: decoder_(decoder), : decoder_(decoder),
id_(0) { id_(0) {
...@@ -1593,6 +1610,10 @@ void RenderBuffer::Destroy() { ...@@ -1593,6 +1610,10 @@ void RenderBuffer::Destroy() {
} }
} }
void RenderBuffer::Invalidate() {
id_ = 0;
}
FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder) FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder)
: decoder_(decoder), : decoder_(decoder),
id_(0) { id_(0) {
...@@ -1649,6 +1670,10 @@ void FrameBuffer::Destroy() { ...@@ -1649,6 +1670,10 @@ void FrameBuffer::Destroy() {
} }
} }
void FrameBuffer::Invalidate() {
id_ = 0;
}
GLenum FrameBuffer::CheckStatus() { GLenum FrameBuffer::CheckStatus() {
DCHECK_NE(id_, 0u); DCHECK_NE(id_, 0u);
ScopedGLErrorSuppressor suppressor(decoder_); ScopedGLErrorSuppressor suppressor(decoder_);
...@@ -1688,6 +1713,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) ...@@ -1688,6 +1713,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
offscreen_target_depth_format_(0), offscreen_target_depth_format_(0),
offscreen_target_stencil_format_(0), offscreen_target_stencil_format_(0),
offscreen_target_samples_(0), offscreen_target_samples_(0),
offscreen_saved_color_format_(0),
current_decoder_error_(error::kNoError), current_decoder_error_(error::kNoError),
use_shader_translator_(true), use_shader_translator_(true),
validators_(group_->feature_info()->validators()), validators_(group_->feature_info()->validators()),
...@@ -1840,6 +1866,9 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context, ...@@ -1840,6 +1866,9 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context,
} }
} }
offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
GL_RGBA : GL_RGB;
// Create the target frame buffer. This is the one that the client renders // Create the target frame buffer. This is the one that the client renders
// directly to. // directly to.
offscreen_target_frame_buffer_.reset(new FrameBuffer(this)); offscreen_target_frame_buffer_.reset(new FrameBuffer(this));
...@@ -2276,8 +2305,9 @@ bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() { ...@@ -2276,8 +2305,9 @@ bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() {
} }
if (parent_ || IsOffscreenBufferMultisampled()) { if (parent_ || IsOffscreenBufferMultisampled()) {
offscreen_saved_color_texture_->AllocateStorage(pending_offscreen_size_, DCHECK(offscreen_saved_color_format_);
GL_RGBA); offscreen_saved_color_texture_->AllocateStorage(
pending_offscreen_size_, offscreen_saved_color_format_);
offscreen_saved_frame_buffer_->AttachRenderTexture( offscreen_saved_frame_buffer_->AttachRenderTexture(
offscreen_saved_color_texture_.get()); offscreen_saved_color_texture_.get());
...@@ -2343,7 +2373,10 @@ bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, ...@@ -2343,7 +2373,10 @@ bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
void GLES2DecoderImpl::Destroy() { void GLES2DecoderImpl::Destroy() {
bool have_context = context_.get() && MakeCurrent(); bool have_context = context_.get() && MakeCurrent();
group_->set_have_context(have_context);
if (group_.get())
group_->set_have_context(have_context);
if (have_context) { if (have_context) {
if (attrib_0_buffer_id_) { if (attrib_0_buffer_id_) {
glDeleteBuffersARB(1, &attrib_0_buffer_id_); glDeleteBuffersARB(1, &attrib_0_buffer_id_);
...@@ -2364,40 +2397,20 @@ void GLES2DecoderImpl::Destroy() { ...@@ -2364,40 +2397,20 @@ void GLES2DecoderImpl::Destroy() {
glDeleteFramebuffersEXT(1, &copy_texture_to_parent_texture_fb_); glDeleteFramebuffersEXT(1, &copy_texture_to_parent_texture_fb_);
} }
if (offscreen_target_frame_buffer_.get()) { if (offscreen_target_frame_buffer_.get())
offscreen_target_frame_buffer_->Destroy(); offscreen_target_frame_buffer_->Destroy();
offscreen_target_frame_buffer_.reset(); if (offscreen_target_color_texture_.get())
}
if (offscreen_target_color_texture_.get()) {
offscreen_target_color_texture_->Destroy(); offscreen_target_color_texture_->Destroy();
offscreen_target_color_texture_.reset(); if (offscreen_target_color_render_buffer_.get())
}
if (offscreen_target_color_render_buffer_.get()) {
offscreen_target_color_render_buffer_->Destroy(); offscreen_target_color_render_buffer_->Destroy();
offscreen_target_color_render_buffer_.reset(); if (offscreen_target_depth_render_buffer_.get())
}
if (offscreen_target_depth_render_buffer_.get()) {
offscreen_target_depth_render_buffer_->Destroy(); offscreen_target_depth_render_buffer_->Destroy();
offscreen_target_depth_render_buffer_.reset(); if (offscreen_target_stencil_render_buffer_.get())
}
if (offscreen_target_stencil_render_buffer_.get()) {
offscreen_target_stencil_render_buffer_->Destroy(); offscreen_target_stencil_render_buffer_->Destroy();
offscreen_target_stencil_render_buffer_.reset(); if (offscreen_saved_frame_buffer_.get())
}
if (offscreen_saved_frame_buffer_.get()) {
offscreen_saved_frame_buffer_->Destroy(); offscreen_saved_frame_buffer_->Destroy();
offscreen_saved_frame_buffer_.reset(); if (offscreen_saved_color_texture_.get())
}
if (offscreen_saved_color_texture_.get()) {
offscreen_saved_color_texture_->Destroy(); offscreen_saved_color_texture_->Destroy();
offscreen_saved_color_texture_.reset();
}
// must release the ContextGroup before destroying the context as its // must release the ContextGroup before destroying the context as its
// destructor uses GL. // destructor uses GL.
...@@ -2405,7 +2418,30 @@ void GLES2DecoderImpl::Destroy() { ...@@ -2405,7 +2418,30 @@ void GLES2DecoderImpl::Destroy() {
context_->Destroy(); context_->Destroy();
context_.reset(); context_.reset();
} } else {
if (offscreen_target_frame_buffer_.get())
offscreen_target_frame_buffer_->Invalidate();
if (offscreen_target_color_texture_.get())
offscreen_target_color_texture_->Invalidate();
if (offscreen_target_color_render_buffer_.get())
offscreen_target_color_render_buffer_->Invalidate();
if (offscreen_target_depth_render_buffer_.get())
offscreen_target_depth_render_buffer_->Invalidate();
if (offscreen_target_stencil_render_buffer_.get())
offscreen_target_stencil_render_buffer_->Invalidate();
if (offscreen_saved_frame_buffer_.get())
offscreen_saved_frame_buffer_->Invalidate();
if (offscreen_saved_color_texture_.get())
offscreen_saved_color_texture_->Invalidate();
}
offscreen_target_frame_buffer_.reset();
offscreen_target_color_texture_.reset();
offscreen_target_color_render_buffer_.reset();
offscreen_target_depth_render_buffer_.reset();
offscreen_target_stencil_render_buffer_.reset();
offscreen_saved_frame_buffer_.reset();
offscreen_saved_color_texture_.reset();
} }
void GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { void GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment