summaryrefslogtreecommitdiffstats
path: root/content/browser/compositor/reflector_impl.h
blob: f771fe46c333596efac177ebc7fa35d9e758b9d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// 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.
  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;
  };

  ~ReflectorImpl() override;

  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_