OLD | NEW |
| (Empty) |
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 <stdint.h> | |
9 | |
10 #include <vector> | |
11 | |
12 #include "base/gtest_prod_util.h" | |
13 #include "cc/output/copy_output_result.h" | |
14 #include "cc/surfaces/surface_factory_client.h" | |
15 #include "content/browser/compositor/image_transport_factory.h" | |
16 #include "content/browser/compositor/owned_mailbox.h" | |
17 #include "content/browser/renderer_host/delegated_frame_evictor.h" | |
18 #include "content/browser/renderer_host/dip_util.h" | |
19 #include "content/browser/renderer_host/render_widget_host_impl.h" | |
20 #include "content/browser/renderer_host/render_widget_host_view_base.h" | |
21 #include "content/public/browser/render_process_host.h" | |
22 #include "ui/compositor/compositor.h" | |
23 #include "ui/compositor/compositor_observer.h" | |
24 #include "ui/compositor/compositor_vsync_manager.h" | |
25 #include "ui/compositor/layer.h" | |
26 #include "ui/compositor/layer_owner_delegate.h" | |
27 #include "ui/events/event.h" | |
28 #include "ui/gfx/geometry/rect_conversions.h" | |
29 | |
30 namespace base { | |
31 class TickClock; | |
32 } | |
33 | |
34 namespace cc { | |
35 class SurfaceFactory; | |
36 enum class SurfaceDrawStatus; | |
37 } | |
38 | |
39 namespace media { | |
40 class VideoFrame; | |
41 } | |
42 | |
43 namespace content { | |
44 | |
45 class DelegatedFrameHost; | |
46 class ReadbackYUVInterface; | |
47 class RenderWidgetHostViewFrameSubscriber; | |
48 class RenderWidgetHostImpl; | |
49 class ResizeLock; | |
50 | |
51 // The DelegatedFrameHostClient is the interface from the DelegatedFrameHost, | |
52 // which manages delegated frames, and the ui::Compositor being used to | |
53 // display them. | |
54 class CONTENT_EXPORT DelegatedFrameHostClient { | |
55 public: | |
56 virtual ui::Layer* DelegatedFrameHostGetLayer() const = 0; | |
57 virtual bool DelegatedFrameHostIsVisible() const = 0; | |
58 virtual gfx::Size DelegatedFrameHostDesiredSizeInDIP() const = 0; | |
59 | |
60 virtual bool DelegatedFrameCanCreateResizeLock() const = 0; | |
61 virtual scoped_ptr<ResizeLock> DelegatedFrameHostCreateResizeLock( | |
62 bool defer_compositor_lock) = 0; | |
63 virtual void DelegatedFrameHostResizeLockWasReleased() = 0; | |
64 | |
65 virtual void DelegatedFrameHostSendCompositorSwapAck( | |
66 int output_surface_id, | |
67 const cc::CompositorFrameAck& ack) = 0; | |
68 virtual void DelegatedFrameHostSendReclaimCompositorResources( | |
69 int output_surface_id, | |
70 const cc::CompositorFrameAck& ack) = 0; | |
71 virtual void DelegatedFrameHostOnLostCompositorResources() = 0; | |
72 | |
73 virtual void DelegatedFrameHostUpdateVSyncParameters( | |
74 const base::TimeTicks& timebase, | |
75 const base::TimeDelta& interval) = 0; | |
76 }; | |
77 | |
78 // The DelegatedFrameHost is used to host all of the RenderWidgetHostView state | |
79 // and functionality that is associated with delegated frames being sent from | |
80 // the RenderWidget. The DelegatedFrameHost will push these changes through to | |
81 // the ui::Compositor associated with its DelegatedFrameHostClient. | |
82 class CONTENT_EXPORT DelegatedFrameHost | |
83 : public ui::CompositorObserver, | |
84 public ui::CompositorVSyncManager::Observer, | |
85 public ui::LayerOwnerDelegate, | |
86 public ImageTransportFactoryObserver, | |
87 public DelegatedFrameEvictorClient, | |
88 public cc::SurfaceFactoryClient, | |
89 public base::SupportsWeakPtr<DelegatedFrameHost> { | |
90 public: | |
91 explicit DelegatedFrameHost(DelegatedFrameHostClient* client); | |
92 ~DelegatedFrameHost() override; | |
93 | |
94 // ui::CompositorObserver implementation. | |
95 void OnCompositingDidCommit(ui::Compositor* compositor) override; | |
96 void OnCompositingStarted(ui::Compositor* compositor, | |
97 base::TimeTicks start_time) override; | |
98 void OnCompositingEnded(ui::Compositor* compositor) override; | |
99 void OnCompositingAborted(ui::Compositor* compositor) override; | |
100 void OnCompositingLockStateChanged(ui::Compositor* compositor) override; | |
101 void OnCompositingShuttingDown(ui::Compositor* compositor) override; | |
102 | |
103 // ui::CompositorVSyncManager::Observer implementation. | |
104 void OnUpdateVSyncParameters(base::TimeTicks timebase, | |
105 base::TimeDelta interval) override; | |
106 | |
107 // ui::LayerOwnerObserver implementation. | |
108 void OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) override; | |
109 | |
110 // ImageTransportFactoryObserver implementation. | |
111 void OnLostResources() override; | |
112 | |
113 // DelegatedFrameEvictorClient implementation. | |
114 void EvictDelegatedFrame() override; | |
115 | |
116 // cc::SurfaceFactoryClient implementation. | |
117 void ReturnResources(const cc::ReturnedResourceArray& resources) override; | |
118 void WillDrawSurface(cc::SurfaceId id, const gfx::Rect& damage_rect) override; | |
119 void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) override; | |
120 | |
121 bool CanCopyToBitmap() const; | |
122 | |
123 // Public interface exposed to RenderWidgetHostView. | |
124 | |
125 void SwapDelegatedFrame(uint32_t output_surface_id, | |
126 scoped_ptr<cc::CompositorFrame> frame); | |
127 void ClearDelegatedFrame(); | |
128 void WasHidden(); | |
129 void WasShown(const ui::LatencyInfo& latency_info); | |
130 void WasResized(); | |
131 bool HasSavedFrame(); | |
132 gfx::Size GetRequestedRendererSize() const; | |
133 void SetCompositor(ui::Compositor* compositor); | |
134 void ResetCompositor(); | |
135 void SetVSyncParameters(const base::TimeTicks& timebase, | |
136 const base::TimeDelta& interval); | |
137 // Note: |src_subset| is specified in DIP dimensions while |output_size| | |
138 // expects pixels. | |
139 void CopyFromCompositingSurface(const gfx::Rect& src_subrect, | |
140 const gfx::Size& output_size, | |
141 const ReadbackRequestCallback& callback, | |
142 const SkColorType preferred_color_type); | |
143 void CopyFromCompositingSurfaceToVideoFrame( | |
144 const gfx::Rect& src_subrect, | |
145 const scoped_refptr<media::VideoFrame>& target, | |
146 const base::Callback<void(const gfx::Rect&, bool)>& callback); | |
147 bool CanCopyToVideoFrame() const; | |
148 void BeginFrameSubscription( | |
149 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber); | |
150 void EndFrameSubscription(); | |
151 bool HasFrameSubscriber() const { return !!frame_subscriber_; } | |
152 uint32_t GetSurfaceIdNamespace(); | |
153 // Returns a null SurfaceId if this DelegatedFrameHost has not yet created | |
154 // a compositor Surface. | |
155 cc::SurfaceId SurfaceIdAtPoint(cc::SurfaceHittestDelegate* delegate, | |
156 const gfx::Point& point, | |
157 gfx::Point* transformed_point); | |
158 | |
159 // Given the SurfaceID of a Surface that is contained within this class' | |
160 // Surface, find the relative transform between the Surfaces and apply it | |
161 // to a point. If a Surface has not yet been created this returns the | |
162 // same point with no transform applied. | |
163 void TransformPointToLocalCoordSpace(const gfx::Point& point, | |
164 cc::SurfaceId original_surface, | |
165 gfx::Point* transformed_point); | |
166 | |
167 // Exposed for tests. | |
168 cc::SurfaceId SurfaceIdForTesting() const { return surface_id_; } | |
169 void OnCompositingDidCommitForTesting(ui::Compositor* compositor) { | |
170 OnCompositingDidCommit(compositor); | |
171 } | |
172 bool ReleasedFrontLockActiveForTesting() const { | |
173 return !!released_front_lock_.get(); | |
174 } | |
175 void SetRequestCopyOfOutputCallbackForTesting( | |
176 const base::Callback<void(scoped_ptr<cc::CopyOutputRequest>)>& callback) { | |
177 request_copy_of_output_callback_for_testing_ = callback; | |
178 } | |
179 | |
180 private: | |
181 friend class DelegatedFrameHostClient; | |
182 friend class RenderWidgetHostViewAuraCopyRequestTest; | |
183 FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, | |
184 SkippedDelegatedFrames); | |
185 FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, | |
186 DiscardDelegatedFramesWithLocking); | |
187 | |
188 RenderWidgetHostViewFrameSubscriber* frame_subscriber() const { | |
189 return frame_subscriber_.get(); | |
190 } | |
191 bool ShouldCreateResizeLock(); | |
192 void LockResources(); | |
193 void UnlockResources(); | |
194 void RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request); | |
195 | |
196 bool ShouldSkipFrame(gfx::Size size_in_dip) const; | |
197 | |
198 // Lazily grab a resize lock if the aura window size doesn't match the current | |
199 // frame size, to give time to the renderer. | |
200 void MaybeCreateResizeLock(); | |
201 | |
202 // Checks if the resize lock can be released because we received an new frame. | |
203 void CheckResizeLock(); | |
204 | |
205 // Update the layers for the resize gutters to the right and bottom of the | |
206 // surface layer. | |
207 void UpdateGutters(); | |
208 | |
209 // Called after async thumbnailer task completes. Scales and crops the result | |
210 // of the copy. | |
211 static void CopyFromCompositingSurfaceHasResultForVideo( | |
212 base::WeakPtr<DelegatedFrameHost> rwhva, | |
213 scoped_refptr<OwnedMailbox> subscriber_texture, | |
214 scoped_refptr<media::VideoFrame> video_frame, | |
215 const base::Callback<void(const gfx::Rect&, bool)>& callback, | |
216 scoped_ptr<cc::CopyOutputResult> result); | |
217 static void CopyFromCompositingSurfaceFinishedForVideo( | |
218 base::WeakPtr<DelegatedFrameHost> rwhva, | |
219 const base::Callback<void(bool)>& callback, | |
220 scoped_refptr<OwnedMailbox> subscriber_texture, | |
221 scoped_ptr<cc::SingleReleaseCallback> release_callback, | |
222 bool result); | |
223 static void ReturnSubscriberTexture( | |
224 base::WeakPtr<DelegatedFrameHost> rwhva, | |
225 scoped_refptr<OwnedMailbox> subscriber_texture, | |
226 const gpu::SyncToken& sync_token); | |
227 | |
228 void SendDelegatedFrameAck(uint32_t output_surface_id); | |
229 void SurfaceDrawn(uint32_t output_surface_id, cc::SurfaceDrawStatus drawn); | |
230 void SendReturnedDelegatedResources(uint32_t output_surface_id); | |
231 | |
232 // Called to consult the current |frame_subscriber_|, to determine and maybe | |
233 // initiate a copy-into-video-frame request. | |
234 void AttemptFrameSubscriberCapture(const gfx::Rect& damage_rect); | |
235 | |
236 DelegatedFrameHostClient* const client_; | |
237 ui::Compositor* compositor_; | |
238 | |
239 // The vsync manager we are observing for changes, if any. | |
240 scoped_refptr<ui::CompositorVSyncManager> vsync_manager_; | |
241 | |
242 // The current VSync timebase and interval. These are zero until the first | |
243 // call to SetVSyncParameters(). | |
244 base::TimeTicks vsync_timebase_; | |
245 base::TimeDelta vsync_interval_; | |
246 | |
247 // Overridable tick clock used for testing functions using current time. | |
248 scoped_ptr<base::TickClock> tick_clock_; | |
249 | |
250 // With delegated renderer, this is the last output surface, used to | |
251 // disambiguate resources with the same id coming from different output | |
252 // surfaces. | |
253 uint32_t last_output_surface_id_; | |
254 | |
255 // The number of delegated frame acks that are pending, to delay resource | |
256 // returns until the acks are sent. | |
257 int pending_delegated_ack_count_; | |
258 | |
259 // True after a delegated frame has been skipped, until a frame is not | |
260 // skipped. | |
261 bool skipped_frames_; | |
262 std::vector<ui::LatencyInfo> skipped_latency_info_list_; | |
263 | |
264 scoped_ptr<ui::Layer> right_gutter_; | |
265 scoped_ptr<ui::Layer> bottom_gutter_; | |
266 | |
267 // This is the last root background color from a swapped frame. | |
268 SkColor background_color_; | |
269 | |
270 // State for rendering into a Surface. | |
271 scoped_ptr<cc::SurfaceIdAllocator> id_allocator_; | |
272 scoped_ptr<cc::SurfaceFactory> surface_factory_; | |
273 cc::SurfaceId surface_id_; | |
274 gfx::Size current_surface_size_; | |
275 float current_scale_factor_; | |
276 cc::ReturnedResourceArray surface_returned_resources_; | |
277 | |
278 // This lock is the one waiting for a frame of the right size to come back | |
279 // from the renderer/GPU process. It is set from the moment the aura window | |
280 // got resized, to the moment we committed the renderer frame of the same | |
281 // size. It keeps track of the size we expect from the renderer, and locks the | |
282 // compositor, as well as the UI for a short time to give a chance to the | |
283 // renderer of producing a frame of the right size. | |
284 scoped_ptr<ResizeLock> resize_lock_; | |
285 | |
286 // Keeps track of the current frame size. | |
287 gfx::Size current_frame_size_in_dip_; | |
288 | |
289 // This lock is for waiting for a front surface to become available to draw. | |
290 scoped_refptr<ui::CompositorLock> released_front_lock_; | |
291 | |
292 enum CanLockCompositorState { | |
293 YES_CAN_LOCK, | |
294 // We locked, so at some point we'll need to kick a frame. | |
295 YES_DID_LOCK, | |
296 // No. A lock timed out, we need to kick a new frame before locking again. | |
297 NO_PENDING_RENDERER_FRAME, | |
298 // No. We've got a frame, but it hasn't been committed. | |
299 NO_PENDING_COMMIT, | |
300 }; | |
301 CanLockCompositorState can_lock_compositor_; | |
302 | |
303 base::TimeTicks last_draw_ended_; | |
304 | |
305 // Subscriber that listens to frame presentation events. | |
306 scoped_ptr<RenderWidgetHostViewFrameSubscriber> frame_subscriber_; | |
307 std::vector<scoped_refptr<OwnedMailbox> > idle_frame_subscriber_textures_; | |
308 | |
309 // Callback used to pass the output request to the layer or to a function | |
310 // specified by a test. | |
311 base::Callback<void(scoped_ptr<cc::CopyOutputRequest>)> | |
312 request_copy_of_output_callback_for_testing_; | |
313 | |
314 // YUV readback pipeline. | |
315 scoped_ptr<content::ReadbackYUVInterface> | |
316 yuv_readback_pipeline_; | |
317 | |
318 scoped_ptr<DelegatedFrameEvictor> delegated_frame_evictor_; | |
319 | |
320 cc::BeginFrameSource* begin_frame_source_; | |
321 }; | |
322 | |
323 } // namespace content | |
324 | |
325 #endif // CONTENT_BROWSER_COMPOSITOR_DELEGATED_FRAME_HOST_H_ | |
OLD | NEW |