1 // Copyright 2014 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 CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_ 6 #define CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_ 7 8 #include "cc/layers/delegated_frame_provider.h" 9 #include "cc/layers/delegated_frame_resource_collection.h" 10 #include "cc/output/copy_output_result.h" 11 #include "cc/surfaces/surface_factory_client.h" 12 #include "content/browser/compositor/image_transport_factory.h" 13 #include "content/browser/compositor/owned_mailbox.h" 14 #include "content/browser/renderer_host/delegated_frame_evictor.h" 15 #include "content/browser/renderer_host/dip_util.h" 16 #include "content/browser/renderer_host/render_widget_host_impl.h" 17 #include "content/browser/renderer_host/render_widget_host_view_base.h" 18 #include "content/public/browser/render_process_host.h" 19 #include "ui/compositor/compositor.h" 20 #include "ui/compositor/compositor_observer.h" 21 #include "ui/compositor/compositor_vsync_manager.h" 22 #include "ui/compositor/layer.h" 23 #include "ui/compositor/layer_owner_delegate.h" 24 #include "ui/gfx/rect_conversions.h" 25 26 namespace cc { 27 class SurfaceFactory; 28 } 29 30 namespace media { 31 class VideoFrame; 32 } 33 34 namespace content { 35 36 class DelegatedFrameHost; 37 class ReadbackYUVInterface; 38 class RenderWidgetHostViewFrameSubscriber; 39 class RenderWidgetHostImpl; 40 class ResizeLock; 41 42 // The DelegatedFrameHostClient is the interface from the DelegatedFrameHost, 43 // which manages delegated frames, and the ui::Compositor being used to 44 // display them. 45 class CONTENT_EXPORT DelegatedFrameHostClient { 46 public: 47 virtual ui::Compositor* GetCompositor() const = 0; 48 virtual ui::Layer* GetLayer() = 0; 49 virtual RenderWidgetHostImpl* GetHost() = 0; 50 virtual bool IsVisible() = 0; 51 virtual scoped_ptr<ResizeLock> CreateResizeLock( 52 bool defer_compositor_lock) = 0; 53 virtual gfx::Size DesiredFrameSize() = 0; 54 55 // TODO(ccameron): It is likely that at least one of these two functions is 56 // redundant. Find which one, and delete it. 57 virtual float CurrentDeviceScaleFactor() = 0; 58 virtual gfx::Size ConvertViewSizeToPixel(const gfx::Size& size) = 0; 59 60 // These are to be overridden for testing only. 61 // TODO(ccameron): This is convoluted. Make the tests that need to override 62 // these functions test DelegatedFrameHost directly (rather than do it 63 // through RenderWidgetHostViewAura). 64 virtual DelegatedFrameHost* GetDelegatedFrameHost() const = 0; 65 virtual bool ShouldCreateResizeLock(); 66 virtual void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request); 67 }; 68 69 // The DelegatedFrameHost is used to host all of the RenderWidgetHostView state 70 // and functionality that is associated with delegated frames being sent from 71 // the RenderWidget. The DelegatedFrameHost will push these changes through to 72 // the ui::Compositor associated with its DelegatedFrameHostClient. 73 class CONTENT_EXPORT DelegatedFrameHost 74 : public ui::CompositorObserver, 75 public ui::CompositorVSyncManager::Observer, 76 public ui::LayerOwnerDelegate, 77 public ImageTransportFactoryObserver, 78 public DelegatedFrameEvictorClient, 79 public cc::DelegatedFrameResourceCollectionClient, 80 public cc::SurfaceFactoryClient, 81 public base::SupportsWeakPtr<DelegatedFrameHost> { 82 public: 83 DelegatedFrameHost(DelegatedFrameHostClient* client); 84 virtual ~DelegatedFrameHost(); 85 86 bool CanCopyToBitmap() const; 87 88 // Public interface exposed to RenderWidgetHostView. 89 void SwapDelegatedFrame( 90 uint32 output_surface_id, 91 scoped_ptr<cc::DelegatedFrameData> frame_data, 92 float frame_device_scale_factor, 93 const std::vector<ui::LatencyInfo>& latency_info); 94 void WasHidden(); 95 void WasShown(const ui::LatencyInfo& latency_info); 96 void WasResized(); 97 bool HasSavedFrame(); 98 gfx::Size GetRequestedRendererSize() const; 99 void AddedToWindow(); 100 void RemovingFromWindow(); 101 void CopyFromCompositingSurface(const gfx::Rect& src_subrect, 102 const gfx::Size& output_size, 103 CopyFromCompositingSurfaceCallback& callback, 104 const SkColorType color_type); 105 void CopyFromCompositingSurfaceToVideoFrame( 106 const gfx::Rect& src_subrect, 107 const scoped_refptr<media::VideoFrame>& target, 108 const base::Callback<void(bool)>& callback); 109 bool CanCopyToVideoFrame() const; 110 bool CanSubscribeFrame() const; 111 void BeginFrameSubscription( 112 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber); 113 void EndFrameSubscription(); 114 bool HasFrameSubscriber() const { return frame_subscriber_; } 115 116 // Exposed for tests. 117 cc::DelegatedFrameProvider* FrameProviderForTesting() const { 118 return frame_provider_.get(); 119 } 120 void OnCompositingDidCommitForTesting(ui::Compositor* compositor) { 121 OnCompositingDidCommit(compositor); 122 } 123 bool ShouldCreateResizeLockForTesting() { return ShouldCreateResizeLock(); } 124 bool ReleasedFrontLockActiveForTesting() const { 125 return !!released_front_lock_.get(); 126 } 127 128 private: 129 friend class DelegatedFrameHostClient; 130 FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, 131 SkippedDelegatedFrames); 132 FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, 133 DiscardDelegatedFramesWithLocking); 134 FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraCopyRequestTest, 135 DestroyedAfterCopyRequest); 136 137 RenderWidgetHostViewFrameSubscriber* frame_subscriber() const { 138 return frame_subscriber_.get(); 139 } 140 bool ShouldCreateResizeLock(); 141 void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request); 142 143 void LockResources(); 144 void UnlockResources(); 145 146 // Overridden from ui::CompositorObserver: 147 virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE; 148 virtual void OnCompositingStarted(ui::Compositor* compositor, 149 base::TimeTicks start_time) OVERRIDE; 150 virtual void OnCompositingEnded(ui::Compositor* compositor) OVERRIDE; 151 virtual void OnCompositingAborted(ui::Compositor* compositor) OVERRIDE; 152 virtual void OnCompositingLockStateChanged( 153 ui::Compositor* compositor) OVERRIDE; 154 155 // Overridden from ui::CompositorVSyncManager::Observer: 156 virtual void OnUpdateVSyncParameters(base::TimeTicks timebase, 157 base::TimeDelta interval) OVERRIDE; 158 159 // Overridden from ui::LayerOwnerObserver: 160 virtual void OnLayerRecreated(ui::Layer* old_layer, 161 ui::Layer* new_layer) OVERRIDE; 162 163 // Overridden from ImageTransportFactoryObserver: 164 virtual void OnLostResources() OVERRIDE; 165 166 bool ShouldSkipFrame(gfx::Size size_in_dip) const; 167 168 // Lazily grab a resize lock if the aura window size doesn't match the current 169 // frame size, to give time to the renderer. 170 void MaybeCreateResizeLock(); 171 172 // Checks if the resize lock can be released because we received an new frame. 173 void CheckResizeLock(); 174 175 // Run all on compositing commit callbacks. 176 void RunOnCommitCallbacks(); 177 178 // Add on compositing commit callback. 179 void AddOnCommitCallbackAndDisableLocks(const base::Closure& callback); 180 181 // Called after async thumbnailer task completes. Scales and crops the result 182 // of the copy. 183 static void CopyFromCompositingSurfaceHasResult( 184 const gfx::Size& dst_size_in_pixel, 185 const SkColorType color_type, 186 const base::Callback<void(bool, const SkBitmap&)>& callback, 187 scoped_ptr<cc::CopyOutputResult> result); 188 static void PrepareTextureCopyOutputResult( 189 const gfx::Size& dst_size_in_pixel, 190 const SkColorType color_type, 191 const base::Callback<void(bool, const SkBitmap&)>& callback, 192 scoped_ptr<cc::CopyOutputResult> result); 193 static void PrepareBitmapCopyOutputResult( 194 const gfx::Size& dst_size_in_pixel, 195 const SkColorType color_type, 196 const base::Callback<void(bool, const SkBitmap&)>& callback, 197 scoped_ptr<cc::CopyOutputResult> result); 198 static void CopyFromCompositingSurfaceHasResultForVideo( 199 base::WeakPtr<DelegatedFrameHost> rwhva, 200 scoped_refptr<OwnedMailbox> subscriber_texture, 201 scoped_refptr<media::VideoFrame> video_frame, 202 const base::Callback<void(bool)>& callback, 203 scoped_ptr<cc::CopyOutputResult> result); 204 static void CopyFromCompositingSurfaceFinishedForVideo( 205 base::WeakPtr<DelegatedFrameHost> rwhva, 206 const base::Callback<void(bool)>& callback, 207 scoped_refptr<OwnedMailbox> subscriber_texture, 208 scoped_ptr<cc::SingleReleaseCallback> release_callback, 209 bool result); 210 static void ReturnSubscriberTexture( 211 base::WeakPtr<DelegatedFrameHost> rwhva, 212 scoped_refptr<OwnedMailbox> subscriber_texture, 213 uint32 sync_point); 214 215 void SendDelegatedFrameAck(uint32 output_surface_id); 216 void SendReturnedDelegatedResources(uint32 output_surface_id); 217 218 // DelegatedFrameEvictorClient implementation. 219 virtual void EvictDelegatedFrame() OVERRIDE; 220 221 // cc::DelegatedFrameProviderClient implementation. 222 virtual void UnusedResourcesAreAvailable() OVERRIDE; 223 224 // cc::SurfaceFactoryClient implementation. 225 virtual void ReturnResources( 226 const cc::ReturnedResourceArray& resources) OVERRIDE; 227 228 void DidReceiveFrameFromRenderer(const gfx::Rect& damage_rect); 229 230 DelegatedFrameHostClient* client_; 231 232 // True if this renders into a Surface, false if it renders into a delegated 233 // layer. 234 bool use_surfaces_; 235 236 std::vector<base::Closure> on_compositing_did_commit_callbacks_; 237 238 // The vsync manager we are observing for changes, if any. 239 scoped_refptr<ui::CompositorVSyncManager> vsync_manager_; 240 241 // The current VSync timebase and interval. These are zero until the first 242 // call to OnUpdateVSyncParameters(). 243 base::TimeTicks vsync_timebase_; 244 base::TimeDelta vsync_interval_; 245 246 // With delegated renderer, this is the last output surface, used to 247 // disambiguate resources with the same id coming from different output 248 // surfaces. 249 uint32 last_output_surface_id_; 250 251 // The number of delegated frame acks that are pending, to delay resource 252 // returns until the acks are sent. 253 int pending_delegated_ack_count_; 254 255 // True after a delegated frame has been skipped, until a frame is not 256 // skipped. 257 bool skipped_frames_; 258 std::vector<ui::LatencyInfo> skipped_latency_info_list_; 259 260 // Holds delegated resources that have been given to a DelegatedFrameProvider, 261 // and gives back resources when they are no longer in use for return to the 262 // renderer. 263 scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_; 264 265 // Provides delegated frame updates to the cc::DelegatedRendererLayer. 266 scoped_refptr<cc::DelegatedFrameProvider> frame_provider_; 267 268 // State for rendering into a Surface. 269 scoped_ptr<cc::SurfaceIdAllocator> id_allocator_; 270 scoped_ptr<cc::SurfaceFactory> surface_factory_; 271 cc::SurfaceId surface_id_; 272 gfx::Size current_surface_size_; 273 cc::ReturnedResourceArray surface_returned_resources_; 274 275 // This lock is the one waiting for a frame of the right size to come back 276 // from the renderer/GPU process. It is set from the moment the aura window 277 // got resized, to the moment we committed the renderer frame of the same 278 // size. It keeps track of the size we expect from the renderer, and locks the 279 // compositor, as well as the UI for a short time to give a chance to the 280 // renderer of producing a frame of the right size. 281 scoped_ptr<ResizeLock> resize_lock_; 282 283 // Keeps track of the current frame size. 284 gfx::Size current_frame_size_in_dip_; 285 286 // This lock is for waiting for a front surface to become available to draw. 287 scoped_refptr<ui::CompositorLock> released_front_lock_; 288 289 enum CanLockCompositorState { 290 YES_CAN_LOCK, 291 // We locked, so at some point we'll need to kick a frame. 292 YES_DID_LOCK, 293 // No. A lock timed out, we need to kick a new frame before locking again. 294 NO_PENDING_RENDERER_FRAME, 295 // No. We've got a frame, but it hasn't been committed. 296 NO_PENDING_COMMIT, 297 }; 298 CanLockCompositorState can_lock_compositor_; 299 300 base::TimeTicks last_draw_ended_; 301 302 // Subscriber that listens to frame presentation events. 303 scoped_ptr<RenderWidgetHostViewFrameSubscriber> frame_subscriber_; 304 std::vector<scoped_refptr<OwnedMailbox> > idle_frame_subscriber_textures_; 305 306 // YUV readback pipeline. 307 scoped_ptr<content::ReadbackYUVInterface> 308 yuv_readback_pipeline_; 309 310 scoped_ptr<DelegatedFrameEvictor> delegated_frame_evictor_; 311 }; 312 313 } // namespace content 314 315 #endif // CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_ 316