diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-03 19:07:05 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-03 19:07:05 +0000 |
commit | 978720676b6f998a7422cf7ffe5be23d98b696e0 (patch) | |
tree | 589565d88b68db2cb06302c7dd5a831d23900692 /gpu | |
parent | a0895fdd6424d60fb7e232e0799a04a33259563c (diff) | |
download | chromium_src-978720676b6f998a7422cf7ffe5be23d98b696e0.zip chromium_src-978720676b6f998a7422cf7ffe5be23d98b696e0.tar.gz chromium_src-978720676b6f998a7422cf7ffe5be23d98b696e0.tar.bz2 |
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
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 98 |
1 files changed, 67 insertions, 31 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 7f3bac22..4d2cf89 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -203,6 +203,10 @@ class Texture { // destroying this object. 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 { return id_; } @@ -234,6 +238,10 @@ class RenderBuffer { // this object. 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 { return id_; } @@ -267,6 +275,10 @@ class FrameBuffer { // this object. 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. GLenum CheckStatus(); @@ -1369,6 +1381,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // used as the destination for multi-sample resolves. scoped_ptr<FrameBuffer> offscreen_saved_frame_buffer_; scoped_ptr<Texture> offscreen_saved_color_texture_; + GLenum offscreen_saved_color_format_; scoped_ptr<Callback0::Type> swap_buffers_callback_; @@ -1540,6 +1553,10 @@ void Texture::Destroy() { } } +void Texture::Invalidate() { + id_ = 0; +} + RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder) : decoder_(decoder), id_(0) { @@ -1593,6 +1610,10 @@ void RenderBuffer::Destroy() { } } +void RenderBuffer::Invalidate() { + id_ = 0; +} + FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder) : decoder_(decoder), id_(0) { @@ -1649,6 +1670,10 @@ void FrameBuffer::Destroy() { } } +void FrameBuffer::Invalidate() { + id_ = 0; +} + GLenum FrameBuffer::CheckStatus() { DCHECK_NE(id_, 0u); ScopedGLErrorSuppressor suppressor(decoder_); @@ -1688,6 +1713,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) offscreen_target_depth_format_(0), offscreen_target_stencil_format_(0), offscreen_target_samples_(0), + offscreen_saved_color_format_(0), current_decoder_error_(error::kNoError), use_shader_translator_(true), validators_(group_->feature_info()->validators()), @@ -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 // directly to. offscreen_target_frame_buffer_.reset(new FrameBuffer(this)); @@ -2276,8 +2305,9 @@ bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() { } if (parent_ || IsOffscreenBufferMultisampled()) { - offscreen_saved_color_texture_->AllocateStorage(pending_offscreen_size_, - GL_RGBA); + DCHECK(offscreen_saved_color_format_); + offscreen_saved_color_texture_->AllocateStorage( + pending_offscreen_size_, offscreen_saved_color_format_); offscreen_saved_frame_buffer_->AttachRenderTexture( offscreen_saved_color_texture_.get()); @@ -2343,7 +2373,10 @@ bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, void GLES2DecoderImpl::Destroy() { 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 (attrib_0_buffer_id_) { glDeleteBuffersARB(1, &attrib_0_buffer_id_); @@ -2364,40 +2397,20 @@ void GLES2DecoderImpl::Destroy() { glDeleteFramebuffersEXT(1, ©_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_.reset(); - } - - if (offscreen_target_color_texture_.get()) { + if (offscreen_target_color_texture_.get()) 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_.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_.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_.reset(); - } - - if (offscreen_saved_frame_buffer_.get()) { + if (offscreen_saved_frame_buffer_.get()) 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_.reset(); - } // must release the ContextGroup before destroying the context as its // destructor uses GL. @@ -2405,7 +2418,30 @@ void GLES2DecoderImpl::Destroy() { context_->Destroy(); 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) { |