OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 // Overridden from GLES2Decoder. | 589 // Overridden from GLES2Decoder. |
590 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, | 590 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, |
591 const scoped_refptr<gfx::GLContext>& context, | 591 const scoped_refptr<gfx::GLContext>& context, |
592 bool offscreen, | 592 bool offscreen, |
593 const gfx::Size& offscreen_size, | 593 const gfx::Size& offscreen_size, |
594 const DisallowedFeatures& disallowed_features, | 594 const DisallowedFeatures& disallowed_features, |
595 const std::vector<int32_t>& attribs) override; | 595 const std::vector<int32_t>& attribs) override; |
596 void Destroy(bool have_context) override; | 596 void Destroy(bool have_context) override; |
597 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override; | 597 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override; |
598 void ReleaseSurface() override; | 598 void ReleaseSurface() override; |
599 void ProduceFrontBuffer(const Mailbox& mailbox) override; | 599 void TakeFrontBuffer(const Mailbox& mailbox) override; |
| 600 void ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override; |
600 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override; | 601 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override; |
601 void UpdateParentTextureInfo(); | 602 void UpdateParentTextureInfo(); |
602 bool MakeCurrent() override; | 603 bool MakeCurrent() override; |
603 GLES2Util* GetGLES2Util() override { return &util_; } | 604 GLES2Util* GetGLES2Util() override { return &util_; } |
604 gfx::GLContext* GetGLContext() override { return context_.get(); } | 605 gfx::GLContext* GetGLContext() override { return context_.get(); } |
605 ContextGroup* GetContextGroup() override { return group_.get(); } | 606 ContextGroup* GetContextGroup() override { return group_.get(); } |
606 Capabilities GetCapabilities() override; | 607 Capabilities GetCapabilities() override; |
607 void RestoreState(const ContextState* prev_state) override; | 608 void RestoreState(const ContextState* prev_state) override; |
608 | 609 |
609 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); } | 610 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); } |
(...skipping 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2056 GLenum offscreen_target_stencil_format_; | 2057 GLenum offscreen_target_stencil_format_; |
2057 GLsizei offscreen_target_samples_; | 2058 GLsizei offscreen_target_samples_; |
2058 GLboolean offscreen_target_buffer_preserved_; | 2059 GLboolean offscreen_target_buffer_preserved_; |
2059 | 2060 |
2060 // The copy that is saved when SwapBuffers is called. | 2061 // The copy that is saved when SwapBuffers is called. |
2061 std::unique_ptr<BackFramebuffer> offscreen_saved_frame_buffer_; | 2062 std::unique_ptr<BackFramebuffer> offscreen_saved_frame_buffer_; |
2062 std::unique_ptr<BackTexture> offscreen_saved_color_texture_; | 2063 std::unique_ptr<BackTexture> offscreen_saved_color_texture_; |
2063 scoped_refptr<TextureRef> | 2064 scoped_refptr<TextureRef> |
2064 offscreen_saved_color_texture_info_; | 2065 offscreen_saved_color_texture_info_; |
2065 | 2066 |
| 2067 // When a client requests ownership of the swapped front buffer, all |
| 2068 // information is saved in this structure, and |in_use| is set to true. When a |
| 2069 // client releases ownership, |in_use| is set to false. |
| 2070 // |
| 2071 // An instance of this struct, with |in_use| = false may be reused instead of |
| 2072 // making a new BackTexture. |
| 2073 struct SavedBackTexture { |
| 2074 std::unique_ptr<BackTexture> back_texture; |
| 2075 scoped_refptr<TextureRef> texture_ref; |
| 2076 bool in_use; |
| 2077 }; |
| 2078 std::vector<SavedBackTexture> saved_back_textures_; |
| 2079 |
| 2080 // If there's a SavedBackTexture that's not in use, takes that. Otherwise, |
| 2081 // generates a new back texture. |
| 2082 void CreateBackTexture(); |
| 2083 size_t create_back_texture_count_for_test_ = 0; |
| 2084 |
| 2085 // Releases all saved BackTextures that are not in use by a client. |
| 2086 void ReleaseNotInUseBackTextures(); |
| 2087 |
| 2088 // Releases all saved BackTextures. |
| 2089 void ReleaseAllBackTextures(); |
| 2090 |
| 2091 size_t GetSavedBackTextureCountForTest() override; |
| 2092 size_t GetCreatedBackTextureCountForTest() override; |
| 2093 |
2066 // The copy that is used as the destination for multi-sample resolves. | 2094 // The copy that is used as the destination for multi-sample resolves. |
2067 std::unique_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_; | 2095 std::unique_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_; |
2068 std::unique_ptr<BackTexture> offscreen_resolved_color_texture_; | 2096 std::unique_ptr<BackTexture> offscreen_resolved_color_texture_; |
2069 GLenum offscreen_saved_color_format_; | 2097 GLenum offscreen_saved_color_format_; |
2070 | 2098 |
2071 std::unique_ptr<QueryManager> query_manager_; | 2099 std::unique_ptr<QueryManager> query_manager_; |
2072 | 2100 |
2073 std::unique_ptr<VertexArrayManager> vertex_array_manager_; | 2101 std::unique_ptr<VertexArrayManager> vertex_array_manager_; |
2074 | 2102 |
2075 std::unique_ptr<ImageManager> image_manager_; | 2103 std::unique_ptr<ImageManager> image_manager_; |
(...skipping 2117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4193 state_.default_transform_feedback = nullptr; | 4221 state_.default_transform_feedback = nullptr; |
4194 state_.indexed_uniform_buffer_bindings = nullptr; | 4222 state_.indexed_uniform_buffer_bindings = nullptr; |
4195 | 4223 |
4196 if (offscreen_saved_color_texture_info_.get()) { | 4224 if (offscreen_saved_color_texture_info_.get()) { |
4197 DCHECK(offscreen_target_color_texture_); | 4225 DCHECK(offscreen_target_color_texture_); |
4198 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(), | 4226 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(), |
4199 offscreen_saved_color_texture_->id()); | 4227 offscreen_saved_color_texture_->id()); |
4200 offscreen_saved_color_texture_->Invalidate(); | 4228 offscreen_saved_color_texture_->Invalidate(); |
4201 offscreen_saved_color_texture_info_ = NULL; | 4229 offscreen_saved_color_texture_info_ = NULL; |
4202 } | 4230 } |
| 4231 ReleaseAllBackTextures(); |
4203 if (have_context) { | 4232 if (have_context) { |
4204 if (copy_texture_CHROMIUM_.get()) { | 4233 if (copy_texture_CHROMIUM_.get()) { |
4205 copy_texture_CHROMIUM_->Destroy(); | 4234 copy_texture_CHROMIUM_->Destroy(); |
4206 copy_texture_CHROMIUM_.reset(); | 4235 copy_texture_CHROMIUM_.reset(); |
4207 } | 4236 } |
4208 | 4237 |
4209 clear_framebuffer_blit_.reset(); | 4238 clear_framebuffer_blit_.reset(); |
4210 | 4239 |
4211 if (state_.current_program.get()) { | 4240 if (state_.current_program.get()) { |
4212 program_manager()->UnuseProgram(shader_manager(), | 4241 program_manager()->UnuseProgram(shader_manager(), |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4350 if (!context_.get()) | 4379 if (!context_.get()) |
4351 return; | 4380 return; |
4352 if (WasContextLost()) { | 4381 if (WasContextLost()) { |
4353 DLOG(ERROR) << " GLES2DecoderImpl: Trying to release lost context."; | 4382 DLOG(ERROR) << " GLES2DecoderImpl: Trying to release lost context."; |
4354 return; | 4383 return; |
4355 } | 4384 } |
4356 context_->ReleaseCurrent(surface_.get()); | 4385 context_->ReleaseCurrent(surface_.get()); |
4357 surface_ = nullptr; | 4386 surface_ = nullptr; |
4358 } | 4387 } |
4359 | 4388 |
4360 void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) { | 4389 void GLES2DecoderImpl::TakeFrontBuffer(const Mailbox& mailbox) { |
4361 if (!offscreen_saved_color_texture_.get()) { | 4390 if (!offscreen_saved_color_texture_.get()) { |
4362 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context"; | 4391 DLOG(ERROR) << "Called TakeFrontBuffer on a non-offscreen context"; |
4363 return; | 4392 return; |
4364 } | 4393 } |
| 4394 |
4365 if (!offscreen_saved_color_texture_info_.get()) { | 4395 if (!offscreen_saved_color_texture_info_.get()) { |
4366 GLuint service_id = offscreen_saved_color_texture_->id(); | 4396 GLuint service_id = offscreen_saved_color_texture_->id(); |
4367 offscreen_saved_color_texture_info_ = TextureRef::Create( | 4397 offscreen_saved_color_texture_info_ = TextureRef::Create( |
4368 texture_manager(), 0, service_id); | 4398 texture_manager(), 0, service_id); |
4369 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(), | 4399 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(), |
4370 GL_TEXTURE_2D); | 4400 GL_TEXTURE_2D); |
4371 UpdateParentTextureInfo(); | 4401 UpdateParentTextureInfo(); |
4372 } | 4402 } |
| 4403 |
4373 mailbox_manager()->ProduceTexture( | 4404 mailbox_manager()->ProduceTexture( |
4374 mailbox, offscreen_saved_color_texture_info_->texture()); | 4405 mailbox, offscreen_saved_color_texture_info_->texture()); |
| 4406 |
| 4407 // Save the BackTexture and TextureRef. |
| 4408 SavedBackTexture save; |
| 4409 save.back_texture.swap(offscreen_saved_color_texture_); |
| 4410 save.texture_ref = offscreen_saved_color_texture_info_; |
| 4411 offscreen_saved_color_texture_info_ = nullptr; |
| 4412 save.in_use = true; |
| 4413 saved_back_textures_.push_back(std::move(save)); |
| 4414 |
| 4415 CreateBackTexture(); |
| 4416 } |
| 4417 |
| 4418 void GLES2DecoderImpl::ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) { |
| 4419 Texture* texture = mailbox_manager()->ConsumeTexture(mailbox); |
| 4420 for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end(); |
| 4421 ++it) { |
| 4422 if (texture != it->texture_ref->texture()) |
| 4423 continue; |
| 4424 |
| 4425 if (is_lost || it->back_texture->size() != offscreen_size_) { |
| 4426 it->back_texture->Invalidate(); |
| 4427 saved_back_textures_.erase(it); |
| 4428 return; |
| 4429 } |
| 4430 |
| 4431 it->in_use = false; |
| 4432 return; |
| 4433 } |
| 4434 |
| 4435 DLOG(ERROR) << "Attempting to return a frontbuffer that was not saved."; |
| 4436 } |
| 4437 |
| 4438 void GLES2DecoderImpl::CreateBackTexture() { |
| 4439 for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end(); |
| 4440 ++it) { |
| 4441 if (it->in_use) |
| 4442 continue; |
| 4443 |
| 4444 if (it->back_texture->size() != offscreen_size_) |
| 4445 continue; |
| 4446 offscreen_saved_color_texture_ = std::move(it->back_texture); |
| 4447 offscreen_saved_color_texture_info_ = it->texture_ref; |
| 4448 saved_back_textures_.erase(it); |
| 4449 return; |
| 4450 } |
| 4451 |
| 4452 ++create_back_texture_count_for_test_; |
| 4453 offscreen_saved_color_texture_.reset( |
| 4454 new BackTexture(memory_tracker(), &state_)); |
| 4455 offscreen_saved_color_texture_->Create(); |
| 4456 offscreen_saved_color_texture_->AllocateStorage( |
| 4457 offscreen_size_, offscreen_saved_color_format_, false); |
| 4458 offscreen_saved_frame_buffer_->AttachRenderTexture( |
| 4459 offscreen_saved_color_texture_.get()); |
| 4460 } |
| 4461 |
| 4462 void GLES2DecoderImpl::ReleaseNotInUseBackTextures() { |
| 4463 for (auto& saved_back_texture : saved_back_textures_) { |
| 4464 if (!saved_back_texture.in_use) |
| 4465 saved_back_texture.back_texture->Invalidate(); |
| 4466 } |
| 4467 |
| 4468 auto to_remove = |
| 4469 std::remove_if(saved_back_textures_.begin(), saved_back_textures_.end(), |
| 4470 [](const SavedBackTexture& saved_back_texture) { |
| 4471 return !saved_back_texture.in_use; |
| 4472 }); |
| 4473 saved_back_textures_.erase(to_remove, saved_back_textures_.end()); |
| 4474 } |
| 4475 |
| 4476 void GLES2DecoderImpl::ReleaseAllBackTextures() { |
| 4477 for (auto& saved_back_texture : saved_back_textures_) { |
| 4478 // The texture will be destroyed by texture_ref's destructor. |
| 4479 DCHECK(saved_back_texture.texture_ref); |
| 4480 saved_back_texture.back_texture->Invalidate(); |
| 4481 } |
| 4482 saved_back_textures_.clear(); |
| 4483 } |
| 4484 |
| 4485 size_t GLES2DecoderImpl::GetSavedBackTextureCountForTest() { |
| 4486 return saved_back_textures_.size(); |
| 4487 } |
| 4488 |
| 4489 size_t GLES2DecoderImpl::GetCreatedBackTextureCountForTest() { |
| 4490 return create_back_texture_count_for_test_; |
4375 } | 4491 } |
4376 | 4492 |
4377 bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { | 4493 bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { |
4378 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); | 4494 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); |
4379 if (!is_offscreen) { | 4495 if (!is_offscreen) { |
4380 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called " | 4496 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called " |
4381 << " with an onscreen framebuffer."; | 4497 << " with an onscreen framebuffer."; |
4382 return false; | 4498 return false; |
4383 } | 4499 } |
4384 | 4500 |
(...skipping 8666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13051 "width", offscreen_size_.width(), "height", offscreen_size_.height()); | 13167 "width", offscreen_size_.width(), "height", offscreen_size_.height()); |
13052 if (offscreen_size_ != offscreen_saved_color_texture_->size()) { | 13168 if (offscreen_size_ != offscreen_saved_color_texture_->size()) { |
13053 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557, | 13169 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557, |
13054 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will | 13170 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will |
13055 // fix this. | 13171 // fix this. |
13056 if (workarounds().needs_offscreen_buffer_workaround) { | 13172 if (workarounds().needs_offscreen_buffer_workaround) { |
13057 offscreen_saved_frame_buffer_->Create(); | 13173 offscreen_saved_frame_buffer_->Create(); |
13058 glFinish(); | 13174 glFinish(); |
13059 } | 13175 } |
13060 | 13176 |
| 13177 // The size has changed, so none of the cached BackTextures are useful |
| 13178 // anymore. |
| 13179 ReleaseNotInUseBackTextures(); |
| 13180 |
13061 // Allocate the offscreen saved color texture. | 13181 // Allocate the offscreen saved color texture. |
13062 DCHECK(offscreen_saved_color_format_); | 13182 DCHECK(offscreen_saved_color_format_); |
13063 offscreen_saved_color_texture_->AllocateStorage( | 13183 offscreen_saved_color_texture_->AllocateStorage( |
13064 offscreen_size_, offscreen_saved_color_format_, false); | 13184 offscreen_size_, offscreen_saved_color_format_, false); |
13065 | 13185 |
13066 offscreen_saved_frame_buffer_->AttachRenderTexture( | 13186 offscreen_saved_frame_buffer_->AttachRenderTexture( |
13067 offscreen_saved_color_texture_.get()); | 13187 offscreen_saved_color_texture_.get()); |
13068 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) { | 13188 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) { |
13069 if (offscreen_saved_frame_buffer_->CheckStatus() != | 13189 if (offscreen_saved_frame_buffer_->CheckStatus() != |
13070 GL_FRAMEBUFFER_COMPLETE) { | 13190 GL_FRAMEBUFFER_COMPLETE) { |
(...skipping 3616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16687 } | 16807 } |
16688 | 16808 |
16689 // Include the auto-generated part of this file. We split this because it means | 16809 // Include the auto-generated part of this file. We split this because it means |
16690 // we can easily edit the non-auto generated parts right here in this file | 16810 // we can easily edit the non-auto generated parts right here in this file |
16691 // instead of having to edit some template or the code generator. | 16811 // instead of having to edit some template or the code generator. |
16692 #include "base/macros.h" | 16812 #include "base/macros.h" |
16693 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 16813 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
16694 | 16814 |
16695 } // namespace gles2 | 16815 } // namespace gles2 |
16696 } // namespace gpu | 16816 } // namespace gpu |
OLD | NEW |