| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_COMPOSITOR_REFLECTOR_IMPL_H_ |
| #define CONTENT_BROWSER_COMPOSITOR_REFLECTOR_IMPL_H_ |
| |
| #include "base/id_map.h" |
| #include "base/memory/scoped_ptr.h" |
| #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" |
| |
| namespace base { class MessageLoopProxy; } |
| |
| namespace gfx { class Rect; } |
| |
| namespace ui { |
| class Compositor; |
| 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 base::SupportsWeakPtr<ReflectorImpl>, |
| public ui::Reflector { |
| public: |
| ReflectorImpl( |
| ui::Compositor* mirrored_compositor, |
| ui::Layer* mirroring_layer, |
| IDMap<BrowserCompositorOutputSurface>* output_surface_map, |
| base::MessageLoopProxy* compositor_thread_loop, |
| int surface_id); |
| |
| ui::Compositor* mirrored_compositor() { |
| return GetMain().mirrored_compositor; |
| } |
| |
| void InitOnImplThread(const gpu::MailboxHolder& mailbox_holder); |
| void Shutdown(); |
| void ShutdownOnImplThread(); |
| |
| // Post a task to attach the reflector to the output surface onto ImplThread. |
| void ReattachToOutputSurfaceFromMainThread( |
| BrowserCompositorOutputSurface* surface); |
| |
| // ui::Reflector implementation. |
| virtual void OnMirroringCompositorResized() override; |
| |
| // Called in |BrowserCompositorOutputSurface::SwapBuffers| to copy |
| // the full screen image to the |texture_id_|. This must be called |
| // on ImplThread. |
| void OnSwapBuffers(); |
| |
| // Called in |BrowserCompositorOutputSurface::PostSubBuffer| copy |
| // the sub image given by |rect| to the texture.This must be called |
| // on ImplThread. |
| void OnPostSubBuffer(gfx::Rect rect); |
| |
| // Create a shared texture that will be used to copy the content of |
| // mirrored compositor to the mirroring compositor. This should |
| // be posted to the main thread when the output is attached in |
| // impl thread. |
| void CreateSharedTextureOnMainThread(gfx::Size size); |
| |
| // Called when the source surface is bound and available. This must |
| // be called on ImplThread. |
| 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); |
| |
| // Request full redraw on mirroring compositor. |
| void FullRedrawOnMainThread(gfx::Size size); |
| |
| void UpdateSubBufferOnMainThread(gfx::Size size, gfx::Rect rect); |
| |
| // Request full redraw on mirrored compositor so that |
| // the full content will be copied to mirroring compositor. |
| void FullRedrawContentOnMainThread(); |
| |
| // This exists just to hold a reference to a ReflectorImpl in a post task, |
| // so the ReflectorImpl gets deleted when the function returns. |
| static void DeleteOnMainThread(scoped_refptr<ReflectorImpl> reflector) {} |
| |
| 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_; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_COMPOSITOR_REFLECTOR_IMPL_H_ |