compositor.h revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UI_COMPOSITOR_COMPOSITOR_H_
6#define UI_COMPOSITOR_COMPOSITOR_H_
7
8#include <string>
9
10#include "base/hash_tables.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/observer_list.h"
14#include "base/time.h"
15#include "cc/trees/layer_tree_host_client.h"
16#include "third_party/skia/include/core/SkColor.h"
17#include "ui/compositor/compositor_export.h"
18#include "ui/compositor/compositor_observer.h"
19#include "ui/gfx/native_widget_types.h"
20#include "ui/gfx/size.h"
21#include "ui/gfx/transform.h"
22#include "ui/gfx/vector2d.h"
23#include "ui/gl/gl_share_group.h"
24
25class SkBitmap;
26
27namespace base {
28class RunLoop;
29}
30
31namespace cc {
32class ContextProvider;
33class Layer;
34class LayerTreeDebugState;
35class LayerTreeHost;
36}
37
38namespace gfx {
39class GLContext;
40class GLSurface;
41class GLShareGroup;
42class Point;
43class Rect;
44}
45
46namespace WebKit {
47class WebGraphicsContext3D;
48}
49
50namespace ui {
51
52class Compositor;
53class CompositorObserver;
54class ContextProviderFromContextFactory;
55class Layer;
56class PostedSwapQueue;
57
58// This class abstracts the creation of the 3D context for the compositor. It is
59// a global object.
60class COMPOSITOR_EXPORT ContextFactory {
61 public:
62  virtual ~ContextFactory() {}
63
64  // Gets the global instance.
65  static ContextFactory* GetInstance();
66
67  // Sets the global instance. Caller keeps ownership.
68  // If this function isn't called (for tests), a "default" factory will be
69  // created on the first call of GetInstance.
70  static void SetInstance(ContextFactory* instance);
71
72  // Creates an output surface for the given compositor. The factory may keep
73  // per-compositor data (e.g. a shared context), that needs to be cleaned up
74  // by calling RemoveCompositor when the compositor gets destroyed.
75  virtual cc::OutputSurface* CreateOutputSurface(
76      Compositor* compositor) = 0;
77
78  // Creates a context used for offscreen rendering. This context can be shared
79  // with all compositors.
80  virtual WebKit::WebGraphicsContext3D* CreateOffscreenContext() = 0;
81
82  virtual scoped_refptr<cc::ContextProvider>
83      OffscreenContextProviderForMainThread() = 0;
84  virtual scoped_refptr<cc::ContextProvider>
85      OffscreenContextProviderForCompositorThread() = 0;
86
87  // Destroys per-compositor data.
88  virtual void RemoveCompositor(Compositor* compositor) = 0;
89};
90
91// The default factory that creates in-process contexts.
92class COMPOSITOR_EXPORT DefaultContextFactory : public ContextFactory {
93 public:
94  DefaultContextFactory();
95  virtual ~DefaultContextFactory();
96
97  // ContextFactory implementation
98  virtual cc::OutputSurface* CreateOutputSurface(
99      Compositor* compositor) OVERRIDE;
100  virtual WebKit::WebGraphicsContext3D* CreateOffscreenContext() OVERRIDE;
101  virtual scoped_refptr<cc::ContextProvider>
102      OffscreenContextProviderForMainThread() OVERRIDE;
103  virtual scoped_refptr<cc::ContextProvider>
104      OffscreenContextProviderForCompositorThread() OVERRIDE;
105  virtual void RemoveCompositor(Compositor* compositor) OVERRIDE;
106
107  bool Initialize();
108
109 private:
110  WebKit::WebGraphicsContext3D* CreateContextCommon(
111      Compositor* compositor,
112      bool offscreen);
113
114  scoped_refptr<ContextProviderFromContextFactory>
115      offscreen_contexts_main_thread_;
116  scoped_refptr<ContextProviderFromContextFactory>
117      offscreen_contexts_compositor_thread_;
118
119  DISALLOW_COPY_AND_ASSIGN(DefaultContextFactory);
120};
121
122// The factory that creates test contexts.
123class COMPOSITOR_EXPORT TestContextFactory : public ContextFactory {
124 public:
125  TestContextFactory();
126  virtual ~TestContextFactory();
127
128  // ContextFactory implementation
129  virtual cc::OutputSurface* CreateOutputSurface(
130      Compositor* compositor) OVERRIDE;
131  virtual WebKit::WebGraphicsContext3D* CreateOffscreenContext() OVERRIDE;
132  virtual scoped_refptr<cc::ContextProvider>
133      OffscreenContextProviderForMainThread() OVERRIDE;
134  virtual scoped_refptr<cc::ContextProvider>
135      OffscreenContextProviderForCompositorThread() OVERRIDE;
136  virtual void RemoveCompositor(Compositor* compositor) OVERRIDE;
137
138 private:
139  scoped_refptr<ContextProviderFromContextFactory>
140      offscreen_contexts_main_thread_;
141  scoped_refptr<ContextProviderFromContextFactory>
142      offscreen_contexts_compositor_thread_;
143
144  DISALLOW_COPY_AND_ASSIGN(TestContextFactory);
145};
146
147// Texture provide an abstraction over the external texture that can be passed
148// to a layer.
149class COMPOSITOR_EXPORT Texture : public base::RefCounted<Texture> {
150 public:
151  Texture(bool flipped, const gfx::Size& size, float device_scale_factor);
152
153  bool flipped() const { return flipped_; }
154  gfx::Size size() const { return size_; }
155  float device_scale_factor() const { return device_scale_factor_; }
156
157  virtual unsigned int PrepareTexture() = 0;
158  virtual WebKit::WebGraphicsContext3D* HostContext3D() = 0;
159
160  // Replaces the texture with the texture from the specified mailbox.
161  virtual void Consume(const std::string& mailbox_name,
162                       const gfx::Size& new_size) {}
163
164  // Moves the texture into the mailbox and returns the mailbox name.
165  // The texture must have been previously consumed from a mailbox.
166  virtual std::string Produce();
167
168 protected:
169  virtual ~Texture();
170  gfx::Size size_;  // in pixel
171
172 private:
173  friend class base::RefCounted<Texture>;
174
175  bool flipped_;
176  float device_scale_factor_;
177
178  DISALLOW_COPY_AND_ASSIGN(Texture);
179};
180
181// An interface to allow the compositor to communicate with its owner.
182class COMPOSITOR_EXPORT CompositorDelegate {
183 public:
184  // Requests the owner to schedule a redraw of the layer tree.
185  virtual void ScheduleDraw() = 0;
186
187 protected:
188  virtual ~CompositorDelegate() {}
189};
190
191// This class represents a lock on the compositor, that can be used to prevent
192// commits to the compositor tree while we're waiting for an asynchronous
193// event. The typical use case is when waiting for a renderer to produce a frame
194// at the right size. The caller keeps a reference on this object, and drops the
195// reference once it desires to release the lock.
196// Note however that the lock is cancelled after a short timeout to ensure
197// responsiveness of the UI, so the compositor tree should be kept in a
198// "reasonable" state while the lock is held.
199// Don't instantiate this class directly, use Compositor::GetCompositorLock.
200class COMPOSITOR_EXPORT CompositorLock
201    : public base::RefCounted<CompositorLock>,
202      public base::SupportsWeakPtr<CompositorLock> {
203 private:
204  friend class base::RefCounted<CompositorLock>;
205  friend class Compositor;
206
207  explicit CompositorLock(Compositor* compositor);
208  ~CompositorLock();
209
210  void CancelLock();
211
212  Compositor* compositor_;
213  DISALLOW_COPY_AND_ASSIGN(CompositorLock);
214};
215
216// This is only to be used for test. It allows execution of other tasks on
217// the current message loop before the current task finishs (there is a
218// potential for re-entrancy).
219class COMPOSITOR_EXPORT DrawWaiterForTest : public ui::CompositorObserver {
220 public:
221  // Waits for a draw to be issued by the compositor. If the test times out
222  // here, there may be a logic error in the compositor code causing it
223  // not to draw.
224  static void Wait(Compositor* compositor);
225
226 private:
227  DrawWaiterForTest();
228  virtual ~DrawWaiterForTest();
229
230  void WaitImpl(Compositor* compositor);
231
232  // CompositorObserver implementation.
233  virtual void OnCompositingDidCommit(Compositor* compositor) OVERRIDE;
234  virtual void OnCompositingStarted(Compositor* compositor,
235                                    base::TimeTicks start_time) OVERRIDE;
236  virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE;
237  virtual void OnCompositingAborted(Compositor* compositor) OVERRIDE;
238  virtual void OnCompositingLockStateChanged(Compositor* compositor) OVERRIDE;
239  virtual void OnUpdateVSyncParameters(Compositor* compositor,
240                                       base::TimeTicks timebase,
241                                       base::TimeDelta interval) OVERRIDE;
242
243  scoped_ptr<base::RunLoop> wait_run_loop_;
244
245  DISALLOW_COPY_AND_ASSIGN(DrawWaiterForTest);
246};
247
248// Compositor object to take care of GPU painting.
249// A Browser compositor object is responsible for generating the final
250// displayable form of pixels comprising a single widget's contents. It draws an
251// appropriately transformed texture for each transformed view in the widget's
252// view hierarchy.
253class COMPOSITOR_EXPORT Compositor
254    : NON_EXPORTED_BASE(public cc::LayerTreeHostClient),
255      public base::SupportsWeakPtr<Compositor> {
256 public:
257  Compositor(CompositorDelegate* delegate,
258             gfx::AcceleratedWidget widget);
259  virtual ~Compositor();
260
261  static void Initialize();
262  static bool WasInitializedWithThread();
263  static void Terminate();
264
265  // Schedules a redraw of the layer tree associated with this compositor.
266  void ScheduleDraw();
267
268  // Sets the root of the layer tree drawn by this Compositor. The root layer
269  // must have no parent. The compositor's root layer is reset if the root layer
270  // is destroyed. NULL can be passed to reset the root layer, in which case the
271  // compositor will stop drawing anything.
272  // The Compositor does not own the root layer.
273  const Layer* root_layer() const { return root_layer_; }
274  Layer* root_layer() { return root_layer_; }
275  void SetRootLayer(Layer* root_layer);
276
277  // Called when we need the compositor to preserve the alpha channel in the
278  // output for situations when we want to render transparently atop something
279  // else, e.g. Aero glass.
280  void SetHostHasTransparentBackground(bool host_has_transparent_background);
281
282  // The scale factor of the device that this compositor is
283  // compositing layers on.
284  float device_scale_factor() const { return device_scale_factor_; }
285
286  // Draws the scene created by the layer tree and any visual effects.
287  void Draw();
288
289  // Where possible, draws are scissored to a damage region calculated from
290  // changes to layer properties.  This bypasses that and indicates that
291  // the whole frame needs to be drawn.
292  void ScheduleFullRedraw();
293
294  // Schedule redraw and append damage_rect to the damage region calculated
295  // from changes to layer properties.
296  void ScheduleRedrawRect(const gfx::Rect& damage_rect);
297
298  // Reads the region |bounds_in_pixel| of the contents of the last rendered
299  // frame into the given bitmap.
300  // Returns false if the pixels could not be read.
301  bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds_in_pixel);
302
303  // Sets the compositor's device scale factor and size.
304  void SetScaleAndSize(float scale, const gfx::Size& size_in_pixel);
305
306  // Returns the size of the widget that is being drawn to in pixel coordinates.
307  const gfx::Size& size() const { return size_; }
308
309  // Sets the background color used for areas that aren't covered by
310  // the |root_layer|.
311  void SetBackgroundColor(SkColor color);
312
313  // Returns the widget for this compositor.
314  gfx::AcceleratedWidget widget() const { return widget_; }
315
316  // Compositor does not own observers. It is the responsibility of the
317  // observer to remove itself when it is done observing.
318  void AddObserver(CompositorObserver* observer);
319  void RemoveObserver(CompositorObserver* observer);
320  bool HasObserver(CompositorObserver* observer);
321
322  // Creates a compositor lock. Returns NULL if it is not possible to lock at
323  // this time (i.e. we're waiting to complete a previous unlock).
324  scoped_refptr<CompositorLock> GetCompositorLock();
325
326  // Internal functions, called back by command-buffer contexts on swap buffer
327  // events.
328
329  // Signals swap has been posted.
330  void OnSwapBuffersPosted();
331
332  // Signals swap has completed.
333  void OnSwapBuffersComplete();
334
335  // Signals swap has aborted (e.g. lost context).
336  void OnSwapBuffersAborted();
337
338  void OnUpdateVSyncParameters(base::TimeTicks timebase,
339                               base::TimeDelta interval);
340
341  // LayerTreeHostClient implementation.
342  virtual void WillBeginFrame() OVERRIDE {}
343  virtual void DidBeginFrame() OVERRIDE {}
344  virtual void Animate(double frame_begin_time) OVERRIDE {}
345  virtual void Layout() OVERRIDE;
346  virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
347                                   float page_scale) OVERRIDE {}
348  virtual scoped_ptr<cc::OutputSurface>
349      CreateOutputSurface() OVERRIDE;
350  virtual void DidInitializeOutputSurface(bool success) OVERRIDE {}
351  virtual void WillCommit() OVERRIDE {}
352  virtual void DidCommit() OVERRIDE;
353  virtual void DidCommitAndDrawFrame() OVERRIDE;
354  virtual void DidCompleteSwapBuffers() OVERRIDE;
355  virtual void ScheduleComposite() OVERRIDE;
356  virtual scoped_refptr<cc::ContextProvider>
357      OffscreenContextProviderForMainThread() OVERRIDE;
358  virtual scoped_refptr<cc::ContextProvider>
359      OffscreenContextProviderForCompositorThread() OVERRIDE;
360
361  int last_started_frame() { return last_started_frame_; }
362  int last_ended_frame() { return last_ended_frame_; }
363
364  bool IsLocked() { return compositor_lock_ != NULL; }
365
366  const cc::LayerTreeDebugState& GetLayerTreeDebugState() const;
367  void SetLayerTreeDebugState(const cc::LayerTreeDebugState& debug_state);
368
369 private:
370  friend class base::RefCounted<Compositor>;
371  friend class CompositorLock;
372
373  // Called by CompositorLock.
374  void UnlockCompositor();
375
376  // Called to release any pending CompositorLock
377  void CancelCompositorLock();
378
379  // Notifies the compositor that compositing is complete.
380  void NotifyEnd();
381
382  CompositorDelegate* delegate_;
383  gfx::Size size_;
384
385  // The root of the Layer tree drawn by this compositor.
386  Layer* root_layer_;
387
388  ObserverList<CompositorObserver> observer_list_;
389
390  gfx::AcceleratedWidget widget_;
391  scoped_refptr<cc::Layer> root_web_layer_;
392  scoped_ptr<cc::LayerTreeHost> host_;
393
394  // Used to verify that we have at most one draw swap in flight.
395  scoped_ptr<PostedSwapQueue> posted_swaps_;
396
397  // The device scale factor of the monitor that this compositor is compositing
398  // layers on.
399  float device_scale_factor_;
400
401  int last_started_frame_;
402  int last_ended_frame_;
403
404  bool next_draw_is_resize_;
405
406  bool disable_schedule_composite_;
407
408  CompositorLock* compositor_lock_;
409
410  DISALLOW_COPY_AND_ASSIGN(Compositor);
411};
412
413}  // namespace ui
414
415#endif  // UI_COMPOSITOR_COMPOSITOR_H_
416