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