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