OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/compositor/delegated_frame_host.h" | 5 #include "content/browser/compositor/delegated_frame_surface_host.h" |
6 | 6 |
7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "cc/output/compositor_frame.h" | 9 #include "cc/output/compositor_frame.h" |
10 #include "cc/output/compositor_frame_ack.h" | 10 #include "cc/output/compositor_frame_ack.h" |
11 #include "cc/output/copy_output_request.h" | 11 #include "cc/output/copy_output_request.h" |
12 #include "cc/resources/single_release_callback.h" | 12 #include "cc/resources/single_release_callback.h" |
13 #include "cc/resources/texture_mailbox.h" | 13 #include "cc/resources/texture_mailbox.h" |
14 #include "cc/surfaces/surface_factory.h" | |
14 #include "content/browser/compositor/resize_lock.h" | 15 #include "content/browser/compositor/resize_lock.h" |
15 #include "content/common/gpu/client/gl_helper.h" | 16 #include "content/common/gpu/client/gl_helper.h" |
16 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" | 17 #include "content/public/browser/render_widget_host_view_frame_subscriber.h" |
17 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
18 #include "media/base/video_frame.h" | 19 #include "media/base/video_frame.h" |
19 #include "media/base/video_util.h" | 20 #include "media/base/video_util.h" |
20 #include "skia/ext/image_operations.h" | 21 #include "skia/ext/image_operations.h" |
21 | 22 |
22 namespace content { | 23 namespace content { |
23 | 24 |
24 //////////////////////////////////////////////////////////////////////////////// | 25 //////////////////////////////////////////////////////////////////////////////// |
25 // DelegatedFrameHostClient | 26 // DelegatedFrameSurfaceHost |
26 | 27 |
27 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { | 28 DelegatedFrameSurfaceHost::DelegatedFrameSurfaceHost( |
28 // On Windows and Linux, holding pointer moves will not help throttling | 29 DelegatedFrameHostClient* client) |
29 // resizes. | |
30 // TODO(piman): on Windows we need to block (nested message loop?) the | |
31 // WM_SIZE event. On Linux we need to throttle at the WM level using | |
32 // _NET_WM_SYNC_REQUEST. | |
33 // TODO(ccameron): Mac browser window resizing is incompletely implemented. | |
34 #if !defined(OS_CHROMEOS) | |
35 return false; | |
36 #else | |
37 return GetDelegatedFrameHost()->ShouldCreateResizeLock(); | |
38 #endif | |
39 } | |
40 | |
41 void DelegatedFrameHostClient::RequestCopyOfOutput( | |
42 scoped_ptr<cc::CopyOutputRequest> request) { | |
43 GetDelegatedFrameHost()->RequestCopyOfOutput(request.Pass()); | |
44 } | |
45 | |
46 //////////////////////////////////////////////////////////////////////////////// | |
47 // DelegatedFrameHost | |
48 | |
49 DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client) | |
50 : client_(client), | 30 : client_(client), |
51 last_output_surface_id_(0), | 31 last_output_surface_id_(0), |
52 pending_delegated_ack_count_(0), | 32 pending_delegated_ack_count_(0), |
53 skipped_frames_(false), | 33 skipped_frames_(false), |
54 can_lock_compositor_(YES_CAN_LOCK), | 34 can_lock_compositor_(YES_CAN_LOCK), |
55 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { | 35 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
56 ImageTransportFactory::GetInstance()->AddObserver(this); | 36 ImageTransportFactory::GetInstance()->AddObserver(this); |
57 } | 37 } |
58 | 38 |
59 void DelegatedFrameHost::WasShown() { | 39 void DelegatedFrameSurfaceHost::WasShown() { |
60 delegated_frame_evictor_->SetVisible(true); | 40 delegated_frame_evictor_->SetVisible(true); |
61 | 41 |
62 if (!released_front_lock_.get()) { | 42 if (!released_front_lock_.get()) { |
63 ui::Compositor* compositor = client_->GetCompositor(); | 43 ui::Compositor* compositor = client_->GetCompositor(); |
64 if (compositor) | 44 if (compositor) |
65 released_front_lock_ = compositor->GetCompositorLock(); | 45 released_front_lock_ = compositor->GetCompositorLock(); |
66 } | 46 } |
67 } | 47 } |
68 | 48 |
69 void DelegatedFrameHost::WasHidden() { | 49 void DelegatedFrameSurfaceHost::WasHidden() { |
70 delegated_frame_evictor_->SetVisible(false); | 50 delegated_frame_evictor_->SetVisible(false); |
71 released_front_lock_ = NULL; | 51 released_front_lock_ = NULL; |
72 } | 52 } |
73 | 53 |
74 void DelegatedFrameHost::MaybeCreateResizeLock() { | 54 void DelegatedFrameSurfaceHost::MaybeCreateResizeLock() { |
75 if (!client_->ShouldCreateResizeLock()) | 55 if (!client_->ShouldCreateResizeLock()) |
76 return; | 56 return; |
77 DCHECK(client_->GetCompositor()); | 57 DCHECK(client_->GetCompositor()); |
78 | 58 |
79 // Listen to changes in the compositor lock state. | 59 // Listen to changes in the compositor lock state. |
80 ui::Compositor* compositor = client_->GetCompositor(); | 60 ui::Compositor* compositor = client_->GetCompositor(); |
81 if (!compositor->HasObserver(this)) | 61 if (!compositor->HasObserver(this)) |
82 compositor->AddObserver(this); | 62 compositor->AddObserver(this); |
83 | 63 |
84 bool defer_compositor_lock = | 64 bool defer_compositor_lock = |
85 can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 65 can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || |
86 can_lock_compositor_ == NO_PENDING_COMMIT; | 66 can_lock_compositor_ == NO_PENDING_COMMIT; |
87 | 67 |
88 if (can_lock_compositor_ == YES_CAN_LOCK) | 68 if (can_lock_compositor_ == YES_CAN_LOCK) |
89 can_lock_compositor_ = YES_DID_LOCK; | 69 can_lock_compositor_ = YES_DID_LOCK; |
90 | 70 |
91 resize_lock_ = client_->CreateResizeLock(defer_compositor_lock); | 71 resize_lock_ = client_->CreateResizeLock(defer_compositor_lock); |
92 } | 72 } |
93 | 73 |
94 bool DelegatedFrameHost::ShouldCreateResizeLock() { | 74 bool DelegatedFrameSurfaceHost::ShouldCreateResizeLock() { |
95 RenderWidgetHostImpl* host = client_->GetHost(); | 75 RenderWidgetHostImpl* host = client_->GetHost(); |
96 | 76 |
97 if (resize_lock_) | 77 if (resize_lock_) |
98 return false; | 78 return false; |
99 | 79 |
100 if (host->should_auto_resize()) | 80 if (host->should_auto_resize()) |
101 return false; | 81 return false; |
102 | 82 |
103 gfx::Size desired_size = client_->DesiredFrameSize(); | 83 gfx::Size desired_size = client_->DesiredFrameSize(); |
104 if (desired_size == current_frame_size_in_dip_ || desired_size.IsEmpty()) | 84 if (desired_size == current_frame_size_in_dip_ || desired_size.IsEmpty()) |
105 return false; | 85 return false; |
106 | 86 |
107 ui::Compositor* compositor = client_->GetCompositor(); | 87 ui::Compositor* compositor = client_->GetCompositor(); |
108 if (!compositor) | 88 if (!compositor) |
109 return false; | 89 return false; |
110 | 90 |
111 return true; | 91 return true; |
112 } | 92 } |
113 | 93 |
114 void DelegatedFrameHost::RequestCopyOfOutput( | 94 void DelegatedFrameSurfaceHost::RequestCopyOfOutput( |
115 scoped_ptr<cc::CopyOutputRequest> request) { | 95 scoped_ptr<cc::CopyOutputRequest> request) { |
116 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); | 96 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); |
117 } | 97 } |
118 | 98 |
119 void DelegatedFrameHost::CopyFromCompositingSurface( | 99 void DelegatedFrameSurfaceHost::CopyFromCompositingSurface( |
120 const gfx::Rect& src_subrect, | 100 const gfx::Rect& src_subrect, |
121 const gfx::Size& dst_size, | 101 const gfx::Size& dst_size, |
122 const base::Callback<void(bool, const SkBitmap&)>& callback, | 102 const base::Callback<void(bool, const SkBitmap&)>& callback, |
123 const SkColorType color_type) { | 103 const SkColorType color_type) { |
124 // Only ARGB888 and RGB565 supported as of now. | 104 // Only ARGB888 and RGB565 supported as of now. |
125 bool format_support = ((color_type == kRGB_565_SkColorType) || | 105 bool format_support = ((color_type == kRGB_565_SkColorType) || |
126 (color_type == kN32_SkColorType)); | 106 (color_type == kN32_SkColorType)); |
127 DCHECK(format_support); | 107 DCHECK(format_support); |
128 if (!CanCopyToBitmap()) { | 108 if (!CanCopyToBitmap()) { |
129 callback.Run(false, SkBitmap()); | 109 callback.Run(false, SkBitmap()); |
130 return; | 110 return; |
131 } | 111 } |
132 | 112 |
133 const gfx::Size& dst_size_in_pixel = | 113 const gfx::Size& dst_size_in_pixel = |
134 client_->ConvertViewSizeToPixel(dst_size); | 114 client_->ConvertViewSizeToPixel(dst_size); |
135 scoped_ptr<cc::CopyOutputRequest> request = | 115 scoped_ptr<cc::CopyOutputRequest> request = |
136 cc::CopyOutputRequest::CreateRequest(base::Bind( | 116 cc::CopyOutputRequest::CreateRequest(base::Bind( |
137 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, | 117 &DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceHasResult, |
138 dst_size_in_pixel, | 118 dst_size_in_pixel, |
139 color_type, | 119 color_type, |
140 callback)); | 120 callback)); |
141 gfx::Rect src_subrect_in_pixel = | 121 gfx::Rect src_subrect_in_pixel = |
142 ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect); | 122 ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect); |
143 request->set_area(src_subrect_in_pixel); | 123 request->set_area(src_subrect_in_pixel); |
144 client_->RequestCopyOfOutput(request.Pass()); | 124 client_->RequestCopyOfOutput(request.Pass()); |
145 } | 125 } |
146 | 126 |
147 void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame( | 127 void DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceToVideoFrame( |
148 const gfx::Rect& src_subrect, | 128 const gfx::Rect& src_subrect, |
149 const scoped_refptr<media::VideoFrame>& target, | 129 const scoped_refptr<media::VideoFrame>& target, |
150 const base::Callback<void(bool)>& callback) { | 130 const base::Callback<void(bool)>& callback) { |
151 if (!CanCopyToVideoFrame()) { | 131 if (!CanCopyToVideoFrame()) { |
152 callback.Run(false); | 132 callback.Run(false); |
153 return; | 133 return; |
154 } | 134 } |
155 | 135 |
156 // Try get a texture to reuse. | 136 // Try get a texture to reuse. |
157 scoped_refptr<OwnedMailbox> subscriber_texture; | 137 scoped_refptr<OwnedMailbox> subscriber_texture; |
158 if (frame_subscriber_) { | 138 if (frame_subscriber_) { |
159 if (!idle_frame_subscriber_textures_.empty()) { | 139 if (!idle_frame_subscriber_textures_.empty()) { |
160 subscriber_texture = idle_frame_subscriber_textures_.back(); | 140 subscriber_texture = idle_frame_subscriber_textures_.back(); |
161 idle_frame_subscriber_textures_.pop_back(); | 141 idle_frame_subscriber_textures_.pop_back(); |
162 } else if (GLHelper* helper = | 142 } else if (GLHelper* helper = |
163 ImageTransportFactory::GetInstance()->GetGLHelper()) { | 143 ImageTransportFactory::GetInstance()->GetGLHelper()) { |
164 subscriber_texture = new OwnedMailbox(helper); | 144 subscriber_texture = new OwnedMailbox(helper); |
165 } | 145 } |
166 } | 146 } |
167 | 147 |
168 scoped_ptr<cc::CopyOutputRequest> request = | 148 scoped_ptr<cc::CopyOutputRequest> request = |
169 cc::CopyOutputRequest::CreateRequest(base::Bind( | 149 cc::CopyOutputRequest::CreateRequest(base::Bind( |
170 &DelegatedFrameHost:: | 150 &DelegatedFrameSurfaceHost:: |
171 CopyFromCompositingSurfaceHasResultForVideo, | 151 CopyFromCompositingSurfaceHasResultForVideo, |
172 AsWeakPtr(), // For caching the ReadbackYUVInterface on this class. | 152 AsWeakPtr(), // For caching the ReadbackYUVInterface on this class. |
173 subscriber_texture, | 153 subscriber_texture, |
174 target, | 154 target, |
175 callback)); | 155 callback)); |
176 gfx::Rect src_subrect_in_pixel = | 156 gfx::Rect src_subrect_in_pixel = |
177 ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect); | 157 ConvertRectToPixel(client_->CurrentDeviceScaleFactor(), src_subrect); |
178 request->set_area(src_subrect_in_pixel); | 158 request->set_area(src_subrect_in_pixel); |
179 if (subscriber_texture.get()) { | 159 if (subscriber_texture.get()) { |
180 request->SetTextureMailbox( | 160 request->SetTextureMailbox( |
181 cc::TextureMailbox(subscriber_texture->mailbox(), | 161 cc::TextureMailbox(subscriber_texture->mailbox(), |
182 subscriber_texture->target(), | 162 subscriber_texture->target(), |
183 subscriber_texture->sync_point())); | 163 subscriber_texture->sync_point())); |
184 } | 164 } |
185 client_->RequestCopyOfOutput(request.Pass()); | 165 client_->RequestCopyOfOutput(request.Pass()); |
186 } | 166 } |
187 | 167 |
188 bool DelegatedFrameHost::CanCopyToBitmap() const { | 168 bool DelegatedFrameSurfaceHost::CanCopyToBitmap() const { |
189 return client_->GetCompositor() && | 169 return client_->GetCompositor() && |
190 client_->GetLayer()->has_external_content(); | 170 client_->GetLayer()->has_external_content(); |
191 } | 171 } |
192 | 172 |
193 bool DelegatedFrameHost::CanCopyToVideoFrame() const { | 173 bool DelegatedFrameSurfaceHost::CanCopyToVideoFrame() const { |
194 return client_->GetCompositor() && | 174 return client_->GetCompositor() && |
195 client_->GetLayer()->has_external_content(); | 175 client_->GetLayer()->has_external_content(); |
196 } | 176 } |
197 | 177 |
198 bool DelegatedFrameHost::CanSubscribeFrame() const { | 178 bool DelegatedFrameSurfaceHost::CanSubscribeFrame() const { |
199 return true; | 179 return true; |
200 } | 180 } |
201 | 181 |
202 void DelegatedFrameHost::BeginFrameSubscription( | 182 void DelegatedFrameSurfaceHost::BeginFrameSubscription( |
203 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { | 183 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { |
204 frame_subscriber_ = subscriber.Pass(); | 184 frame_subscriber_ = subscriber.Pass(); |
205 } | 185 } |
206 | 186 |
207 void DelegatedFrameHost::EndFrameSubscription() { | 187 void DelegatedFrameSurfaceHost::EndFrameSubscription() { |
208 idle_frame_subscriber_textures_.clear(); | 188 idle_frame_subscriber_textures_.clear(); |
209 frame_subscriber_.reset(); | 189 frame_subscriber_.reset(); |
210 } | 190 } |
211 | 191 |
212 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { | 192 bool DelegatedFrameSurfaceHost::HasFrameSubscriber() const { |
193 return frame_subscriber_; | |
194 } | |
195 | |
196 bool DelegatedFrameSurfaceHost::ShouldSkipFrame(gfx::Size size_in_dip) const { | |
213 // Should skip a frame only when another frame from the renderer is guaranteed | 197 // Should skip a frame only when another frame from the renderer is guaranteed |
214 // to replace it. Otherwise may cause hangs when the renderer is waiting for | 198 // to replace it. Otherwise may cause hangs when the renderer is waiting for |
215 // the completion of latency infos (such as when taking a Snapshot.) | 199 // the completion of latency infos (such as when taking a Snapshot.) |
216 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 200 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || |
217 can_lock_compositor_ == NO_PENDING_COMMIT || | 201 can_lock_compositor_ == NO_PENDING_COMMIT || !resize_lock_.get()) |
218 !resize_lock_.get()) | |
219 return false; | 202 return false; |
220 | 203 |
221 return size_in_dip != resize_lock_->expected_size(); | 204 return size_in_dip != resize_lock_->expected_size(); |
222 } | 205 } |
223 | 206 |
224 void DelegatedFrameHost::WasResized() { | 207 void DelegatedFrameSurfaceHost::WasResized() { |
225 MaybeCreateResizeLock(); | 208 MaybeCreateResizeLock(); |
226 } | 209 } |
227 | 210 |
228 gfx::Size DelegatedFrameHost::GetRequestedRendererSize() const { | 211 gfx::Size DelegatedFrameSurfaceHost::GetRequestedRendererSize() const { |
229 if (resize_lock_) | 212 if (resize_lock_) |
230 return resize_lock_->expected_size(); | 213 return resize_lock_->expected_size(); |
231 else | 214 else |
232 return client_->DesiredFrameSize(); | 215 return client_->DesiredFrameSize(); |
233 } | 216 } |
234 | 217 |
235 void DelegatedFrameHost::CheckResizeLock() { | 218 void DelegatedFrameSurfaceHost::CheckResizeLock() { |
236 if (!resize_lock_ || | 219 if (!resize_lock_ || |
237 resize_lock_->expected_size() != current_frame_size_in_dip_) | 220 resize_lock_->expected_size() != current_frame_size_in_dip_) |
238 return; | 221 return; |
239 | 222 |
240 // Since we got the size we were looking for, unlock the compositor. But delay | 223 // Since we got the size we were looking for, unlock the compositor. But delay |
241 // the release of the lock until we've kicked a frame with the new texture, to | 224 // the release of the lock until we've kicked a frame with the new texture, to |
242 // avoid resizing the UI before we have a chance to draw a "good" frame. | 225 // avoid resizing the UI before we have a chance to draw a "good" frame. |
243 resize_lock_->UnlockCompositor(); | 226 resize_lock_->UnlockCompositor(); |
244 ui::Compositor* compositor = client_->GetCompositor(); | 227 ui::Compositor* compositor = client_->GetCompositor(); |
245 if (compositor) { | 228 if (compositor) { |
246 if (!compositor->HasObserver(this)) | 229 if (!compositor->HasObserver(this)) |
247 compositor->AddObserver(this); | 230 compositor->AddObserver(this); |
248 } | 231 } |
249 } | 232 } |
250 | 233 |
251 void DelegatedFrameHost::DidReceiveFrameFromRenderer() { | 234 void DelegatedFrameSurfaceHost::DidReceiveFrameFromRenderer() { |
252 if (frame_subscriber() && CanCopyToVideoFrame()) { | 235 if (frame_subscriber() && CanCopyToVideoFrame()) { |
253 const base::TimeTicks present_time = base::TimeTicks::Now(); | 236 const base::TimeTicks present_time = base::TimeTicks::Now(); |
254 scoped_refptr<media::VideoFrame> frame; | 237 scoped_refptr<media::VideoFrame> frame; |
255 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; | 238 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; |
256 if (frame_subscriber()->ShouldCaptureFrame(present_time, | 239 if (frame_subscriber()->ShouldCaptureFrame( |
257 &frame, &callback)) { | 240 present_time, &frame, &callback)) { |
258 CopyFromCompositingSurfaceToVideoFrame( | 241 CopyFromCompositingSurfaceToVideoFrame( |
259 gfx::Rect(current_frame_size_in_dip_), | 242 gfx::Rect(current_frame_size_in_dip_), |
260 frame, | 243 frame, |
261 base::Bind(callback, present_time)); | 244 base::Bind(callback, present_time)); |
262 } | 245 } |
263 } | 246 } |
264 } | 247 } |
265 | 248 |
266 void DelegatedFrameHost::SwapDelegatedFrame( | 249 void DelegatedFrameSurfaceHost::SwapDelegatedFrame( |
267 uint32 output_surface_id, | 250 uint32 output_surface_id, |
268 scoped_ptr<cc::DelegatedFrameData> frame_data, | 251 scoped_ptr<cc::DelegatedFrameData> frame_data, |
269 float frame_device_scale_factor, | 252 float frame_device_scale_factor, |
270 const std::vector<ui::LatencyInfo>& latency_info) { | 253 const std::vector<ui::LatencyInfo>& latency_info) { |
271 RenderWidgetHostImpl* host = client_->GetHost(); | 254 RenderWidgetHostImpl* host = client_->GetHost(); |
272 DCHECK(!frame_data->render_pass_list.empty()); | 255 DCHECK(!frame_data->render_pass_list.empty()); |
273 | 256 |
274 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); | 257 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); |
275 | 258 |
276 gfx::Size frame_size = root_pass->output_rect.size(); | 259 gfx::Size frame_size = root_pass->output_rect.size(); |
277 gfx::Size frame_size_in_dip = | 260 gfx::Size frame_size_in_dip = |
278 ConvertSizeToDIP(frame_device_scale_factor, frame_size); | 261 ConvertSizeToDIP(frame_device_scale_factor, frame_size); |
279 | 262 |
280 gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect); | 263 gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect); |
281 damage_rect.Intersect(gfx::Rect(frame_size)); | 264 damage_rect.Intersect(gfx::Rect(frame_size)); |
282 gfx::Rect damage_rect_in_dip = | 265 gfx::Rect damage_rect_in_dip = |
283 ConvertRectToDIP(frame_device_scale_factor, damage_rect); | 266 ConvertRectToDIP(frame_device_scale_factor, damage_rect); |
284 | 267 |
285 if (ShouldSkipFrame(frame_size_in_dip)) { | 268 if (ShouldSkipFrame(frame_size_in_dip)) { |
286 cc::CompositorFrameAck ack; | 269 cc::CompositorFrameAck ack; |
287 cc::TransferableResource::ReturnResources(frame_data->resource_list, | 270 cc::TransferableResource::ReturnResources(frame_data->resource_list, |
288 &ack.resources); | 271 &ack.resources); |
289 | 272 |
290 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), | 273 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), |
291 latency_info.begin(), latency_info.end()); | 274 latency_info.begin(), |
275 latency_info.end()); | |
292 | 276 |
293 RenderWidgetHostImpl::SendSwapCompositorFrameAck( | 277 RenderWidgetHostImpl::SendSwapCompositorFrameAck( |
294 host->GetRoutingID(), output_surface_id, | 278 host->GetRoutingID(), |
295 host->GetProcess()->GetID(), ack); | 279 output_surface_id, |
280 host->GetProcess()->GetID(), | |
281 ack); | |
296 skipped_frames_ = true; | 282 skipped_frames_ = true; |
297 return; | 283 return; |
298 } | 284 } |
299 | 285 |
300 if (skipped_frames_) { | 286 if (skipped_frames_) { |
301 skipped_frames_ = false; | 287 skipped_frames_ = false; |
302 damage_rect = gfx::Rect(frame_size); | 288 damage_rect = gfx::Rect(frame_size); |
303 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); | 289 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); |
304 | 290 |
305 // Give the same damage rect to the compositor. | 291 // Give the same damage rect to the compositor. |
306 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); | 292 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); |
307 root_pass->damage_rect = damage_rect; | 293 root_pass->damage_rect = damage_rect; |
308 } | 294 } |
309 | 295 |
310 if (output_surface_id != last_output_surface_id_) { | 296 if (output_surface_id != last_output_surface_id_) { |
311 // Resource ids are scoped by the output surface. | 297 // Resource ids are scoped by the output surface. |
312 // If the originating output surface doesn't match the last one, it | 298 // If the originating output surface doesn't match the last one, it |
313 // indicates the renderer's output surface may have been recreated, in which | 299 // indicates the renderer's output surface may have been recreated, in which |
314 // case we should recreate the DelegatedRendererLayer, to avoid matching | 300 // case we should recreate the DelegatedRendererLayer, to avoid matching |
315 // resources from the old one with resources from the new one which would | 301 // resources from the old one with resources from the new one which would |
316 // have the same id. Changing the layer to showing painted content destroys | 302 // have the same id. Changing the layer to showing painted content destroys |
317 // the DelegatedRendererLayer. | 303 // the DelegatedRendererLayer. |
318 EvictDelegatedFrame(); | 304 EvictDelegatedFrame(); |
319 | 305 |
320 // Drop the cc::DelegatedFrameResourceCollection so that we will not return | 306 // Drop the cc::DelegatedFrameResourceCollection so that we will not return |
321 // any resources from the old output surface with the new output surface id. | 307 // any resources from the old output surface with the new output surface id. |
322 if (resource_collection_.get()) { | |
323 resource_collection_->SetClient(NULL); | |
324 | |
325 if (resource_collection_->LoseAllResources()) | |
326 SendReturnedDelegatedResources(last_output_surface_id_); | |
327 | |
328 resource_collection_ = NULL; | |
329 } | |
330 last_output_surface_id_ = output_surface_id; | 308 last_output_surface_id_ = output_surface_id; |
331 } | 309 } |
332 if (frame_size.IsEmpty()) { | 310 if (frame_size.IsEmpty()) { |
333 DCHECK(frame_data->resource_list.empty()); | 311 DCHECK(frame_data->resource_list.empty()); |
334 EvictDelegatedFrame(); | 312 EvictDelegatedFrame(); |
335 } else { | 313 } else { |
336 if (!resource_collection_) { | 314 if (!surface_factory_) { |
337 resource_collection_ = new cc::DelegatedFrameResourceCollection; | 315 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
338 resource_collection_->SetClient(this); | 316 cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
317 id_allocator_ = factory->CreateSurfaceIdAllocator(); | |
318 surface_factory_ = make_scoped_ptr(new cc::SurfaceFactory(manager, this)); | |
339 } | 319 } |
340 // If the physical frame size changes, we need a new |frame_provider_|. If | 320 if (surface_id_.is_null() || frame_size != current_surface_size_ || |
341 // the physical frame size is the same, but the size in DIP changed, we | |
342 // need to adjust the scale at which the frames will be drawn, and we do | |
343 // this by making a new |frame_provider_| also to ensure the scale change | |
344 // is presented in sync with the new frame content. | |
345 if (!frame_provider_.get() || frame_size != frame_provider_->frame_size() || | |
346 frame_size_in_dip != current_frame_size_in_dip_) { | 321 frame_size_in_dip != current_frame_size_in_dip_) { |
347 frame_provider_ = new cc::DelegatedFrameProvider( | 322 if (!surface_id_.is_null()) |
348 resource_collection_.get(), frame_data.Pass()); | 323 surface_factory_->Destroy(surface_id_); |
349 client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(), | 324 surface_id_ = id_allocator_->GenerateId(); |
350 frame_size_in_dip); | 325 surface_factory_->Create(surface_id_, frame_size); |
351 } else { | 326 client_->GetLayer()->SetShowSurface(surface_id_, frame_size_in_dip); |
352 frame_provider_->SetFrameData(frame_data.Pass()); | 327 current_surface_size_ = frame_size; |
353 } | 328 } |
329 scoped_ptr<cc::CompositorFrame> compositor_frame = | |
330 make_scoped_ptr(new cc::CompositorFrame()); | |
331 compositor_frame->delegated_frame_data = frame_data.Pass(); | |
332 surface_factory_->SubmitFrame(surface_id_, compositor_frame.Pass()); | |
354 } | 333 } |
355 released_front_lock_ = NULL; | 334 released_front_lock_ = NULL; |
356 current_frame_size_in_dip_ = frame_size_in_dip; | 335 current_frame_size_in_dip_ = frame_size_in_dip; |
357 CheckResizeLock(); | 336 CheckResizeLock(); |
358 | 337 |
359 client_->SchedulePaintInRect(damage_rect_in_dip); | 338 client_->SchedulePaintInRect(damage_rect_in_dip); |
360 | 339 |
361 pending_delegated_ack_count_++; | 340 pending_delegated_ack_count_++; |
362 | 341 |
363 ui::Compositor* compositor = client_->GetCompositor(); | 342 ui::Compositor* compositor = client_->GetCompositor(); |
364 if (!compositor) { | 343 if (!compositor) { |
365 SendDelegatedFrameAck(output_surface_id); | 344 SendDelegatedFrameAck(output_surface_id); |
366 } else { | 345 } else { |
367 std::vector<ui::LatencyInfo>::const_iterator it; | 346 std::vector<ui::LatencyInfo>::const_iterator it; |
368 for (it = latency_info.begin(); it != latency_info.end(); ++it) | 347 for (it = latency_info.begin(); it != latency_info.end(); ++it) |
369 compositor->SetLatencyInfo(*it); | 348 compositor->SetLatencyInfo(*it); |
370 // If we've previously skipped any latency infos add them. | 349 // If we've previously skipped any latency infos add them. |
371 for (it = skipped_latency_info_list_.begin(); | 350 for (it = skipped_latency_info_list_.begin(); |
372 it != skipped_latency_info_list_.end(); | 351 it != skipped_latency_info_list_.end(); |
373 ++it) | 352 ++it) |
374 compositor->SetLatencyInfo(*it); | 353 compositor->SetLatencyInfo(*it); |
375 skipped_latency_info_list_.clear(); | 354 skipped_latency_info_list_.clear(); |
376 AddOnCommitCallbackAndDisableLocks( | 355 AddOnCommitCallbackAndDisableLocks( |
377 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, | 356 base::Bind(&DelegatedFrameSurfaceHost::SendDelegatedFrameAck, |
378 AsWeakPtr(), | 357 AsWeakPtr(), |
379 output_surface_id)); | 358 output_surface_id)); |
380 } | 359 } |
381 DidReceiveFrameFromRenderer(); | 360 DidReceiveFrameFromRenderer(); |
382 if (frame_provider_.get()) | 361 if (!surface_id_.is_null()) |
383 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); | 362 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); |
384 // Note: the frame may have been evicted immediately. | 363 // Note: the frame may have been evicted immediately. |
385 } | 364 } |
386 | 365 |
387 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { | 366 void DelegatedFrameSurfaceHost::SetLayerOwner(ui::LayerOwner* layer_owner) { |
367 layer_owner->set_layer_owner_delegate(this); | |
368 } | |
369 | |
370 cc::DelegatedFrameProvider* DelegatedFrameSurfaceHost::FrameProviderForTesting() | |
371 const { | |
372 return NULL; | |
373 } | |
374 | |
375 void DelegatedFrameSurfaceHost::OnCompositingDidCommitForTesting( | |
376 ui::Compositor* compositor) { | |
377 OnCompositingDidCommit(compositor); | |
378 } | |
379 | |
380 void DelegatedFrameSurfaceHost::SendDelegatedFrameAck( | |
381 uint32 output_surface_id) { | |
388 RenderWidgetHostImpl* host = client_->GetHost(); | 382 RenderWidgetHostImpl* host = client_->GetHost(); |
389 cc::CompositorFrameAck ack; | 383 cc::CompositorFrameAck ack; |
390 if (resource_collection_) | 384 if (!surface_returned_resources_.empty()) |
391 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 385 ack.resources.swap(surface_returned_resources_); |
392 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(), | 386 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(), |
393 output_surface_id, | 387 output_surface_id, |
394 host->GetProcess()->GetID(), | 388 host->GetProcess()->GetID(), |
395 ack); | 389 ack); |
396 DCHECK_GT(pending_delegated_ack_count_, 0); | 390 DCHECK_GT(pending_delegated_ack_count_, 0); |
397 pending_delegated_ack_count_--; | 391 pending_delegated_ack_count_--; |
398 } | 392 } |
399 | 393 |
400 void DelegatedFrameHost::UnusedResourcesAreAvailable() { | 394 void DelegatedFrameSurfaceHost::SendReturnedDelegatedResources( |
401 if (pending_delegated_ack_count_) | |
402 return; | |
403 | |
404 SendReturnedDelegatedResources(last_output_surface_id_); | |
405 } | |
406 | |
407 void DelegatedFrameHost::SendReturnedDelegatedResources( | |
408 uint32 output_surface_id) { | 395 uint32 output_surface_id) { |
409 RenderWidgetHostImpl* host = client_->GetHost(); | 396 RenderWidgetHostImpl* host = client_->GetHost(); |
410 DCHECK(resource_collection_); | |
411 | 397 |
412 cc::CompositorFrameAck ack; | 398 cc::CompositorFrameAck ack; |
413 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 399 if (!surface_returned_resources_.empty()) { |
piman
2014/07/25 01:27:42
This if can go away, the only caller is ReturnReso
| |
400 ack.resources.swap(surface_returned_resources_); | |
401 } | |
414 DCHECK(!ack.resources.empty()); | 402 DCHECK(!ack.resources.empty()); |
415 | 403 |
416 RenderWidgetHostImpl::SendReclaimCompositorResources( | 404 RenderWidgetHostImpl::SendReclaimCompositorResources( |
417 host->GetRoutingID(), | 405 host->GetRoutingID(), |
418 output_surface_id, | 406 output_surface_id, |
419 host->GetProcess()->GetID(), | 407 host->GetProcess()->GetID(), |
420 ack); | 408 ack); |
421 } | 409 } |
422 | 410 |
423 void DelegatedFrameHost::EvictDelegatedFrame() { | 411 void DelegatedFrameSurfaceHost::ReturnResources( |
412 const cc::ReturnedResourceArray& resources) { | |
413 if (resources.empty()) | |
414 return; | |
415 std::copy(resources.begin(), | |
416 resources.end(), | |
417 std::back_inserter(surface_returned_resources_)); | |
418 if (!pending_delegated_ack_count_) | |
419 SendReturnedDelegatedResources(last_output_surface_id_); | |
420 } | |
421 | |
422 void DelegatedFrameSurfaceHost::EvictDelegatedFrame() { | |
424 client_->GetLayer()->SetShowPaintedContent(); | 423 client_->GetLayer()->SetShowPaintedContent(); |
425 frame_provider_ = NULL; | 424 if (!surface_id_.is_null()) { |
425 surface_factory_->Destroy(surface_id_); | |
426 surface_id_ = cc::SurfaceId(); | |
427 } | |
426 delegated_frame_evictor_->DiscardedFrame(); | 428 delegated_frame_evictor_->DiscardedFrame(); |
427 } | 429 } |
428 | 430 |
429 // static | 431 // static |
430 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( | 432 void DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceHasResult( |
431 const gfx::Size& dst_size_in_pixel, | 433 const gfx::Size& dst_size_in_pixel, |
432 const SkColorType color_type, | 434 const SkColorType color_type, |
433 const base::Callback<void(bool, const SkBitmap&)>& callback, | 435 const base::Callback<void(bool, const SkBitmap&)>& callback, |
434 scoped_ptr<cc::CopyOutputResult> result) { | 436 scoped_ptr<cc::CopyOutputResult> result) { |
435 if (result->IsEmpty() || result->size().IsEmpty()) { | 437 if (result->IsEmpty() || result->size().IsEmpty()) { |
436 callback.Run(false, SkBitmap()); | 438 callback.Run(false, SkBitmap()); |
437 return; | 439 return; |
438 } | 440 } |
439 | 441 |
440 if (result->HasTexture()) { | 442 if (result->HasTexture()) { |
441 PrepareTextureCopyOutputResult(dst_size_in_pixel, color_type, | 443 PrepareTextureCopyOutputResult( |
442 callback, | 444 dst_size_in_pixel, color_type, callback, result.Pass()); |
443 result.Pass()); | |
444 return; | 445 return; |
445 } | 446 } |
446 | 447 |
447 DCHECK(result->HasBitmap()); | 448 DCHECK(result->HasBitmap()); |
448 PrepareBitmapCopyOutputResult(dst_size_in_pixel, color_type, callback, | 449 PrepareBitmapCopyOutputResult( |
449 result.Pass()); | 450 dst_size_in_pixel, color_type, callback, result.Pass()); |
450 } | 451 } |
451 | 452 |
452 static void CopyFromCompositingSurfaceFinished( | 453 static void CopyFromCompositingSurfaceFinished( |
453 const base::Callback<void(bool, const SkBitmap&)>& callback, | 454 const base::Callback<void(bool, const SkBitmap&)>& callback, |
454 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 455 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
455 scoped_ptr<SkBitmap> bitmap, | 456 scoped_ptr<SkBitmap> bitmap, |
456 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 457 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
457 bool result) { | 458 bool result) { |
458 bitmap_pixels_lock.reset(); | 459 bitmap_pixels_lock.reset(); |
459 | 460 |
460 uint32 sync_point = 0; | 461 uint32 sync_point = 0; |
461 if (result) { | 462 if (result) { |
462 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | 463 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
463 sync_point = gl_helper->InsertSyncPoint(); | 464 sync_point = gl_helper->InsertSyncPoint(); |
464 } | 465 } |
465 bool lost_resource = sync_point == 0; | 466 bool lost_resource = sync_point == 0; |
466 release_callback->Run(sync_point, lost_resource); | 467 release_callback->Run(sync_point, lost_resource); |
467 | 468 |
468 callback.Run(result, *bitmap); | 469 callback.Run(result, *bitmap); |
469 } | 470 } |
470 | 471 |
471 // static | 472 // static |
472 void DelegatedFrameHost::PrepareTextureCopyOutputResult( | 473 void DelegatedFrameSurfaceHost::PrepareTextureCopyOutputResult( |
473 const gfx::Size& dst_size_in_pixel, | 474 const gfx::Size& dst_size_in_pixel, |
474 const SkColorType color_type, | 475 const SkColorType color_type, |
475 const base::Callback<void(bool, const SkBitmap&)>& callback, | 476 const base::Callback<void(bool, const SkBitmap&)>& callback, |
476 scoped_ptr<cc::CopyOutputResult> result) { | 477 scoped_ptr<cc::CopyOutputResult> result) { |
477 DCHECK(result->HasTexture()); | 478 DCHECK(result->HasTexture()); |
478 base::ScopedClosureRunner scoped_callback_runner( | 479 base::ScopedClosureRunner scoped_callback_runner( |
479 base::Bind(callback, false, SkBitmap())); | 480 base::Bind(callback, false, SkBitmap())); |
480 | 481 |
481 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | 482 scoped_ptr<SkBitmap> bitmap(new SkBitmap); |
482 if (!bitmap->allocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), | 483 if (!bitmap->allocPixels(SkImageInfo::Make(dst_size_in_pixel.width(), |
(...skipping 28 matching lines...) Expand all Loading... | |
511 color_type, | 512 color_type, |
512 base::Bind(&CopyFromCompositingSurfaceFinished, | 513 base::Bind(&CopyFromCompositingSurfaceFinished, |
513 callback, | 514 callback, |
514 base::Passed(&release_callback), | 515 base::Passed(&release_callback), |
515 base::Passed(&bitmap), | 516 base::Passed(&bitmap), |
516 base::Passed(&bitmap_pixels_lock)), | 517 base::Passed(&bitmap_pixels_lock)), |
517 GLHelper::SCALER_QUALITY_FAST); | 518 GLHelper::SCALER_QUALITY_FAST); |
518 } | 519 } |
519 | 520 |
520 // static | 521 // static |
521 void DelegatedFrameHost::PrepareBitmapCopyOutputResult( | 522 void DelegatedFrameSurfaceHost::PrepareBitmapCopyOutputResult( |
522 const gfx::Size& dst_size_in_pixel, | 523 const gfx::Size& dst_size_in_pixel, |
523 const SkColorType color_type, | 524 const SkColorType color_type, |
524 const base::Callback<void(bool, const SkBitmap&)>& callback, | 525 const base::Callback<void(bool, const SkBitmap&)>& callback, |
525 scoped_ptr<cc::CopyOutputResult> result) { | 526 scoped_ptr<cc::CopyOutputResult> result) { |
526 if (color_type != kN32_SkColorType) { | 527 if (color_type != kN32_SkColorType) { |
527 NOTIMPLEMENTED(); | 528 NOTIMPLEMENTED(); |
528 callback.Run(false, SkBitmap()); | 529 callback.Run(false, SkBitmap()); |
529 return; | 530 return; |
530 } | 531 } |
531 DCHECK(result->HasBitmap()); | 532 DCHECK(result->HasBitmap()); |
532 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | 533 scoped_ptr<SkBitmap> source = result->TakeBitmap(); |
533 DCHECK(source); | 534 DCHECK(source); |
534 SkBitmap bitmap = skia::ImageOperations::Resize( | 535 SkBitmap bitmap = |
535 *source, | 536 skia::ImageOperations::Resize(*source, |
536 skia::ImageOperations::RESIZE_BEST, | 537 skia::ImageOperations::RESIZE_BEST, |
537 dst_size_in_pixel.width(), | 538 dst_size_in_pixel.width(), |
538 dst_size_in_pixel.height()); | 539 dst_size_in_pixel.height()); |
539 callback.Run(true, bitmap); | 540 callback.Run(true, bitmap); |
540 } | 541 } |
541 | 542 |
542 // static | 543 // static |
543 void DelegatedFrameHost::ReturnSubscriberTexture( | 544 void DelegatedFrameSurfaceHost::ReturnSubscriberTexture( |
544 base::WeakPtr<DelegatedFrameHost> dfh, | 545 base::WeakPtr<DelegatedFrameSurfaceHost> dfh, |
545 scoped_refptr<OwnedMailbox> subscriber_texture, | 546 scoped_refptr<OwnedMailbox> subscriber_texture, |
546 uint32 sync_point) { | 547 uint32 sync_point) { |
547 if (!subscriber_texture.get()) | 548 if (!subscriber_texture.get()) |
548 return; | 549 return; |
549 if (!dfh) | 550 if (!dfh) |
550 return; | 551 return; |
551 | 552 |
552 subscriber_texture->UpdateSyncPoint(sync_point); | 553 subscriber_texture->UpdateSyncPoint(sync_point); |
553 | 554 |
554 if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) | 555 if (dfh->frame_subscriber_ && subscriber_texture->texture_id()) |
555 dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); | 556 dfh->idle_frame_subscriber_textures_.push_back(subscriber_texture); |
556 } | 557 } |
557 | 558 |
558 void DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo( | 559 void DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceFinishedForVideo( |
559 base::WeakPtr<DelegatedFrameHost> dfh, | 560 base::WeakPtr<DelegatedFrameSurfaceHost> dfh, |
560 const base::Callback<void(bool)>& callback, | 561 const base::Callback<void(bool)>& callback, |
561 scoped_refptr<OwnedMailbox> subscriber_texture, | 562 scoped_refptr<OwnedMailbox> subscriber_texture, |
562 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 563 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
563 bool result) { | 564 bool result) { |
564 callback.Run(result); | 565 callback.Run(result); |
565 | 566 |
566 uint32 sync_point = 0; | 567 uint32 sync_point = 0; |
567 if (result) { | 568 if (result) { |
568 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | 569 GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
569 sync_point = gl_helper->InsertSyncPoint(); | 570 sync_point = gl_helper->InsertSyncPoint(); |
570 } | 571 } |
571 if (release_callback) { | 572 if (release_callback) { |
572 // A release callback means the texture came from the compositor, so there | 573 // A release callback means the texture came from the compositor, so there |
573 // should be no |subscriber_texture|. | 574 // should be no |subscriber_texture|. |
574 DCHECK(!subscriber_texture); | 575 DCHECK(!subscriber_texture); |
575 bool lost_resource = sync_point == 0; | 576 bool lost_resource = sync_point == 0; |
576 release_callback->Run(sync_point, lost_resource); | 577 release_callback->Run(sync_point, lost_resource); |
577 } | 578 } |
578 ReturnSubscriberTexture(dfh, subscriber_texture, sync_point); | 579 ReturnSubscriberTexture(dfh, subscriber_texture, sync_point); |
579 } | 580 } |
580 | 581 |
581 // static | 582 // static |
582 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo( | 583 void DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceHasResultForVideo( |
583 base::WeakPtr<DelegatedFrameHost> dfh, | 584 base::WeakPtr<DelegatedFrameSurfaceHost> dfh, |
584 scoped_refptr<OwnedMailbox> subscriber_texture, | 585 scoped_refptr<OwnedMailbox> subscriber_texture, |
585 scoped_refptr<media::VideoFrame> video_frame, | 586 scoped_refptr<media::VideoFrame> video_frame, |
586 const base::Callback<void(bool)>& callback, | 587 const base::Callback<void(bool)>& callback, |
587 scoped_ptr<cc::CopyOutputResult> result) { | 588 scoped_ptr<cc::CopyOutputResult> result) { |
588 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); | 589 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); |
589 base::ScopedClosureRunner scoped_return_subscriber_texture( | 590 base::ScopedClosureRunner scoped_return_subscriber_texture( |
590 base::Bind(&ReturnSubscriberTexture, dfh, subscriber_texture, 0)); | 591 base::Bind(&ReturnSubscriberTexture, dfh, subscriber_texture, 0)); |
591 | 592 |
592 if (!dfh) | 593 if (!dfh) |
593 return; | 594 return; |
594 if (result->IsEmpty()) | 595 if (result->IsEmpty()) |
595 return; | 596 return; |
596 if (result->size().IsEmpty()) | 597 if (result->size().IsEmpty()) |
597 return; | 598 return; |
598 | 599 |
599 // Compute the dest size we want after the letterboxing resize. Make the | 600 // Compute the dest size we want after the letterboxing resize. Make the |
600 // coordinates and sizes even because we letterbox in YUV space | 601 // coordinates and sizes even because we letterbox in YUV space |
601 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to | 602 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to |
602 // line up correctly. | 603 // line up correctly. |
603 // The video frame's coded_size() and the result's size() are both physical | 604 // The video frame's coded_size() and the result's size() are both physical |
604 // pixels. | 605 // pixels. |
605 gfx::Rect region_in_frame = | 606 gfx::Rect region_in_frame = media::ComputeLetterboxRegion( |
606 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), | 607 gfx::Rect(video_frame->coded_size()), result->size()); |
607 result->size()); | |
608 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, | 608 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, |
609 region_in_frame.y() & ~1, | 609 region_in_frame.y() & ~1, |
610 region_in_frame.width() & ~1, | 610 region_in_frame.width() & ~1, |
611 region_in_frame.height() & ~1); | 611 region_in_frame.height() & ~1); |
612 if (region_in_frame.IsEmpty()) | 612 if (region_in_frame.IsEmpty()) |
613 return; | 613 return; |
614 | 614 |
615 if (!result->HasTexture()) { | 615 if (!result->HasTexture()) { |
616 DCHECK(result->HasBitmap()); | 616 DCHECK(result->HasBitmap()); |
617 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap(); | 617 scoped_ptr<SkBitmap> bitmap = result->TakeBitmap(); |
618 // Scale the bitmap to the required size, if necessary. | 618 // Scale the bitmap to the required size, if necessary. |
619 SkBitmap scaled_bitmap; | 619 SkBitmap scaled_bitmap; |
620 if (result->size().width() != region_in_frame.width() || | 620 if (result->size().width() != region_in_frame.width() || |
621 result->size().height() != region_in_frame.height()) { | 621 result->size().height() != region_in_frame.height()) { |
622 skia::ImageOperations::ResizeMethod method = | 622 skia::ImageOperations::ResizeMethod method = |
623 skia::ImageOperations::RESIZE_GOOD; | 623 skia::ImageOperations::RESIZE_GOOD; |
624 scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), method, | 624 scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), |
625 method, | |
625 region_in_frame.width(), | 626 region_in_frame.width(), |
626 region_in_frame.height()); | 627 region_in_frame.height()); |
627 } else { | 628 } else { |
628 scaled_bitmap = *bitmap.get(); | 629 scaled_bitmap = *bitmap.get(); |
629 } | 630 } |
630 | 631 |
631 { | 632 { |
632 SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); | 633 SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); |
633 | 634 |
634 media::CopyRGBToVideoFrame( | 635 media::CopyRGBToVideoFrame( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
685 video_frame->coded_size(), | 686 video_frame->coded_size(), |
686 region_in_frame, | 687 region_in_frame, |
687 true, | 688 true, |
688 true)); | 689 true)); |
689 yuv_readback_pipeline = dfh->yuv_readback_pipeline_.get(); | 690 yuv_readback_pipeline = dfh->yuv_readback_pipeline_.get(); |
690 } | 691 } |
691 | 692 |
692 ignore_result(scoped_callback_runner.Release()); | 693 ignore_result(scoped_callback_runner.Release()); |
693 ignore_result(scoped_return_subscriber_texture.Release()); | 694 ignore_result(scoped_return_subscriber_texture.Release()); |
694 base::Callback<void(bool result)> finished_callback = base::Bind( | 695 base::Callback<void(bool result)> finished_callback = base::Bind( |
695 &DelegatedFrameHost::CopyFromCompositingSurfaceFinishedForVideo, | 696 &DelegatedFrameSurfaceHost::CopyFromCompositingSurfaceFinishedForVideo, |
696 dfh->AsWeakPtr(), | 697 dfh->AsWeakPtr(), |
697 callback, | 698 callback, |
698 subscriber_texture, | 699 subscriber_texture, |
699 base::Passed(&release_callback)); | 700 base::Passed(&release_callback)); |
700 yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(), | 701 yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(), |
701 texture_mailbox.sync_point(), | 702 texture_mailbox.sync_point(), |
702 video_frame.get(), | 703 video_frame.get(), |
703 finished_callback); | 704 finished_callback); |
704 } | 705 } |
705 | 706 |
706 //////////////////////////////////////////////////////////////////////////////// | 707 //////////////////////////////////////////////////////////////////////////////// |
707 // DelegatedFrameHost, ui::CompositorObserver implementation: | 708 // DelegatedFrameSurfaceHost, ui::CompositorObserver implementation: |
708 | 709 |
709 void DelegatedFrameHost::OnCompositingDidCommit( | 710 void DelegatedFrameSurfaceHost::OnCompositingDidCommit( |
710 ui::Compositor* compositor) { | 711 ui::Compositor* compositor) { |
711 RenderWidgetHostImpl* host = client_->GetHost(); | 712 RenderWidgetHostImpl* host = client_->GetHost(); |
712 if (can_lock_compositor_ == NO_PENDING_COMMIT) { | 713 if (can_lock_compositor_ == NO_PENDING_COMMIT) { |
713 can_lock_compositor_ = YES_CAN_LOCK; | 714 can_lock_compositor_ = YES_CAN_LOCK; |
714 if (resize_lock_.get() && resize_lock_->GrabDeferredLock()) | 715 if (resize_lock_.get() && resize_lock_->GrabDeferredLock()) |
715 can_lock_compositor_ = YES_DID_LOCK; | 716 can_lock_compositor_ = YES_DID_LOCK; |
716 } | 717 } |
717 RunOnCommitCallbacks(); | 718 RunOnCommitCallbacks(); |
718 if (resize_lock_ && | 719 if (resize_lock_ && |
719 resize_lock_->expected_size() == current_frame_size_in_dip_) { | 720 resize_lock_->expected_size() == current_frame_size_in_dip_) { |
720 resize_lock_.reset(); | 721 resize_lock_.reset(); |
721 host->WasResized(); | 722 host->WasResized(); |
722 // We may have had a resize while we had the lock (e.g. if the lock expired, | 723 // We may have had a resize while we had the lock (e.g. if the lock expired, |
723 // or if the UI still gave us some resizes), so make sure we grab a new lock | 724 // or if the UI still gave us some resizes), so make sure we grab a new lock |
724 // if necessary. | 725 // if necessary. |
725 MaybeCreateResizeLock(); | 726 MaybeCreateResizeLock(); |
726 } | 727 } |
727 } | 728 } |
728 | 729 |
729 void DelegatedFrameHost::OnCompositingStarted( | 730 void DelegatedFrameSurfaceHost::OnCompositingStarted( |
730 ui::Compositor* compositor, base::TimeTicks start_time) { | 731 ui::Compositor* compositor, |
732 base::TimeTicks start_time) { | |
731 last_draw_ended_ = start_time; | 733 last_draw_ended_ = start_time; |
732 } | 734 } |
733 | 735 |
734 void DelegatedFrameHost::OnCompositingEnded( | 736 void DelegatedFrameSurfaceHost::OnCompositingEnded(ui::Compositor* compositor) { |
737 } | |
738 | |
739 void DelegatedFrameSurfaceHost::OnCompositingAborted( | |
735 ui::Compositor* compositor) { | 740 ui::Compositor* compositor) { |
736 } | 741 } |
737 | 742 |
738 void DelegatedFrameHost::OnCompositingAborted(ui::Compositor* compositor) { | 743 void DelegatedFrameSurfaceHost::OnCompositingLockStateChanged( |
739 } | |
740 | |
741 void DelegatedFrameHost::OnCompositingLockStateChanged( | |
742 ui::Compositor* compositor) { | 744 ui::Compositor* compositor) { |
743 // A compositor lock that is part of a resize lock timed out. We | 745 // A compositor lock that is part of a resize lock timed out. We |
744 // should display a renderer frame. | 746 // should display a renderer frame. |
745 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { | 747 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { |
746 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; | 748 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; |
747 } | 749 } |
748 } | 750 } |
749 | 751 |
750 void DelegatedFrameHost::OnUpdateVSyncParameters( | 752 void DelegatedFrameSurfaceHost::OnUpdateVSyncParameters( |
751 base::TimeTicks timebase, | 753 base::TimeTicks timebase, |
752 base::TimeDelta interval) { | 754 base::TimeDelta interval) { |
753 RenderWidgetHostImpl* host = client_->GetHost(); | 755 RenderWidgetHostImpl* host = client_->GetHost(); |
754 if (client_->IsVisible()) | 756 if (client_->IsVisible()) |
755 host->UpdateVSyncParameters(timebase, interval); | 757 host->UpdateVSyncParameters(timebase, interval); |
756 } | 758 } |
757 | 759 |
758 //////////////////////////////////////////////////////////////////////////////// | 760 //////////////////////////////////////////////////////////////////////////////// |
759 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: | 761 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: |
760 | 762 |
761 void DelegatedFrameHost::OnLostResources() { | 763 void DelegatedFrameSurfaceHost::OnLostResources() { |
762 RenderWidgetHostImpl* host = client_->GetHost(); | 764 RenderWidgetHostImpl* host = client_->GetHost(); |
763 if (frame_provider_.get()) | 765 if (!surface_id_.is_null()) |
764 EvictDelegatedFrame(); | 766 EvictDelegatedFrame(); |
765 idle_frame_subscriber_textures_.clear(); | 767 idle_frame_subscriber_textures_.clear(); |
766 yuv_readback_pipeline_.reset(); | 768 yuv_readback_pipeline_.reset(); |
767 | 769 |
768 host->ScheduleComposite(); | 770 host->ScheduleComposite(); |
769 } | 771 } |
770 | 772 |
771 //////////////////////////////////////////////////////////////////////////////// | 773 //////////////////////////////////////////////////////////////////////////////// |
772 // DelegatedFrameHost, private: | 774 // DelegatedFrameSurfaceHost, private: |
773 | 775 |
774 DelegatedFrameHost::~DelegatedFrameHost() { | 776 DelegatedFrameSurfaceHost::~DelegatedFrameSurfaceHost() { |
775 ImageTransportFactory::GetInstance()->RemoveObserver(this); | 777 ImageTransportFactory::GetInstance()->RemoveObserver(this); |
776 | 778 |
777 if (resource_collection_.get()) | 779 if (!surface_id_.is_null()) |
778 resource_collection_->SetClient(NULL); | 780 surface_factory_->Destroy(surface_id_); |
779 | |
780 DCHECK(!vsync_manager_); | 781 DCHECK(!vsync_manager_); |
781 } | 782 } |
782 | 783 |
783 void DelegatedFrameHost::RunOnCommitCallbacks() { | 784 void DelegatedFrameSurfaceHost::RunOnCommitCallbacks() { |
784 for (std::vector<base::Closure>::const_iterator | 785 for (std::vector<base::Closure>::const_iterator it = |
785 it = on_compositing_did_commit_callbacks_.begin(); | 786 on_compositing_did_commit_callbacks_.begin(); |
786 it != on_compositing_did_commit_callbacks_.end(); ++it) { | 787 it != on_compositing_did_commit_callbacks_.end(); |
788 ++it) { | |
787 it->Run(); | 789 it->Run(); |
788 } | 790 } |
789 on_compositing_did_commit_callbacks_.clear(); | 791 on_compositing_did_commit_callbacks_.clear(); |
790 } | 792 } |
791 | 793 |
792 void DelegatedFrameHost::AddOnCommitCallbackAndDisableLocks( | 794 void DelegatedFrameSurfaceHost::AddOnCommitCallbackAndDisableLocks( |
793 const base::Closure& callback) { | 795 const base::Closure& callback) { |
794 ui::Compositor* compositor = client_->GetCompositor(); | 796 ui::Compositor* compositor = client_->GetCompositor(); |
795 DCHECK(compositor); | 797 DCHECK(compositor); |
796 | 798 |
797 if (!compositor->HasObserver(this)) | 799 if (!compositor->HasObserver(this)) |
798 compositor->AddObserver(this); | 800 compositor->AddObserver(this); |
799 | 801 |
800 can_lock_compositor_ = NO_PENDING_COMMIT; | 802 can_lock_compositor_ = NO_PENDING_COMMIT; |
801 on_compositing_did_commit_callbacks_.push_back(callback); | 803 on_compositing_did_commit_callbacks_.push_back(callback); |
802 } | 804 } |
803 | 805 |
804 void DelegatedFrameHost::AddedToWindow() { | 806 void DelegatedFrameSurfaceHost::AddedToWindow() { |
805 ui::Compositor* compositor = client_->GetCompositor(); | 807 ui::Compositor* compositor = client_->GetCompositor(); |
806 if (compositor) { | 808 if (compositor) { |
807 DCHECK(!vsync_manager_); | 809 DCHECK(!vsync_manager_); |
808 vsync_manager_ = compositor->vsync_manager(); | 810 vsync_manager_ = compositor->vsync_manager(); |
809 vsync_manager_->AddObserver(this); | 811 vsync_manager_->AddObserver(this); |
810 } | 812 } |
811 } | 813 } |
812 | 814 |
813 void DelegatedFrameHost::RemovingFromWindow() { | 815 void DelegatedFrameSurfaceHost::RemovingFromWindow() { |
814 RunOnCommitCallbacks(); | 816 RunOnCommitCallbacks(); |
815 resize_lock_.reset(); | 817 resize_lock_.reset(); |
816 client_->GetHost()->WasResized(); | 818 client_->GetHost()->WasResized(); |
817 ui::Compositor* compositor = client_->GetCompositor(); | 819 ui::Compositor* compositor = client_->GetCompositor(); |
818 if (compositor && compositor->HasObserver(this)) | 820 if (compositor && compositor->HasObserver(this)) |
819 compositor->RemoveObserver(this); | 821 compositor->RemoveObserver(this); |
820 | 822 |
821 if (vsync_manager_) { | 823 if (vsync_manager_) { |
822 vsync_manager_->RemoveObserver(this); | 824 vsync_manager_->RemoveObserver(this); |
823 vsync_manager_ = NULL; | 825 vsync_manager_ = NULL; |
824 } | 826 } |
825 } | 827 } |
826 | 828 |
827 void DelegatedFrameHost::LockResources() { | 829 void DelegatedFrameSurfaceHost::LockResources() { |
828 DCHECK(frame_provider_); | 830 DCHECK(!surface_id_.is_null()); |
829 delegated_frame_evictor_->LockFrame(); | 831 delegated_frame_evictor_->LockFrame(); |
830 } | 832 } |
831 | 833 |
832 void DelegatedFrameHost::UnlockResources() { | 834 void DelegatedFrameSurfaceHost::UnlockResources() { |
833 DCHECK(frame_provider_); | 835 DCHECK(!surface_id_.is_null()); |
834 delegated_frame_evictor_->UnlockFrame(); | 836 delegated_frame_evictor_->UnlockFrame(); |
835 } | 837 } |
836 | 838 |
837 //////////////////////////////////////////////////////////////////////////////// | 839 //////////////////////////////////////////////////////////////////////////////// |
838 // DelegatedFrameHost, ui::LayerOwnerDelegate implementation: | 840 // DelegatedFrameSurfaceHost, ui::LayerOwnerDelegate implementation: |
839 | 841 |
840 void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, | 842 void DelegatedFrameSurfaceHost::OnLayerRecreated(ui::Layer* old_layer, |
841 ui::Layer* new_layer) { | 843 ui::Layer* new_layer) { |
842 // The new_layer is the one that will be used by our Window, so that's the one | 844 // The new_layer is the one that will be used by our Window, so that's the one |
843 // that should keep our frame. old_layer will be returned to the | 845 // that should keep our frame. old_layer will be returned to the |
844 // RecreateLayer caller, and should have a copy. | 846 // RecreateLayer caller, and should have a copy. |
845 if (frame_provider_.get()) { | 847 if (!surface_id_.is_null()) { |
846 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 848 client_->GetLayer()->SetShowSurface(surface_id_, |
847 current_frame_size_in_dip_); | 849 current_frame_size_in_dip_); |
848 } | 850 } |
849 } | 851 } |
850 | 852 |
851 } // namespace content | 853 } // namespace content |
852 | |
OLD | NEW |