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

Unified Diff: content/browser/compositor/reflector_impl.cc

Issue 228083002: Make ReflectorImpl use mailboxes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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: content/browser/compositor/reflector_impl.cc
diff --git a/content/browser/compositor/reflector_impl.cc b/content/browser/compositor/reflector_impl.cc
index 428aaad4105cee636b9a6fab236f2c9365a157c6..528237c1d2a9220330d635eda0d42fd36ec23e35 100644
--- a/content/browser/compositor/reflector_impl.cc
+++ b/content/browser/compositor/reflector_impl.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/location.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
+#include "content/browser/compositor/owned_mailbox.h"
#include "content/common/gpu/client/gl_helper.h"
#include "ui/compositor/layer.h"
@@ -17,67 +18,71 @@ ReflectorImpl::ReflectorImpl(
ui::Layer* mirroring_layer,
IDMap<BrowserCompositorOutputSurface>* output_surface_map,
int surface_id)
- : texture_id_(0),
- texture_size_(mirrored_compositor->size()),
- output_surface_map_(output_surface_map),
+ : output_surface_map_(output_surface_map),
+ output_surface_(NULL),
+ impl_thread_texture_id_(0),
+ needs_set_mailbox_(true),
mirrored_compositor_(mirrored_compositor),
- mirroring_compositor_(mirroring_layer->GetCompositor()),
mirroring_layer_(mirroring_layer),
impl_message_loop_(ui::Compositor::GetCompositorMessageLoop()),
main_message_loop_(base::MessageLoopProxy::current()),
surface_id_(surface_id) {
- impl_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&ReflectorImpl::InitOnImplThread, this));
+ GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
+ main_thread_mailbox_ = new OwnedMailbox(helper);
+ impl_message_loop_->PostTask(FROM_HERE,
+ base::Bind(&ReflectorImpl::InitOnImplThread,
+ this,
+ main_thread_mailbox_->holder()));
}
-void ReflectorImpl::InitOnImplThread() {
+void ReflectorImpl::InitOnImplThread(const gpu::MailboxHolder& mailbox_holder) {
// Ignore if the reflector was shutdown before
// initialized, or it's already initialized.
if (!output_surface_map_ || gl_helper_.get())
return;
+ impl_thread_mailbox_holder_ = mailbox_holder;
+
BrowserCompositorOutputSurface* source_surface =
output_surface_map_->Lookup(surface_id_);
// Skip if the source surface isn't ready yet. This will be
- // initiailze when the source surface becomes ready.
+ // initialized when the source surface becomes ready.
if (!source_surface)
return;
- AttachToOutputSurfaceOnImplThread(source_surface);
- // The shared texture doesn't have the data, so invokes full redraw
- // now.
- main_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
- scoped_refptr<ReflectorImpl>(this)));
+ AttachToOutputSurfaceOnImplThread(impl_thread_mailbox_holder_,
+ source_surface);
}
-void ReflectorImpl::OnSourceSurfaceReady(int surface_id) {
- DCHECK_EQ(surface_id_, surface_id);
- InitOnImplThread();
+void ReflectorImpl::OnSourceSurfaceReady(
+ BrowserCompositorOutputSurface* source_surface) {
+ AttachToOutputSurfaceOnImplThread(impl_thread_mailbox_holder_,
+ source_surface);
}
void ReflectorImpl::Shutdown() {
- mirroring_compositor_ = NULL;
+ main_thread_mailbox_ = NULL;
+ mirroring_layer_->SetShowPaintedContent();
mirroring_layer_ = NULL;
- {
- base::AutoLock lock(texture_lock_);
- texture_id_ = 0;
- }
- shared_texture_ = NULL;
impl_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
}
+void ReflectorImpl::DetachFromOutputSurface() {
+ DCHECK(output_surface_);
+ output_surface_->SetReflector(NULL);
+ DCHECK(impl_thread_texture_id_);
+ gl_helper_->DeleteTexture(impl_thread_texture_id_);
+ impl_thread_texture_id_ = 0;
+ gl_helper_.reset();
+ output_surface_ = NULL;
+}
+
void ReflectorImpl::ShutdownOnImplThread() {
- BrowserCompositorOutputSurface* output_surface =
- output_surface_map_->Lookup(surface_id_);
- if (output_surface)
- output_surface->SetReflector(NULL);
+ if (output_surface_)
+ DetachFromOutputSurface();
output_surface_map_ = NULL;
- gl_helper_.reset();
// The instance must be deleted on main thread.
main_message_loop_->PostTask(
FROM_HERE,
@@ -87,119 +92,113 @@ void ReflectorImpl::ShutdownOnImplThread() {
void ReflectorImpl::ReattachToOutputSurfaceFromMainThread(
BrowserCompositorOutputSurface* output_surface) {
+ GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
+ main_thread_mailbox_ = new OwnedMailbox(helper);
+ needs_set_mailbox_ = true;
impl_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::AttachToOutputSurfaceOnImplThread,
- this, output_surface));
+ this,
+ main_thread_mailbox_->holder(),
+ output_surface));
}
void ReflectorImpl::OnMirroringCompositorResized() {
- mirroring_compositor_->ScheduleFullRedraw();
-}
-
-void ReflectorImpl::OnLostResources() {
- mirroring_layer_->SetShowPaintedContent();
-}
-
-void ReflectorImpl::OnReshape(gfx::Size size) {
- if (texture_size_ == size)
- return;
- texture_size_ = size;
- {
- base::AutoLock lock(texture_lock_);
- if (texture_id_) {
- gl_helper_->ResizeTexture(texture_id_, size);
- gl_helper_->Flush();
- }
- }
- main_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&ReflectorImpl::UpdateTextureSizeOnMainThread,
- this->AsWeakPtr(),
- texture_size_));
+ mirroring_layer_->SchedulePaint(mirroring_layer_->bounds());
}
void ReflectorImpl::OnSwapBuffers() {
- {
- base::AutoLock lock(texture_lock_);
- if (texture_id_) {
- gl_helper_->CopyTextureFullImage(texture_id_, texture_size_);
- gl_helper_->Flush();
- }
+ gfx::Size size = output_surface_->SurfaceSize();
+ if (impl_thread_texture_id_) {
+ gl_helper_->CopyTextureFullImage(impl_thread_texture_id_, size);
+ gl_helper_->Flush();
}
main_message_loop_->PostTask(
FROM_HERE,
- base::Bind(&ReflectorImpl::FullRedrawOnMainThread,
- this->AsWeakPtr(),
- texture_size_));
+ base::Bind(
+ &ReflectorImpl::FullRedrawOnMainThread, this->AsWeakPtr(), size));
}
void ReflectorImpl::OnPostSubBuffer(gfx::Rect rect) {
- {
- base::AutoLock lock(texture_lock_);
- if (texture_id_) {
- gl_helper_->CopyTextureSubImage(texture_id_, rect);
- gl_helper_->Flush();
- }
+ if (impl_thread_texture_id_) {
+ gl_helper_->CopyTextureSubImage(impl_thread_texture_id_, rect);
+ gl_helper_->Flush();
}
main_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
this->AsWeakPtr(),
- texture_size_,
+ output_surface_->SurfaceSize(),
rect));
}
-void ReflectorImpl::CreateSharedTextureOnMainThread(gfx::Size size) {
- {
- base::AutoLock lock(texture_lock_);
- texture_id_ =
- ImageTransportFactory::GetInstance()->GetGLHelper()->CreateTexture();
- shared_texture_ =
- ImageTransportFactory::GetInstance()->CreateOwnedTexture(
- size, 1.0f, texture_id_);
- ImageTransportFactory::GetInstance()->GetGLHelper()->Flush();
- }
- mirroring_layer_->SetExternalTexture(shared_texture_.get());
- FullRedrawOnMainThread(size);
-}
-
ReflectorImpl::~ReflectorImpl() {
// Make sure the reflector is deleted on main thread.
DCHECK_EQ(main_message_loop_.get(),
base::MessageLoopProxy::current().get());
}
+static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox,
+ unsigned int sync_point,
+ bool is_lost) {
+ mailbox->UpdateSyncPoint(sync_point);
+}
+
void ReflectorImpl::AttachToOutputSurfaceOnImplThread(
+ const gpu::MailboxHolder& mailbox_holder,
BrowserCompositorOutputSurface* output_surface) {
+ if (output_surface == output_surface_)
+ return;
+ if (output_surface_)
+ DetachFromOutputSurface();
+ output_surface_ = output_surface;
output_surface->context_provider()->BindToCurrentThread();
gl_helper_.reset(
new GLHelper(output_surface->context_provider()->ContextGL(),
output_surface->context_provider()->ContextSupport()));
+ impl_thread_texture_id_ = gl_helper_->ConsumeMailboxToTexture(
+ mailbox_holder.mailbox, mailbox_holder.sync_point);
+ gl_helper_->ResizeTexture(impl_thread_texture_id_,
+ output_surface->SurfaceSize());
+ gl_helper_->Flush();
output_surface->SetReflector(this);
+ // The texture doesn't have the data, so invokes full redraw now.
main_message_loop_->PostTask(
FROM_HERE,
- base::Bind(&ReflectorImpl::CreateSharedTextureOnMainThread,
- this->AsWeakPtr(),
- texture_size_));
+ base::Bind(&ReflectorImpl::FullRedrawContentOnMainThread,
+ scoped_refptr<ReflectorImpl>(this)));
}
void ReflectorImpl::UpdateTextureSizeOnMainThread(gfx::Size size) {
- if (!mirroring_layer_)
+ if (!mirroring_layer_ || !main_thread_mailbox_ ||
+ main_thread_mailbox_->mailbox().IsZero())
danakj 2014/04/08 16:08:01 I'm not sure where this method is all called, but
piman 2014/04/08 23:17:46 It can't fail in ReattachToOutputSurfaceFromMainTh
return;
+ if (needs_set_mailbox_) {
+ mirroring_layer_->SetTextureMailbox(
+ cc::TextureMailbox(main_thread_mailbox_->holder()),
+ cc::SingleReleaseCallback::Create(
+ base::Bind(ReleaseMailbox, main_thread_mailbox_)),
+ size);
+ needs_set_mailbox_ = false;
+ } else if (size != texture_size_) {
danakj 2014/04/08 16:08:01 This texture_size_ is only here to prevent extra c
piman 2014/04/08 23:17:46 I wanted to avoid full layer invalidations if the
+ mirroring_layer_->SetTextureSize(size);
+ } else {
+ return;
+ }
mirroring_layer_->SetBounds(gfx::Rect(size));
+ texture_size_ = size;
}
void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) {
- if (!mirroring_compositor_)
+ if (!mirroring_layer_)
return;
UpdateTextureSizeOnMainThread(size);
- mirroring_compositor_->ScheduleFullRedraw();
+ mirroring_layer_->SchedulePaint(mirroring_layer_->bounds());
}
void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size,
gfx::Rect rect) {
- if (!mirroring_compositor_)
+ if (!mirroring_layer_)
return;
UpdateTextureSizeOnMainThread(size);
// Flip the coordinates to compositor's one.

Powered by Google App Engine
This is Rietveld 408576698