diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-09 22:14:17 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-09 22:14:17 +0000 |
commit | 4508b15bef1094ccf68771f40f7b61013fee43ff (patch) | |
tree | a465e41f18421640c86ebb5326885397eb3b9e79 | |
parent | a4139bb350549d2fefed191f2fb3c98fdfa42d41 (diff) | |
download | chromium_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
21 files changed, 304 insertions, 428 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_; diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index ce3e7c0..cc0763d 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -1490,10 +1490,6 @@ bool RenderWidgetHostViewAura::HasAcceleratedSurface( return false; } -void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor( - scoped_refptr<ui::Texture>) { -} - // static void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResult( const gfx::Size& dst_size_in_pixel, diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 4177295..b74f7f3 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -477,10 +477,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAura // Called prior to removing |window_| from a WindowEventDispatcher. void RemovingFromRootWindow(); - // Called after commit for the last reference to the texture going away - // after it was released as the frontbuffer. - void SetSurfaceNotInUseByCompositor(scoped_refptr<ui::Texture>); - // Called after async thumbnailer task completes. Scales and crops the result // of the copy. static void CopyFromCompositingSurfaceHasResult( diff --git a/ui/aura/bench/bench_main.cc b/ui/aura/bench/bench_main.cc index ff0d32d..337da8d 100644 --- a/ui/aura/bench/bench_main.cc +++ b/ui/aura/bench/bench_main.cc @@ -138,36 +138,15 @@ class BenchCompositorObserver : public ui::CompositorObserver { DISALLOW_COPY_AND_ASSIGN(BenchCompositorObserver); }; -class WebGLTexture : public ui::Texture { - public: - WebGLTexture(gpu::gles2::GLES2Interface* gl, const gfx::Size& size) - : ui::Texture(false, size, 1.0f), - gl_(gl), - texture_id_(0u) { - gl->GenTextures(1, &texture_id_); - gl->BindTexture(GL_TEXTURE_2D, texture_id_); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - } - - virtual unsigned int PrepareTexture() OVERRIDE { - return texture_id_; - } - - private: - virtual ~WebGLTexture() { - gl_->DeleteTextures(1, &texture_id_); - } - - gpu::gles2::GLES2Interface* gl_; - GLuint texture_id_; - - DISALLOW_COPY_AND_ASSIGN(WebGLTexture); -}; +void ReturnMailbox(scoped_refptr<cc::ContextProvider> context_provider, + GLuint texture, + GLuint sync_point, + bool is_lost) { + gpu::gles2::GLES2Interface* gl = context_provider->ContextGL(); + gl->WaitSyncPointCHROMIUM(sync_point); + gl->DeleteTextures(1, &texture); + gl->ShallowFlushCHROMIUM(); +} // A benchmark that adds a texture layer that is updated every frame. class WebGLBench : public BenchCompositorObserver { @@ -177,7 +156,6 @@ class WebGLBench : public BenchCompositorObserver { parent_(parent), webgl_(ui::LAYER_TEXTURED), compositor_(compositor), - texture_(), fbo_(0), do_draw_(true) { CommandLine* command_line = CommandLine::ForCurrentProcess(); @@ -205,23 +183,47 @@ class WebGLBench : public BenchCompositorObserver { context_provider_ = ui::ContextFactory::GetInstance()->SharedMainThreadContextProvider(); gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); - texture_ = new WebGLTexture(gl, bounds.size()); + GLuint texture = 0; + gl->GenTextures(1, &texture); + gl->BindTexture(GL_TEXTURE_2D, texture); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl->TexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA, + width, + height, + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + NULL); + gpu::Mailbox mailbox; + gl->GenMailboxCHROMIUM(mailbox.name); + gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); + gl->GenFramebuffers(1, &fbo_); - compositor->AddObserver(this); - webgl_.SetExternalTexture(texture_.get()); gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_); gl->FramebufferTexture2D( - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, texture_->PrepareTexture(), 0); + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); gl->ClearColor(0.f, 1.f, 0.f, 1.f); gl->Clear(GL_COLOR_BUFFER_BIT); gl->Flush(); + + GLuint sync_point = gl->InsertSyncPointCHROMIUM(); + webgl_.SetTextureMailbox( + cc::TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point), + cc::SingleReleaseCallback::Create( + base::Bind(ReturnMailbox, context_provider_, texture)), + bounds.size()); + compositor->AddObserver(this); } virtual ~WebGLBench() { - context_provider_->ContextGL()->DeleteFramebuffers(1, &fbo_); webgl_.SetShowPaintedContent(); - texture_ = NULL; + gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); + gl->DeleteFramebuffers(1, &fbo_); compositor_->RemoveObserver(this); } @@ -232,7 +234,6 @@ class WebGLBench : public BenchCompositorObserver { gl->Clear(GL_COLOR_BUFFER_BIT); gl->Flush(); } - webgl_.SetExternalTexture(texture_.get()); webgl_.SchedulePaint(gfx::Rect(webgl_.bounds().size())); compositor_->ScheduleDraw(); } @@ -242,7 +243,6 @@ class WebGLBench : public BenchCompositorObserver { Layer webgl_; Compositor* compositor_; scoped_refptr<cc::ContextProvider> context_provider_; - scoped_refptr<WebGLTexture> texture_; // The FBO that is used to render to the texture. unsigned int fbo_; diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index d8da38d..d0f6715 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc @@ -63,19 +63,6 @@ void ContextFactory::SetInstance(ContextFactory* instance) { g_context_factory = instance; } -Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor) - : size_(size), - flipped_(flipped), - device_scale_factor_(device_scale_factor) { -} - -Texture::~Texture() { -} - -gpu::Mailbox Texture::Produce() { - return gpu::Mailbox(); -} - CompositorLock::CompositorLock(Compositor* compositor) : compositor_(compositor) { base::MessageLoop::current()->PostDelayedTask( diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index 7b4ce6a..3a1530b 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h @@ -103,39 +103,6 @@ class COMPOSITOR_EXPORT ContextFactory { virtual bool DoesCreateTestContexts() = 0; }; -// Texture provide an abstraction over the external texture that can be passed -// to a layer. -class COMPOSITOR_EXPORT Texture : public base::RefCounted<Texture> { - public: - Texture(bool flipped, const gfx::Size& size, float device_scale_factor); - - bool flipped() const { return flipped_; } - gfx::Size size() const { return size_; } - float device_scale_factor() const { return device_scale_factor_; } - - virtual unsigned int PrepareTexture() = 0; - - // Replaces the texture with the texture from the specified mailbox. - virtual void Consume(const gpu::Mailbox& mailbox, - const gfx::Size& new_size) {} - - // Moves the texture into the mailbox and returns the mailbox name. - // The texture must have been previously consumed from a mailbox. - virtual gpu::Mailbox Produce(); - - protected: - virtual ~Texture(); - gfx::Size size_; // in pixel - - private: - friend class base::RefCounted<Texture>; - - bool flipped_; - float device_scale_factor_; - - DISALLOW_COPY_AND_ASSIGN(Texture); -}; - // This class represents a lock on the compositor, that can be used to prevent // commits to the compositor tree while we're waiting for an asynchronous // event. The typical use case is when waiting for a renderer to produce a frame diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index e4161d8..bb94860 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc @@ -501,49 +501,35 @@ void Layer::SwitchCCLayerForTest() { content_layer_ = new_layer; } -void Layer::SetExternalTexture(Texture* texture) { - DCHECK(texture); - - // Hold a ref to the old |Texture| until we have updated all - // compositor references to the texture id that it holds. - scoped_refptr<ui::Texture> old_texture = texture_; - - DCHECK_EQ(type_, LAYER_TEXTURED); - DCHECK(!solid_color_layer_.get()); - texture_ = texture; - if (!texture_layer_.get()) { - scoped_refptr<cc::TextureLayer> new_layer = cc::TextureLayer::Create(this); - new_layer->SetFlipped(texture_->flipped()); - SwitchToLayer(new_layer); - texture_layer_ = new_layer; - } - RecomputeDrawsContentAndUVRect(); -} - void Layer::SetTextureMailbox( const cc::TextureMailbox& mailbox, scoped_ptr<cc::SingleReleaseCallback> release_callback, - float scale_factor) { + gfx::Size texture_size_in_dip) { DCHECK_EQ(type_, LAYER_TEXTURED); DCHECK(!solid_color_layer_.get()); - texture_ = NULL; - if (!texture_layer_.get() || !texture_layer_->uses_mailbox()) { + DCHECK(mailbox.IsValid()); + DCHECK(release_callback); + if (!texture_layer_) { scoped_refptr<cc::TextureLayer> new_layer = cc::TextureLayer::CreateForMailbox(this); - new_layer->SetFlipped(false); + new_layer->SetFlipped(true); SwitchToLayer(new_layer); texture_layer_ = new_layer; } - texture_layer_->SetTextureMailbox(mailbox, release_callback.Pass()); + if (mailbox_release_callback_) + mailbox_release_callback_->Run(0, false); + mailbox_release_callback_ = release_callback.Pass(); mailbox_ = mailbox; - mailbox_scale_factor_ = scale_factor; - RecomputeDrawsContentAndUVRect(); + SetTextureSize(texture_size_in_dip); } -cc::TextureMailbox Layer::GetTextureMailbox(float* scale_factor) { - if (scale_factor) - *scale_factor = mailbox_scale_factor_; - return mailbox_; +void Layer::SetTextureSize(gfx::Size texture_size_in_dip) { + DCHECK(texture_layer_.get()); + if (frame_size_in_dip_ == texture_size_in_dip) + return; + frame_size_in_dip_ = texture_size_in_dip; + RecomputeDrawsContentAndUVRect(); + texture_layer_->SetNeedsDisplay(); } void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider, @@ -555,7 +541,7 @@ void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider, SwitchToLayer(new_layer); delegated_renderer_layer_ = new_layer; - delegated_frame_size_in_dip_ = frame_size_in_dip; + frame_size_in_dip_ = frame_size_in_dip; RecomputeDrawsContentAndUVRect(); } @@ -572,15 +558,17 @@ void Layer::SetShowPaintedContent() { content_layer_ = new_layer; mailbox_ = cc::TextureMailbox(); - texture_ = NULL; - + if (mailbox_release_callback_) { + mailbox_release_callback_->Run(0, false); + mailbox_release_callback_.reset(); + } RecomputeDrawsContentAndUVRect(); } void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); } bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) { - if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !texture_.get())) + if (type_ == LAYER_SOLID_COLOR || (!delegate_ && !mailbox_.IsValid())) return false; damaged_region_.op(invalid_rect.x(), @@ -599,7 +587,7 @@ void Layer::ScheduleDraw() { } void Layer::SendDamagedRects() { - if ((delegate_ || texture_.get()) && !damaged_region_.isEmpty()) { + if ((delegate_ || mailbox_.IsValid()) && !damaged_region_.isEmpty()) { for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) { const SkIRect& sk_damaged = iter.rect(); gfx::Rect damaged( @@ -671,15 +659,19 @@ void Layer::PaintContents(SkCanvas* sk_canvas, bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_; } unsigned Layer::PrepareTexture() { - DCHECK(texture_layer_.get()); - return texture_->PrepareTexture(); + NOTREACHED(); + return 0; } bool Layer::PrepareTextureMailbox( cc::TextureMailbox* mailbox, scoped_ptr<cc::SingleReleaseCallback>* release_callback, bool use_shared_memory) { - return false; + if (!mailbox_release_callback_) + return false; + *mailbox = mailbox_; + *release_callback = mailbox_release_callback_.Pass(); + return true; } void Layer::SetForceRenderSurface(bool force) { @@ -946,29 +938,16 @@ void Layer::RecomputeDrawsContentAndUVRect() { DCHECK(cc_layer_); gfx::Size size(bounds_.size()); if (texture_layer_.get()) { - gfx::Size texture_size; - if (!texture_layer_->uses_mailbox()) { - DCHECK(texture_.get()); - float texture_scale_factor = 1.0f / texture_->device_scale_factor(); - texture_size = gfx::ToFlooredSize( - gfx::ScaleSize(texture_->size(), texture_scale_factor)); - } else { - DCHECK(mailbox_.IsSharedMemory()); - float texture_scale_factor = 1.0f / mailbox_scale_factor_; - texture_size = gfx::ToFlooredSize( - gfx::ScaleSize(mailbox_.shared_memory_size(), texture_scale_factor)); - } - size.SetToMin(texture_size); - + size.SetToMin(frame_size_in_dip_); gfx::PointF uv_top_left(0.f, 0.f); gfx::PointF uv_bottom_right( - static_cast<float>(size.width())/texture_size.width(), - static_cast<float>(size.height())/texture_size.height()); + static_cast<float>(size.width()) / frame_size_in_dip_.width(), + static_cast<float>(size.height()) / frame_size_in_dip_.height()); texture_layer_->SetUV(uv_top_left, uv_bottom_right); } else if (delegated_renderer_layer_.get()) { + size.SetToMin(frame_size_in_dip_); delegated_renderer_layer_->SetDisplaySize( - ConvertSizeToPixel(this, delegated_frame_size_in_dip_)); - size.SetToMin(delegated_frame_size_in_dip_); + ConvertSizeToPixel(this, frame_size_in_dip_)); } cc_layer_->SetBounds(ConvertSizeToPixel(this, size)); } diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index ed805bf..9224f37 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h @@ -48,7 +48,6 @@ namespace ui { class Compositor; class LayerAnimator; class LayerOwner; -class Texture; // Layer manages a texture, transform and a set of child Layers. Any View that // has enabled layers ends up creating a Layer to manage the texture. @@ -256,19 +255,12 @@ class COMPOSITOR_EXPORT Layer const std::string& name() const { return name_; } void set_name(const std::string& name) { name_ = name; } - const ui::Texture* texture() const { return texture_.get(); } - - // Assigns a new external texture. |texture| can be NULL to disable external - // updates. - void SetExternalTexture(ui::Texture* texture); - ui::Texture* external_texture() { return texture_.get(); } - // Set new TextureMailbox for this layer. Note that |mailbox| may hold a // shared memory resource or an actual mailbox for a texture. void SetTextureMailbox(const cc::TextureMailbox& mailbox, scoped_ptr<cc::SingleReleaseCallback> release_callback, - float scale_factor); - cc::TextureMailbox GetTextureMailbox(float* scale_factor); + gfx::Size texture_size_in_dip); + void SetTextureSize(gfx::Size texture_size_in_dip); // Begins showing delegated frames from the |frame_provider|. void SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider, @@ -414,8 +406,6 @@ class COMPOSITOR_EXPORT Layer Compositor* compositor_; - scoped_refptr<ui::Texture> texture_; - Layer* parent_; // This layer's children, in bottom-to-top stacking order. @@ -485,15 +475,16 @@ class COMPOSITOR_EXPORT Layer // A cached copy of |Compositor::device_scale_factor()|. float device_scale_factor_; - // A cached copy of the TextureMailbox given texture_layer_. + // The mailbox used by texture_layer_. cc::TextureMailbox mailbox_; - // Device scale factor in which mailbox_ was rendered in. - float mailbox_scale_factor_; + // The callback to release the mailbox. This is only set after + // SetTextureMailbox is called, before we give it to the TextureLayer. + scoped_ptr<cc::SingleReleaseCallback> mailbox_release_callback_; - // The size of the delegated frame in DIP, set when SetShowDelegatedContent - // was called. - gfx::Size delegated_frame_size_in_dip_; + // The size of the frame or texture in DIP, set when SetShowDelegatedContent + // or SetTextureMailbox was called. + gfx::Size frame_size_in_dip_; DISALLOW_COPY_AND_ASSIGN(Layer); }; diff --git a/ui/compositor/layer_owner_delegate.h b/ui/compositor/layer_owner_delegate.h index e5362d9..68ba92e 100644 --- a/ui/compositor/layer_owner_delegate.h +++ b/ui/compositor/layer_owner_delegate.h @@ -13,7 +13,7 @@ class Layer; // Called from RecreateLayer() after the new layer was created. old_layer is // the layer that will be returned to the caller of RecreateLayer, new_layer // will be the layer now used. Used when the layer has external content -// (SetExternalTexture / SetTextureMailbox / SetDelegatedFrame was called). +// (SetTextureMailbox / SetDelegatedFrame was called). class COMPOSITOR_EXPORT LayerOwnerDelegate { public: virtual void OnLayerRecreated(Layer* old_layer, Layer* new_layer) = 0; diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index 4c838a3..52051c1 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc @@ -642,17 +642,6 @@ class LayerWithNullDelegateTest : public LayerWithDelegateTest { DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest); }; -class FakeTexture : public Texture { - public: - FakeTexture(bool flipped, const gfx::Size& size, float device_scale_factor) - : Texture(flipped, size, device_scale_factor) {} - - virtual unsigned int PrepareTexture() OVERRIDE { return 0; } - - protected: - virtual ~FakeTexture() {} -}; - TEST_F(LayerWithNullDelegateTest, EscapedDebugNames) { scoped_ptr<Layer> layer(CreateLayer(LAYER_NOT_DRAWN)); std::string name = "\"\'\\/\b\f\n\r\t\n"; @@ -673,6 +662,10 @@ TEST_F(LayerWithNullDelegateTest, EscapedDebugNames) { EXPECT_EQ(name, roundtrip); } +void ReturnMailbox(bool* run, uint32 sync_point, bool is_lost) { + *run = true; +} + TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) { scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400))); @@ -689,9 +682,12 @@ TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) { cc::Layer* before_layer = l1->cc_layer(); - scoped_refptr<Texture> texture = - new FakeTexture(false, gfx::Size(10, 10), 1.f); - l1->SetExternalTexture(texture.get()); + bool callback1_run = false; + cc::TextureMailbox mailbox(gpu::Mailbox::Generate(), 0, 0); + l1->SetTextureMailbox(mailbox, + cc::SingleReleaseCallback::Create( + base::Bind(ReturnMailbox, &callback1_run)), + gfx::Size(1, 1)); EXPECT_NE(before_layer, l1->cc_layer()); @@ -701,6 +697,25 @@ TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) { EXPECT_TRUE(l1->cc_layer()->contents_opaque()); EXPECT_TRUE(l1->cc_layer()->force_render_surface()); EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree()); + EXPECT_FALSE(callback1_run); + + bool callback2_run = false; + mailbox = cc::TextureMailbox(gpu::Mailbox::Generate(), 0, 0); + l1->SetTextureMailbox(mailbox, + cc::SingleReleaseCallback::Create( + base::Bind(ReturnMailbox, &callback2_run)), + gfx::Size(1, 1)); + EXPECT_TRUE(callback1_run); + EXPECT_FALSE(callback2_run); + + l1->SetShowPaintedContent(); + EXPECT_EQ(gfx::PointF().ToString(), + l1->cc_layer()->anchor_point().ToString()); + EXPECT_TRUE(l1->cc_layer()->DrawsContent()); + EXPECT_TRUE(l1->cc_layer()->contents_opaque()); + EXPECT_TRUE(l1->cc_layer()->force_render_surface()); + EXPECT_TRUE(l1->cc_layer()->hide_layer_and_subtree()); + EXPECT_TRUE(callback2_run); } // Various visibile/drawn assertions. diff --git a/ui/views/view.cc b/ui/views/view.cc index dd09f88..6c9c3a1 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc @@ -1690,7 +1690,7 @@ std::string View::DoPrintViewGraph(bool first, View* view_with_children) { if (!parent_) result.append(", shape=box"); if (layer()) { - if (layer()->texture()) + if (layer()->has_external_content()) result.append(", color=green"); else result.append(", color=red"); |