• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
CapabilitiesCapabilities60     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 
capabilities()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.
context_provider()89   scoped_refptr<ContextProvider> context_provider() const {
90     return context_provider_.get();
91   }
software_device()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.
UpdateSmoothnessTakesPriority(bool prefer_smoothness)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 
HasClient()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