Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 1943513002: [Reland 1] Pepper takes ownership of a mailbox before passing it to the texture layer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments from sunnyps and piman. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_decoder.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder_mock.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index d4d0fab085fbfcc7d9713bf5b20bb2eb8a8152c1..88c2ee623bc951ad7a22dfe8360babb71c1cc853 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -593,7 +593,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
const std::vector<int32_t>& attribs) override;
void Destroy(bool have_context) override;
void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
- void ProduceFrontBuffer(const Mailbox& mailbox) override;
+ void TakeFrontBuffer(const Mailbox& mailbox) override;
+ void ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
void UpdateParentTextureInfo();
bool MakeCurrent() override;
@@ -2007,6 +2008,33 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
scoped_refptr<TextureRef>
offscreen_saved_color_texture_info_;
+ // When a client requests ownership of the swapped front buffer, all
+ // information is saved in this structure, and |in_use| is set to true. When a
+ // client releases ownership, |in_use| is set to false.
+ //
+ // An instance of this struct, with |in_use| = false may be reused instead of
+ // making a new BackTexture.
+ struct SavedBackTexture {
+ std::unique_ptr<BackTexture> back_texture;
+ scoped_refptr<TextureRef> texture_ref;
+ bool in_use;
+ };
+ std::vector<SavedBackTexture> saved_back_textures_;
+
+ // If there's a SavedBackTexture that's not in use, takes that. Otherwise,
+ // generates a new back texture.
+ void CreateBackTexture();
+ size_t create_back_texture_count_for_test_ = 0;
+
+ // Releases all saved BackTextures that are not in use by a client.
+ void ReleaseNotInUseBackTextures();
+
+ // Releases all saved BackTextures.
+ void ReleaseAllBackTextures();
+
+ size_t GetSavedBackTextureCountForTest() override;
+ size_t GetCreatedBackTextureCountForTest() override;
+
// The copy that is used as the destination for multi-sample resolves.
std::unique_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
std::unique_ptr<BackTexture> offscreen_resolved_color_texture_;
@@ -4081,6 +4109,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
offscreen_saved_color_texture_->Invalidate();
offscreen_saved_color_texture_info_ = NULL;
}
+ ReleaseAllBackTextures();
if (have_context) {
if (copy_texture_CHROMIUM_.get()) {
copy_texture_CHROMIUM_->Destroy();
@@ -4219,11 +4248,12 @@ void GLES2DecoderImpl::SetSurface(
RestoreCurrentFramebufferBindings();
}
-void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
+void GLES2DecoderImpl::TakeFrontBuffer(const Mailbox& mailbox) {
if (!offscreen_saved_color_texture_.get()) {
- LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
+ DLOG(ERROR) << "Called TakeFrontBuffer on a non-offscreen context";
return;
}
+
if (!offscreen_saved_color_texture_info_.get()) {
GLuint service_id = offscreen_saved_color_texture_->id();
offscreen_saved_color_texture_info_ = TextureRef::Create(
@@ -4232,8 +4262,94 @@ void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
GL_TEXTURE_2D);
UpdateParentTextureInfo();
}
+
mailbox_manager()->ProduceTexture(
mailbox, offscreen_saved_color_texture_info_->texture());
+
+ // Save the BackTexture and TextureRef.
+ SavedBackTexture save;
+ save.back_texture.swap(offscreen_saved_color_texture_);
+ save.texture_ref = offscreen_saved_color_texture_info_;
+ offscreen_saved_color_texture_info_ = nullptr;
+ save.in_use = true;
+ saved_back_textures_.push_back(std::move(save));
+
+ CreateBackTexture();
+}
+
+void GLES2DecoderImpl::ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) {
+ Texture* texture = mailbox_manager()->ConsumeTexture(mailbox);
+ for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end();
+ ++it) {
+ if (texture != it->texture_ref->texture())
+ continue;
+
+ if (is_lost || it->back_texture->size() != offscreen_size_) {
+ it->back_texture->Invalidate();
+ saved_back_textures_.erase(it);
+ return;
+ }
+
+ it->in_use = false;
+ return;
+ }
+
+ DLOG(ERROR) << "Attempting to return a frontbuffer that was not saved.";
+}
+
+void GLES2DecoderImpl::CreateBackTexture() {
+ for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end();
+ ++it) {
+ if (it->in_use)
+ continue;
+
+ if (it->back_texture->size() != offscreen_size_)
+ continue;
+ offscreen_saved_color_texture_ = std::move(it->back_texture);
+ offscreen_saved_color_texture_info_ = it->texture_ref;
+ saved_back_textures_.erase(it);
+ return;
+ }
+
+ ++create_back_texture_count_for_test_;
+ offscreen_saved_color_texture_.reset(
+ new BackTexture(memory_tracker(), &state_));
+ offscreen_saved_color_texture_->Create();
+ offscreen_saved_color_texture_->AllocateStorage(
+ offscreen_size_, offscreen_saved_color_format_, false);
+ offscreen_saved_frame_buffer_->AttachRenderTexture(
+ offscreen_saved_color_texture_.get());
+}
+
+void GLES2DecoderImpl::ReleaseNotInUseBackTextures() {
+ for (auto& saved_back_texture : saved_back_textures_) {
+ if (!saved_back_texture.in_use)
+ saved_back_texture.back_texture->Invalidate();
+ }
+
+ auto to_remove =
+ std::remove_if(saved_back_textures_.begin(), saved_back_textures_.end(),
+ [](const SavedBackTexture& saved_back_texture) {
+ return !saved_back_texture.in_use;
+ });
+ saved_back_textures_.erase(to_remove, saved_back_textures_.end());
+}
+
+void GLES2DecoderImpl::ReleaseAllBackTextures() {
+ for (auto& saved_back_texture : saved_back_textures_) {
+ // The texture will be destroyed by texture_ref's destructor.
+ DCHECK(saved_back_texture.texture_ref);
+ saved_back_texture.back_texture->Invalidate();
+ }
+ saved_back_textures_.clear();
+}
+
+size_t GLES2DecoderImpl::GetSavedBackTextureCountForTest() {
+ return saved_back_textures_.size();
+}
+
+size_t GLES2DecoderImpl::GetCreatedBackTextureCountForTest() {
+ return create_back_texture_count_for_test_;
}
bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
@@ -12786,6 +12902,10 @@ void GLES2DecoderImpl::DoSwapBuffers() {
glFinish();
}
+ // The size has changed, so none of the cached BackTextures are useful
+ // anymore.
+ ReleaseNotInUseBackTextures();
+
// Allocate the offscreen saved color texture.
DCHECK(offscreen_saved_color_format_);
offscreen_saved_color_texture_->AllocateStorage(
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_decoder.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698