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