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

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: rebase 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..14e992b939ac2145411a2f269d595ab16df5fd93 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,199 +18,227 @@ 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),
- mirrored_compositor_(mirrored_compositor),
- mirroring_compositor_(mirroring_layer->GetCompositor()),
- mirroring_layer_(mirroring_layer),
+ : impl_unsafe_(output_surface_map),
+ main_unsafe_(mirrored_compositor, mirroring_layer),
impl_message_loop_(ui::Compositor::GetCompositorMessageLoop()),
main_message_loop_(base::MessageLoopProxy::current()),
surface_id_(surface_id) {
+ GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
+ MainThreadData& main = GetMain();
+ main.mailbox = new OwnedMailbox(helper);
impl_message_loop_->PostTask(
FROM_HERE,
- base::Bind(&ReflectorImpl::InitOnImplThread, this));
+ base::Bind(
+ &ReflectorImpl::InitOnImplThread, this, main.mailbox->holder()));
}
-void ReflectorImpl::InitOnImplThread() {
+ReflectorImpl::MainThreadData::MainThreadData(
+ ui::Compositor* mirrored_compositor,
+ ui::Layer* mirroring_layer)
+ : needs_set_mailbox(true),
+ mirrored_compositor(mirrored_compositor),
+ mirroring_layer(mirroring_layer) {}
+
+ReflectorImpl::MainThreadData::~MainThreadData() {}
+
+ReflectorImpl::ImplThreadData::ImplThreadData(
+ IDMap<BrowserCompositorOutputSurface>* output_surface_map)
+ : output_surface_map(output_surface_map),
+ output_surface(NULL),
+ texture_id(0) {}
+
+ReflectorImpl::ImplThreadData::~ImplThreadData() {}
+
+ReflectorImpl::ImplThreadData& ReflectorImpl::GetImpl() {
+ DCHECK(impl_message_loop_->BelongsToCurrentThread());
+ return impl_unsafe_;
+}
+
+ReflectorImpl::MainThreadData& ReflectorImpl::GetMain() {
+ DCHECK(main_message_loop_->BelongsToCurrentThread());
+ return main_unsafe_;
+}
+
+void ReflectorImpl::InitOnImplThread(const gpu::MailboxHolder& mailbox_holder) {
+ ImplThreadData& impl = GetImpl();
// Ignore if the reflector was shutdown before
// initialized, or it's already initialized.
- if (!output_surface_map_ || gl_helper_.get())
+ if (!impl.output_surface_map || impl.gl_helper.get())
return;
+ impl.mailbox_holder = mailbox_holder;
+
BrowserCompositorOutputSurface* source_surface =
- output_surface_map_->Lookup(surface_id_);
+ impl.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.mailbox_holder, source_surface);
}
-void ReflectorImpl::OnSourceSurfaceReady(int surface_id) {
- DCHECK_EQ(surface_id_, surface_id);
- InitOnImplThread();
+void ReflectorImpl::OnSourceSurfaceReady(
+ BrowserCompositorOutputSurface* source_surface) {
+ ImplThreadData& impl = GetImpl();
+ AttachToOutputSurfaceOnImplThread(impl.mailbox_holder, source_surface);
}
void ReflectorImpl::Shutdown() {
- mirroring_compositor_ = NULL;
- mirroring_layer_ = NULL;
- {
- base::AutoLock lock(texture_lock_);
- texture_id_ = 0;
- }
- shared_texture_ = NULL;
+ MainThreadData& main = GetMain();
+ main.mailbox = NULL;
+ main.mirroring_layer->SetShowPaintedContent();
+ main.mirroring_layer = NULL;
impl_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
+ FROM_HERE, base::Bind(&ReflectorImpl::ShutdownOnImplThread, this));
+}
+
+void ReflectorImpl::DetachFromOutputSurface() {
+ ImplThreadData& impl = GetImpl();
+ DCHECK(impl.output_surface);
+ impl.output_surface->SetReflector(NULL);
+ DCHECK(impl.texture_id);
+ impl.gl_helper->DeleteTexture(impl.texture_id);
+ impl.texture_id = 0;
+ impl.gl_helper.reset();
+ impl.output_surface = NULL;
}
void ReflectorImpl::ShutdownOnImplThread() {
- BrowserCompositorOutputSurface* output_surface =
- output_surface_map_->Lookup(surface_id_);
- if (output_surface)
- output_surface->SetReflector(NULL);
- output_surface_map_ = NULL;
- gl_helper_.reset();
+ ImplThreadData& impl = GetImpl();
+ if (impl.output_surface)
+ DetachFromOutputSurface();
+ impl.output_surface_map = NULL;
// The instance must be deleted on main thread.
- main_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&ReflectorImpl::DeleteOnMainThread,
- scoped_refptr<ReflectorImpl>(this)));
+ main_message_loop_->PostTask(FROM_HERE,
+ base::Bind(&ReflectorImpl::DeleteOnMainThread,
+ scoped_refptr<ReflectorImpl>(this)));
}
void ReflectorImpl::ReattachToOutputSurfaceFromMainThread(
BrowserCompositorOutputSurface* output_surface) {
+ MainThreadData& main = GetMain();
+ GLHelper* helper = ImageTransportFactory::GetInstance()->GetGLHelper();
+ main.mailbox = new OwnedMailbox(helper);
+ main.needs_set_mailbox = true;
+ main.mirroring_layer->SetShowPaintedContent();
impl_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::AttachToOutputSurfaceOnImplThread,
- this, output_surface));
+ this,
+ main.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_));
+ MainThreadData& main = GetMain();
+ main.mirroring_layer->SchedulePaint(main.mirroring_layer->bounds());
}
void ReflectorImpl::OnSwapBuffers() {
- {
- base::AutoLock lock(texture_lock_);
- if (texture_id_) {
- gl_helper_->CopyTextureFullImage(texture_id_, texture_size_);
- gl_helper_->Flush();
- }
+ ImplThreadData& impl = GetImpl();
+ gfx::Size size = impl.output_surface->SurfaceSize();
+ if (impl.texture_id) {
+ impl.gl_helper->CopyTextureFullImage(impl.texture_id, size);
+ impl.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();
- }
+ ImplThreadData& impl = GetImpl();
+ if (impl.texture_id) {
+ impl.gl_helper->CopyTextureSubImage(impl.texture_id, rect);
+ impl.gl_helper->Flush();
}
main_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReflectorImpl::UpdateSubBufferOnMainThread,
this->AsWeakPtr(),
- texture_size_,
+ impl.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());
+ 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) {
+ ImplThreadData& impl = GetImpl();
+ if (output_surface == impl.output_surface)
+ return;
+ if (impl.output_surface)
+ DetachFromOutputSurface();
+ impl.output_surface = output_surface;
output_surface->context_provider()->BindToCurrentThread();
- gl_helper_.reset(
+ impl.gl_helper.reset(
new GLHelper(output_surface->context_provider()->ContextGL(),
output_surface->context_provider()->ContextSupport()));
+ impl.texture_id = impl.gl_helper->ConsumeMailboxToTexture(
+ mailbox_holder.mailbox, mailbox_holder.sync_point);
+ impl.gl_helper->ResizeTexture(impl.texture_id, output_surface->SurfaceSize());
+ impl.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_)
+ MainThreadData& main = GetMain();
+ if (!main.mirroring_layer || !main.mailbox ||
+ main.mailbox->mailbox().IsZero())
return;
- mirroring_layer_->SetBounds(gfx::Rect(size));
+ if (main.needs_set_mailbox) {
+ main.mirroring_layer->SetTextureMailbox(
+ cc::TextureMailbox(main.mailbox->holder()),
+ cc::SingleReleaseCallback::Create(
+ base::Bind(ReleaseMailbox, main.mailbox)),
+ size);
+ main.needs_set_mailbox = false;
+ } else {
+ main.mirroring_layer->SetTextureSize(size);
+ }
+ main.mirroring_layer->SetBounds(gfx::Rect(size));
}
void ReflectorImpl::FullRedrawOnMainThread(gfx::Size size) {
- if (!mirroring_compositor_)
+ MainThreadData& main = GetMain();
+ if (!main.mirroring_layer)
return;
UpdateTextureSizeOnMainThread(size);
- mirroring_compositor_->ScheduleFullRedraw();
+ main.mirroring_layer->SchedulePaint(main.mirroring_layer->bounds());
}
void ReflectorImpl::UpdateSubBufferOnMainThread(gfx::Size size,
gfx::Rect rect) {
- if (!mirroring_compositor_)
+ MainThreadData& main = GetMain();
+ if (!main.mirroring_layer)
return;
UpdateTextureSizeOnMainThread(size);
// Flip the coordinates to compositor's one.
int y = size.height() - rect.y() - rect.height();
gfx::Rect new_rect(rect.x(), y, rect.width(), rect.height());
- mirroring_layer_->SchedulePaint(new_rect);
+ main.mirroring_layer->SchedulePaint(new_rect);
}
void ReflectorImpl::FullRedrawContentOnMainThread() {
- mirrored_compositor_->ScheduleFullRedraw();
+ MainThreadData& main = GetMain();
+ main.mirrored_compositor->ScheduleFullRedraw();
}
} // namespace content
« no previous file with comments | « content/browser/compositor/reflector_impl.h ('k') | content/browser/renderer_host/render_widget_host_view_aura.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698