summaryrefslogtreecommitdiffstats
path: root/content/browser/compositor
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-09 22:14:17 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-09 22:14:17 +0000
commit4508b15bef1094ccf68771f40f7b61013fee43ff (patch)
treea465e41f18421640c86ebb5326885397eb3b9e79 /content/browser/compositor
parenta4139bb350549d2fefed191f2fb3c98fdfa42d41 (diff)
downloadchromium_src-4508b15bef1094ccf68771f40f7b61013fee43ff.zip
chromium_src-4508b15bef1094ccf68771f40f7b61013fee43ff.tar.gz
chromium_src-4508b15bef1094ccf68771f40f7b61013fee43ff.tar.bz2
Make ReflectorImpl use mailboxes
- fixes ui::Layer::SetTextureMailbox to not be hard-coded for software frames. - adds a ui::Layer::SetTextureSize to update the size without sending a new mailbox (since it doesn't change). - entirely removes ui::Layer::SetExternalTexture and ui::Texture, and derived classes. - significantly changes the ReflectorImpl implementation: * an OwnedMailbox is created on the main thread, using the shared main thread context. * the mailbox is passed to the impl thread, that creates a texture out of it with the OutputSurface context, and does operations on that. * the mailbox is passed to the layer. * if the OutputSurface is recreated (assuming, after a lost context), the OwnedMailbox is recreated, and passed to the impl side again, together with the new surface. * the OwnedMailbox takes care of deleting the texture, whether because of a lost context, or when the ReflectorImpl is shut down. BUG=333408 R=danakj@chromium.org, oshima@chromium.org, sky@chromium.org Review URL: https://codereview.chromium.org/228083002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262836 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/compositor')
-rw-r--r--content/browser/compositor/browser_compositor_output_surface.cc12
-rw-r--r--content/browser/compositor/browser_compositor_output_surface.h1
-rw-r--r--content/browser/compositor/gpu_process_transport_factory.cc67
-rw-r--r--content/browser/compositor/gpu_process_transport_factory.h4
-rw-r--r--content/browser/compositor/image_transport_factory.h6
-rw-r--r--content/browser/compositor/image_transport_factory_browsertest.cc17
-rw-r--r--content/browser/compositor/no_transport_image_transport_factory.cc7
-rw-r--r--content/browser/compositor/no_transport_image_transport_factory.h4
-rw-r--r--content/browser/compositor/owned_mailbox.h1
-rw-r--r--content/browser/compositor/reflector_impl.cc243
-rw-r--r--content/browser/compositor/reflector_impl.h71
11 files changed, 189 insertions, 244 deletions
diff --git a/content/browser/compositor/browser_compositor_output_surface.cc b/content/browser/compositor/browser_compositor_output_surface.cc
index 6f82df4..b1cdd90 100644
--- a/content/browser/compositor/browser_compositor_output_surface.cc
+++ b/content/browser/compositor/browser_compositor_output_surface.cc
@@ -40,6 +40,9 @@ BrowserCompositorOutputSurface::BrowserCompositorOutputSurface(
BrowserCompositorOutputSurface::~BrowserCompositorOutputSurface() {
DCHECK(CalledOnValidThread());
+ if (reflector_)
+ reflector_->DetachFromOutputSurface();
+ DCHECK(!reflector_);
if (!HasClient())
return;
output_surface_map_->Remove(surface_id_);
@@ -62,18 +65,11 @@ bool BrowserCompositorOutputSurface::BindToClient(
output_surface_map_->AddWithID(this, surface_id_);
if (reflector_)
- reflector_->OnSourceSurfaceReady(surface_id_);
+ reflector_->OnSourceSurfaceReady(this);
vsync_manager_->AddObserver(this);
return true;
}
-void BrowserCompositorOutputSurface::Reshape(const gfx::Size& size,
- float scale_factor) {
- OutputSurface::Reshape(size, scale_factor);
- if (reflector_.get())
- reflector_->OnReshape(size);
-}
-
void BrowserCompositorOutputSurface::OnUpdateVSyncParameters(
base::TimeTicks timebase,
base::TimeDelta interval) {
diff --git a/content/browser/compositor/browser_compositor_output_surface.h b/content/browser/compositor/browser_compositor_output_surface.h
index 7c26b083..5f9378d 100644
--- a/content/browser/compositor/browser_compositor_output_surface.h
+++ b/content/browser/compositor/browser_compositor_output_surface.h
@@ -29,7 +29,6 @@ class CONTENT_EXPORT BrowserCompositorOutputSurface
// cc::OutputSurface implementation.
virtual bool BindToClient(cc::OutputSurfaceClient* client) OVERRIDE;
- virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE;
// ui::CompositorOutputSurface::Observer implementation.
virtual void OnUpdateVSyncParameters(base::TimeTicks timebase,
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 5ac65d9..e01a79b 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -57,55 +57,6 @@ struct GpuProcessTransportFactory::PerCompositorData {
scoped_refptr<ReflectorImpl> reflector;
};
-class OwnedTexture : public ui::Texture, ImageTransportFactoryObserver {
- public:
- OwnedTexture(const scoped_refptr<ContextProvider>& provider,
- const gfx::Size& size,
- float device_scale_factor,
- GLuint texture_id)
- : ui::Texture(true, size, device_scale_factor),
- provider_(provider),
- texture_id_(texture_id) {
- ImageTransportFactory::GetInstance()->AddObserver(this);
- }
-
- // ui::Texture overrides:
- virtual unsigned int PrepareTexture() OVERRIDE {
- // It's possible that we may have lost the context owning our
- // texture but not yet fired the OnLostResources callback, so poll to see if
- // it's still valid.
- if (provider_ && provider_->IsContextLost())
- texture_id_ = 0u;
- return texture_id_;
- }
-
- // ImageTransportFactory overrides:
- virtual void OnLostResources() OVERRIDE {
- DeleteTexture();
- provider_ = NULL;
- }
-
- protected:
- virtual ~OwnedTexture() {
- ImageTransportFactory::GetInstance()->RemoveObserver(this);
- DeleteTexture();
- }
-
- protected:
- void DeleteTexture() {
- if (texture_id_) {
- provider_->ContextGL()->DeleteTextures(1, &texture_id_);
- texture_id_ = 0;
- }
- }
-
- scoped_refptr<cc::ContextProvider> provider_;
- GLuint texture_id_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(OwnedTexture);
-};
-
GpuProcessTransportFactory::GpuProcessTransportFactory()
: callback_factory_(this), offscreen_content_bound_to_other_thread_(false) {
output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy(
@@ -233,12 +184,8 @@ scoped_refptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector(
PerCompositorData* data = per_compositor_data_[source];
DCHECK(data);
- if (data->reflector.get())
- RemoveObserver(data->reflector.get());
-
data->reflector = new ReflectorImpl(
source, target, &output_surface_map_, data->surface_id);
- AddObserver(data->reflector.get());
return data->reflector;
}
@@ -249,7 +196,6 @@ void GpuProcessTransportFactory::RemoveReflector(
PerCompositorData* data =
per_compositor_data_[reflector_impl->mirrored_compositor()];
DCHECK(data);
- RemoveObserver(reflector_impl);
data->reflector->Shutdown();
data->reflector = NULL;
}
@@ -290,19 +236,6 @@ gfx::GLSurfaceHandle GpuProcessTransportFactory::GetSharedSurfaceHandle() {
return handle;
}
-scoped_refptr<ui::Texture> GpuProcessTransportFactory::CreateOwnedTexture(
- const gfx::Size& size,
- float device_scale_factor,
- unsigned int texture_id) {
- scoped_refptr<cc::ContextProvider> provider =
- SharedMainThreadContextProvider();
- if (!provider.get())
- return NULL;
- scoped_refptr<OwnedTexture> image(new OwnedTexture(
- provider, size, device_scale_factor, texture_id));
- return image;
-}
-
GLHelper* GpuProcessTransportFactory::GetGLHelper() {
if (!gl_helper_ && !per_compositor_data_.empty()) {
scoped_refptr<cc::ContextProvider> provider =
diff --git a/content/browser/compositor/gpu_process_transport_factory.h b/content/browser/compositor/gpu_process_transport_factory.h
index 1e936d2..18f7f85 100644
--- a/content/browser/compositor/gpu_process_transport_factory.h
+++ b/content/browser/compositor/gpu_process_transport_factory.h
@@ -52,10 +52,6 @@ class GpuProcessTransportFactory
// ImageTransportFactory implementation.
virtual ui::ContextFactory* AsContextFactory() OVERRIDE;
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() OVERRIDE;
- virtual scoped_refptr<ui::Texture> CreateOwnedTexture(
- const gfx::Size& size,
- float device_scale_factor,
- unsigned int texture_id) OVERRIDE;
virtual GLHelper* GetGLHelper() OVERRIDE;
virtual void AddObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
virtual void RemoveObserver(
diff --git a/content/browser/compositor/image_transport_factory.h b/content/browser/compositor/image_transport_factory.h
index f14fb20..1c6912f 100644
--- a/content/browser/compositor/image_transport_factory.h
+++ b/content/browser/compositor/image_transport_factory.h
@@ -69,12 +69,6 @@ class CONTENT_EXPORT ImageTransportFactory {
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() = 0;
- // Creates a ui::Texture that deletes the GL texture when deleted.
- virtual scoped_refptr<ui::Texture> CreateOwnedTexture(
- const gfx::Size& size,
- float device_scale_factor,
- unsigned int texture_id) = 0;
-
// Gets a GLHelper instance, associated with the shared context. This
// GLHelper will get destroyed whenever the shared context is lost
// (ImageTransportFactoryObserver::OnLostResources is called).
diff --git a/content/browser/compositor/image_transport_factory_browsertest.cc b/content/browser/compositor/image_transport_factory_browsertest.cc
index fede399..d4792fb 100644
--- a/content/browser/compositor/image_transport_factory_browsertest.cc
+++ b/content/browser/compositor/image_transport_factory_browsertest.cc
@@ -5,6 +5,7 @@
#include "base/run_loop.h"
#include "cc/output/context_provider.h"
#include "content/browser/compositor/image_transport_factory.h"
+#include "content/browser/compositor/owned_mailbox.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/test/content_browser_test.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -38,15 +39,10 @@ IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest,
return;
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
- ui::ContextFactory* context_factory = ui::ContextFactory::GetInstance();
- gpu::gles2::GLES2Interface* gl =
- context_factory->SharedMainThreadContextProvider()->ContextGL();
- GLuint texture_id = 0;
- gl->GenTextures(1, &texture_id);
- scoped_refptr<ui::Texture> texture =
- factory->CreateOwnedTexture(gfx::Size(1, 1), 1.f, texture_id);
- ASSERT_TRUE(texture.get());
+ scoped_refptr<OwnedMailbox> mailbox =
+ new OwnedMailbox(factory->GetGLHelper());
+ EXPECT_FALSE(mailbox->mailbox().IsZero());
MockImageTransportFactoryObserver observer;
factory->AddObserver(&observer);
@@ -55,6 +51,9 @@ IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest,
EXPECT_CALL(observer, OnLostResources())
.WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
+ ui::ContextFactory* context_factory = ui::ContextFactory::GetInstance();
+ gpu::gles2::GLES2Interface* gl =
+ context_factory->SharedMainThreadContextProvider()->ContextGL();
gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
GL_INNOCENT_CONTEXT_RESET_ARB);
@@ -63,7 +62,7 @@ IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest,
gl->Flush();
run_loop.Run();
- EXPECT_EQ(0u, texture->PrepareTexture());
+ EXPECT_TRUE(mailbox->mailbox().IsZero());
factory->RemoveObserver(&observer);
}
diff --git a/content/browser/compositor/no_transport_image_transport_factory.cc b/content/browser/compositor/no_transport_image_transport_factory.cc
index fd56b68..d1c5951 100644
--- a/content/browser/compositor/no_transport_image_transport_factory.cc
+++ b/content/browser/compositor/no_transport_image_transport_factory.cc
@@ -26,13 +26,6 @@ NoTransportImageTransportFactory::GetSharedSurfaceHandle() {
return gfx::GLSurfaceHandle();
}
-scoped_refptr<ui::Texture> NoTransportImageTransportFactory::CreateOwnedTexture(
- const gfx::Size& size,
- float device_scale_factor,
- unsigned int texture_id) {
- return NULL;
-}
-
GLHelper* NoTransportImageTransportFactory::GetGLHelper() {
if (!gl_helper_) {
context_provider_ = context_factory_->SharedMainThreadContextProvider();
diff --git a/content/browser/compositor/no_transport_image_transport_factory.h b/content/browser/compositor/no_transport_image_transport_factory.h
index 1d72449..a0f6216 100644
--- a/content/browser/compositor/no_transport_image_transport_factory.h
+++ b/content/browser/compositor/no_transport_image_transport_factory.h
@@ -24,10 +24,6 @@ class NoTransportImageTransportFactory : public ImageTransportFactory {
// ImageTransportFactory implementation.
virtual ui::ContextFactory* AsContextFactory() OVERRIDE;
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() OVERRIDE;
- virtual scoped_refptr<ui::Texture> CreateOwnedTexture(
- const gfx::Size& size,
- float device_scale_factor,
- unsigned int texture_id) OVERRIDE;
virtual GLHelper* GetGLHelper() OVERRIDE;
virtual void AddObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
virtual void RemoveObserver(ImageTransportFactoryObserver* observer) OVERRIDE;
diff --git a/content/browser/compositor/owned_mailbox.h b/content/browser/compositor/owned_mailbox.h
index 6fc4258..3926c81 100644
--- a/content/browser/compositor/owned_mailbox.h
+++ b/content/browser/compositor/owned_mailbox.h
@@ -22,6 +22,7 @@ class CONTENT_EXPORT OwnedMailbox : public base::RefCounted<OwnedMailbox>,
public:
explicit OwnedMailbox(GLHelper* gl_helper);
+ const gpu::MailboxHolder& holder() const { return mailbox_holder_; }
const gpu::Mailbox& mailbox() const { return mailbox_holder_.mailbox; }
uint32 texture_id() const { return texture_id_; }
uint32 target() const { return mailbox_holder_.texture_target; }
diff --git a/content/browser/compositor/reflector_impl.cc b/content/browser/compositor/reflector_impl.cc
index 428aaad..14e992b 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
diff --git a/content/browser/compositor/reflector_impl.h b/content/browser/compositor/reflector_impl.h
index 82c1f46..e20e4b9 100644
--- a/content/browser/compositor/reflector_impl.h
+++ b/content/browser/compositor/reflector_impl.h
@@ -10,6 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "content/browser/compositor/image_transport_factory.h"
+#include "gpu/command_buffer/common/mailbox_holder.h"
#include "ui/compositor/reflector.h"
#include "ui/gfx/size.h"
@@ -24,12 +25,12 @@ class Layer;
namespace content {
+class OwnedMailbox;
class BrowserCompositorOutputSurface;
// A reflector implementation that copies the framebuffer content
// to the texture, then draw it onto the mirroring compositor.
-class ReflectorImpl : public ImageTransportFactoryObserver,
- public base::SupportsWeakPtr<ReflectorImpl>,
+class ReflectorImpl : public base::SupportsWeakPtr<ReflectorImpl>,
public ui::Reflector {
public:
ReflectorImpl(
@@ -39,10 +40,10 @@ class ReflectorImpl : public ImageTransportFactoryObserver,
int surface_id);
ui::Compositor* mirrored_compositor() {
- return mirrored_compositor_;
+ return GetMain().mirrored_compositor;
}
- void InitOnImplThread();
+ void InitOnImplThread(const gpu::MailboxHolder& mailbox_holder);
void Shutdown();
void ShutdownOnImplThread();
@@ -53,13 +54,6 @@ class ReflectorImpl : public ImageTransportFactoryObserver,
// ui::Reflector implementation.
virtual void OnMirroringCompositorResized() OVERRIDE;
- // ImageTransportFactoryObsever implementation.
- virtual void OnLostResources() OVERRIDE;
-
- // Called when the output surface's size has changed.
- // This must be called on ImplThread.
- void OnReshape(gfx::Size size);
-
// Called in |BrowserCompositorOutputSurface::SwapBuffers| to copy
// the full screen image to the |texture_id_|. This must be called
// on ImplThread.
@@ -78,12 +72,36 @@ class ReflectorImpl : public ImageTransportFactoryObserver,
// Called when the source surface is bound and available. This must
// be called on ImplThread.
- void OnSourceSurfaceReady(int surface_id);
+ void OnSourceSurfaceReady(BrowserCompositorOutputSurface* surface);
+
+ void DetachFromOutputSurface();
private:
+ struct MainThreadData {
+ MainThreadData(ui::Compositor* mirrored_compositor,
+ ui::Layer* mirroring_layer);
+ ~MainThreadData();
+ scoped_refptr<OwnedMailbox> mailbox;
+ bool needs_set_mailbox;
+ ui::Compositor* mirrored_compositor;
+ ui::Layer* mirroring_layer;
+ };
+
+ struct ImplThreadData {
+ explicit ImplThreadData(
+ IDMap<BrowserCompositorOutputSurface>* output_surface_map);
+ ~ImplThreadData();
+ IDMap<BrowserCompositorOutputSurface>* output_surface_map;
+ BrowserCompositorOutputSurface* output_surface;
+ scoped_ptr<GLHelper> gl_helper;
+ unsigned texture_id;
+ gpu::MailboxHolder mailbox_holder;
+ };
+
virtual ~ReflectorImpl();
void AttachToOutputSurfaceOnImplThread(
+ const gpu::MailboxHolder& mailbox_holder,
BrowserCompositorOutputSurface* surface);
void UpdateTextureSizeOnMainThread(gfx::Size size);
@@ -101,25 +119,16 @@ class ReflectorImpl : public ImageTransportFactoryObserver,
// so the ReflectorImpl gets deleted when the function returns.
static void DeleteOnMainThread(scoped_refptr<ReflectorImpl> reflector) {}
- // These variables are initialized on MainThread before
- // the reflector is attached to the output surface. Once
- // attached, they must be accessed only on ImplThraed unless
- // the context is lost. When the context is lost, these
- // will be re-ininitiailzed when the new output-surface
- // is created on MainThread.
- int texture_id_;
- base::Lock texture_lock_;
- gfx::Size texture_size_;
-
- // Must be accessed only on ImplThread.
- IDMap<BrowserCompositorOutputSurface>* output_surface_map_;
- scoped_ptr<GLHelper> gl_helper_;
-
- // Must be accessed only on MainThread.
- ui::Compositor* mirrored_compositor_;
- ui::Compositor* mirroring_compositor_;
- ui::Layer* mirroring_layer_;
- scoped_refptr<ui::Texture> shared_texture_;
+ MainThreadData& GetMain();
+ ImplThreadData& GetImpl();
+
+ // Must be accessed only on ImplThread, through GetImpl().
+ ImplThreadData impl_unsafe_;
+
+ // Must be accessed only on MainThread, through GetMain().
+ MainThreadData main_unsafe_;
+
+ // Can be accessed on both.
scoped_refptr<base::MessageLoopProxy> impl_message_loop_;
scoped_refptr<base::MessageLoopProxy> main_message_loop_;
int surface_id_;