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