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

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

Issue 1912833002: 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: Fix test. Created 4 years, 8 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
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 c9e8470b6cca2e031b61a22bbd12e737b48a5c55..a929aa00cd22875858e0e116632b2f76919ba5fe 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -593,7 +593,10 @@ 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 ReleaseSurface() 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;
@@ -1994,6 +1997,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_;
@@ -4067,6 +4097,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();
@@ -4205,11 +4236,23 @@ void GLES2DecoderImpl::SetSurface(
RestoreCurrentFramebufferBindings();
}
-void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
+void GLES2DecoderImpl::ReleaseSurface() {
+ if (!context_.get())
+ return;
+ if (WasContextLost()) {
+ DLOG(ERROR) << " GLES2DecoderImpl: Trying to release lost context.";
+ return;
+ }
+ context_->ReleaseCurrent(surface_.get());
+ surface_ = nullptr;
+}
+
+void GLES2DecoderImpl::TakeFrontBuffer(const Mailbox& mailbox) {
if (!offscreen_saved_color_texture_.get()) {
- LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
+ LOG(ERROR) << "Called TakeFrontBuffer on a non-offscreen context";
piman 2016/04/26 01:54:01 nit: DLOG
erikchen 2016/04/27 16:31:23 Done.
return;
}
+
if (!offscreen_saved_color_texture_info_.get()) {
GLuint service_id = offscreen_saved_color_texture_->id();
offscreen_saved_color_texture_info_ = TextureRef::Create(
@@ -4218,8 +4261,93 @@ 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;
+ }
+
+ NOTREACHED();
piman 2016/04/26 01:54:01 nit: Not NOTREACHED(), this could be reached from
erikchen 2016/04/27 16:31:23 This seems like the perfect place for NOTREACHED()
piman 2016/04/27 23:00:58 I insist :) This is consistent in GPU code. DCHECK
erikchen 2016/04/27 23:59:24 Point taken. Thanks for the example. Switched to a
+}
+
+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();
+ }
+
+ std::remove_if(saved_back_textures_.begin(), saved_back_textures_.end(),
+ [](const SavedBackTexture& saved_back_texture) {
+ return !saved_back_texture.in_use;
+ });
+}
+
+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) {
@@ -12715,6 +12843,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(

Powered by Google App Engine
This is Rietveld 408576698