Home | History | Annotate | Download | only in output
      1 // Copyright 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 CC_OUTPUT_OUTPUT_SURFACE_H_
      6 #define CC_OUTPUT_OUTPUT_SURFACE_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/memory/ref_counted.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/memory/weak_ptr.h"
     12 #include "cc/base/cc_export.h"
     13 #include "cc/output/context_provider.h"
     14 #include "cc/output/software_output_device.h"
     15 #include "cc/scheduler/frame_rate_controller.h"
     16 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
     17 
     18 namespace base { class SingleThreadTaskRunner; }
     19 
     20 namespace ui { struct LatencyInfo; }
     21 
     22 namespace gfx {
     23 class Rect;
     24 class Size;
     25 class Transform;
     26 }
     27 
     28 namespace cc {
     29 
     30 class CompositorFrame;
     31 class CompositorFrameAck;
     32 struct ManagedMemoryPolicy;
     33 class OutputSurfaceClient;
     34 class OutputSurfaceCallbacks;
     35 
     36 // Represents the output surface for a compositor. The compositor owns
     37 // and manages its destruction. Its lifetime is:
     38 //   1. Created on the main thread by the LayerTreeHost through its client.
     39 //   2. Passed to the compositor thread and bound to a client via BindToClient.
     40 //      From here on, it will only be used on the compositor thread.
     41 //   3. If the 3D context is lost, then the compositor will delete the output
     42 //      surface (on the compositor thread) and go back to step 1.
     43 class CC_EXPORT OutputSurface : public FrameRateControllerClient {
     44  public:
     45   enum {
     46     DEFAULT_MAX_FRAMES_PENDING = 2
     47   };
     48 
     49   explicit OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D> context3d);
     50 
     51   explicit OutputSurface(scoped_ptr<cc::SoftwareOutputDevice> software_device);
     52 
     53   OutputSurface(scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
     54                 scoped_ptr<cc::SoftwareOutputDevice> software_device);
     55 
     56   virtual ~OutputSurface();
     57 
     58   struct Capabilities {
     59     Capabilities()
     60         : delegated_rendering(false),
     61           max_frames_pending(0),
     62           deferred_gl_initialization(false),
     63           draw_and_swap_full_viewport_every_frame(false),
     64           adjust_deadline_for_parent(true) {}
     65     bool delegated_rendering;
     66     int max_frames_pending;
     67     bool deferred_gl_initialization;
     68     bool draw_and_swap_full_viewport_every_frame;
     69     // This doesn't handle the <webview> case, but once BeginFrame is
     70     // supported natively, we shouldn't need adjust_deadline_for_parent.
     71     bool adjust_deadline_for_parent;
     72   };
     73 
     74   const Capabilities& capabilities() const {
     75     return capabilities_;
     76   }
     77 
     78   // Obtain the 3d context or the software device associated with this output
     79   // surface. Either of these may return a null pointer, but not both.
     80   // In the event of a lost context, the entire output surface should be
     81   // recreated.
     82   WebKit::WebGraphicsContext3D* context3d() const {
     83     return context3d_.get();
     84   }
     85 
     86   SoftwareOutputDevice* software_device() const {
     87     return software_device_.get();
     88   }
     89 
     90   // In the case where both the context3d and software_device are present
     91   // (namely Android WebView), this is called to determine whether the software
     92   // device should be used on the current frame.
     93   virtual bool ForcedDrawToSoftwareDevice() const;
     94 
     95   // Called by the compositor on the compositor thread. This is a place where
     96   // thread-specific data for the output surface can be initialized, since from
     97   // this point on the output surface will only be used on the compositor
     98   // thread.
     99   virtual bool BindToClient(OutputSurfaceClient* client);
    100 
    101   void InitializeBeginFrameEmulation(
    102       base::SingleThreadTaskRunner* task_runner,
    103       bool throttle_frame_production,
    104       base::TimeDelta interval);
    105 
    106   void SetMaxFramesPending(int max_frames_pending);
    107 
    108   virtual void EnsureBackbuffer();
    109   virtual void DiscardBackbuffer();
    110 
    111   virtual void Reshape(gfx::Size size, float scale_factor);
    112   virtual gfx::Size SurfaceSize() const;
    113 
    114   virtual void BindFramebuffer();
    115 
    116   // The implementation may destroy or steal the contents of the CompositorFrame
    117   // passed in (though it will not take ownership of the CompositorFrame
    118   // itself).
    119   virtual void SwapBuffers(CompositorFrame* frame);
    120 
    121   // Notifies frame-rate smoothness preference. If true, all non-critical
    122   // processing should be stopped, or lowered in priority.
    123   virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {}
    124 
    125   // Requests a BeginFrame notification from the output surface. The
    126   // notification will be delivered by calling
    127   // OutputSurfaceClient::BeginFrame until the callback is disabled.
    128   virtual void SetNeedsBeginFrame(bool enable);
    129 
    130  protected:
    131   // Synchronously initialize context3d and enter hardware mode.
    132   // This can only supported in threaded compositing mode.
    133   // |offscreen_context_provider| should match what is returned by
    134   // LayerTreeClient::OffscreenContextProviderForCompositorThread.
    135   bool InitializeAndSetContext3D(
    136       scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
    137       scoped_refptr<ContextProvider> offscreen_context_provider);
    138   void ReleaseGL();
    139 
    140   void PostSwapBuffersComplete();
    141 
    142   struct cc::OutputSurface::Capabilities capabilities_;
    143   scoped_ptr<OutputSurfaceCallbacks> callbacks_;
    144   scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
    145   scoped_ptr<cc::SoftwareOutputDevice> software_device_;
    146   bool has_gl_discard_backbuffer_;
    147   bool has_swap_buffers_complete_callback_;
    148   gfx::Size surface_size_;
    149   float device_scale_factor_;
    150   base::WeakPtrFactory<OutputSurface> weak_ptr_factory_;
    151 
    152   // The FrameRateController is deprecated.
    153   // Platforms should move to native BeginFrames instead.
    154   void OnVSyncParametersChanged(base::TimeTicks timebase,
    155                                 base::TimeDelta interval);
    156   virtual void FrameRateControllerTick(bool throttled,
    157                                        const BeginFrameArgs& args) OVERRIDE;
    158   scoped_ptr<FrameRateController> frame_rate_controller_;
    159   int max_frames_pending_;
    160   int pending_swap_buffers_;
    161   bool needs_begin_frame_;
    162   bool begin_frame_pending_;
    163 
    164   // Forwarded to OutputSurfaceClient but threaded through OutputSurface
    165   // first so OutputSurface has a chance to update the FrameRateController
    166   bool HasClient() { return !!client_; }
    167   void SetNeedsRedrawRect(gfx::Rect damage_rect);
    168   void BeginFrame(const BeginFrameArgs& args);
    169   void DidSwapBuffers();
    170   void OnSwapBuffersComplete(const CompositorFrameAck* ack);
    171   void DidLoseOutputSurface();
    172   void SetExternalStencilTest(bool enabled);
    173   void SetExternalDrawConstraints(const gfx::Transform& transform,
    174                                   gfx::Rect viewport,
    175                                   gfx::Rect clip,
    176                                   bool valid_for_tile_management);
    177 
    178   // virtual for testing.
    179   virtual base::TimeDelta RetroactiveBeginFramePeriod();
    180   virtual void PostCheckForRetroactiveBeginFrame();
    181   void CheckForRetroactiveBeginFrame();
    182 
    183  private:
    184   OutputSurfaceClient* client_;
    185   friend class OutputSurfaceCallbacks;
    186 
    187   void SetContext3D(scoped_ptr<WebKit::WebGraphicsContext3D> context3d);
    188   void ResetContext3D();
    189   void SetMemoryPolicy(const ManagedMemoryPolicy& policy,
    190                        bool discard_backbuffer_when_not_visible);
    191 
    192   // This stores a BeginFrame that we couldn't process immediately, but might
    193   // process retroactively in the near future.
    194   BeginFrameArgs skipped_begin_frame_args_;
    195 
    196   // check_for_retroactive_begin_frame_pending_ is used to avoid posting
    197   // redundant checks for a retroactive BeginFrame.
    198   bool check_for_retroactive_begin_frame_pending_;
    199 
    200   DISALLOW_COPY_AND_ASSIGN(OutputSurface);
    201 };
    202 
    203 }  // namespace cc
    204 
    205 #endif  // CC_OUTPUT_OUTPUT_SURFACE_H_
    206