| 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_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" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 if (!surface) { | 46 if (!surface) { |
| 47 LOG(ERROR) << "Attempting to require callback on nonexistent surface"; | 47 LOG(ERROR) << "Attempting to require callback on nonexistent surface"; |
| 48 return; | 48 return; |
| 49 } | 49 } |
| 50 surface->AddDestructionDependency(sequence); | 50 surface->AddDestructionDependency(sequence); |
| 51 } | 51 } |
| 52 | 52 |
| 53 } // namespace | 53 } // namespace |
| 54 | 54 |
| 55 //////////////////////////////////////////////////////////////////////////////// | 55 //////////////////////////////////////////////////////////////////////////////// |
| 56 // DelegatedFrameHostClient | |
| 57 | |
| 58 bool DelegatedFrameHostClient::ShouldCreateResizeLock() { | |
| 59 // On Windows and Linux, holding pointer moves will not help throttling | |
| 60 // resizes. | |
| 61 // TODO(piman): on Windows we need to block (nested message loop?) the | |
| 62 // WM_SIZE event. On Linux we need to throttle at the WM level using | |
| 63 // _NET_WM_SYNC_REQUEST. | |
| 64 // TODO(ccameron): Mac browser window resizing is incompletely implemented. | |
| 65 #if !defined(OS_CHROMEOS) | |
| 66 return false; | |
| 67 #else | |
| 68 return GetDelegatedFrameHost()->ShouldCreateResizeLock(); | |
| 69 #endif | |
| 70 } | |
| 71 | |
| 72 void DelegatedFrameHostClient::RequestCopyOfOutput( | |
| 73 scoped_ptr<cc::CopyOutputRequest> request) { | |
| 74 GetDelegatedFrameHost()->RequestCopyOfOutput(request.Pass()); | |
| 75 } | |
| 76 | |
| 77 //////////////////////////////////////////////////////////////////////////////// | |
| 78 // DelegatedFrameHost | 56 // DelegatedFrameHost |
| 79 | 57 |
| 80 DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client) | 58 DelegatedFrameHost::DelegatedFrameHost(DelegatedFrameHostClient* client, |
| 59 ui::Layer* layer) |
| 81 : client_(client), | 60 : client_(client), |
| 61 layer_(layer), |
| 82 compositor_(nullptr), | 62 compositor_(nullptr), |
| 83 use_surfaces_(UseSurfacesEnabled()), | 63 use_surfaces_(UseSurfacesEnabled()), |
| 84 last_output_surface_id_(0), | 64 last_output_surface_id_(0), |
| 85 pending_delegated_ack_count_(0), | 65 pending_delegated_ack_count_(0), |
| 86 skipped_frames_(false), | 66 skipped_frames_(false), |
| 87 current_scale_factor_(1.f), | 67 current_scale_factor_(1.f), |
| 88 can_lock_compositor_(YES_CAN_LOCK), | 68 can_lock_compositor_(YES_CAN_LOCK), |
| 89 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { | 69 delegated_frame_evictor_(new DelegatedFrameEvictor(this)) { |
| 90 ImageTransportFactory::GetInstance()->AddObserver(this); | 70 ImageTransportFactory::GetInstance()->AddObserver(this); |
| 91 } | 71 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 107 bool DelegatedFrameHost::HasSavedFrame() { | 87 bool DelegatedFrameHost::HasSavedFrame() { |
| 108 return delegated_frame_evictor_->HasFrame(); | 88 return delegated_frame_evictor_->HasFrame(); |
| 109 } | 89 } |
| 110 | 90 |
| 111 void DelegatedFrameHost::WasHidden() { | 91 void DelegatedFrameHost::WasHidden() { |
| 112 delegated_frame_evictor_->SetVisible(false); | 92 delegated_frame_evictor_->SetVisible(false); |
| 113 released_front_lock_ = NULL; | 93 released_front_lock_ = NULL; |
| 114 } | 94 } |
| 115 | 95 |
| 116 void DelegatedFrameHost::MaybeCreateResizeLock() { | 96 void DelegatedFrameHost::MaybeCreateResizeLock() { |
| 117 if (!client_->ShouldCreateResizeLock()) | 97 if (!ShouldCreateResizeLock()) |
| 118 return; | 98 return; |
| 119 DCHECK(compositor_); | 99 DCHECK(compositor_); |
| 120 | 100 |
| 121 bool defer_compositor_lock = | 101 bool defer_compositor_lock = |
| 122 can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 102 can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || |
| 123 can_lock_compositor_ == NO_PENDING_COMMIT; | 103 can_lock_compositor_ == NO_PENDING_COMMIT; |
| 124 | 104 |
| 125 if (can_lock_compositor_ == YES_CAN_LOCK) | 105 if (can_lock_compositor_ == YES_CAN_LOCK) |
| 126 can_lock_compositor_ = YES_DID_LOCK; | 106 can_lock_compositor_ = YES_DID_LOCK; |
| 127 | 107 |
| 128 resize_lock_ = client_->CreateResizeLock(defer_compositor_lock); | 108 resize_lock_ = |
| 109 client_->DelegatedFrameHostCreateResizeLock(defer_compositor_lock); |
| 129 } | 110 } |
| 130 | 111 |
| 131 bool DelegatedFrameHost::ShouldCreateResizeLock() { | 112 bool DelegatedFrameHost::ShouldCreateResizeLock() { |
| 132 RenderWidgetHostImpl* host = client_->GetHost(); | 113 if (!client_->DelegatedFrameCanCreateResizeLock()) |
| 114 return false; |
| 133 | 115 |
| 134 if (resize_lock_) | 116 if (resize_lock_) |
| 135 return false; | 117 return false; |
| 136 | 118 |
| 137 if (host->auto_resize_enabled()) | 119 gfx::Size desired_size = client_->DelegatedFrameHostDesiredSizeInDIP(); |
| 138 return false; | |
| 139 | |
| 140 gfx::Size desired_size = client_->DesiredFrameSize(); | |
| 141 if (desired_size == current_frame_size_in_dip_ || desired_size.IsEmpty()) | 120 if (desired_size == current_frame_size_in_dip_ || desired_size.IsEmpty()) |
| 142 return false; | 121 return false; |
| 143 | 122 |
| 144 if (!compositor_) | 123 if (!compositor_) |
| 145 return false; | 124 return false; |
| 146 | 125 |
| 147 return true; | 126 return true; |
| 148 } | 127 } |
| 149 | 128 |
| 150 void DelegatedFrameHost::RequestCopyOfOutput( | |
| 151 scoped_ptr<cc::CopyOutputRequest> request) { | |
| 152 client_->GetLayer()->RequestCopyOfOutput(request.Pass()); | |
| 153 } | |
| 154 | |
| 155 void DelegatedFrameHost::CopyFromCompositingSurface( | 129 void DelegatedFrameHost::CopyFromCompositingSurface( |
| 156 const gfx::Rect& src_subrect, | 130 const gfx::Rect& src_subrect, |
| 157 const gfx::Size& output_size, | 131 const gfx::Size& output_size, |
| 158 ReadbackRequestCallback& callback, | 132 ReadbackRequestCallback& callback, |
| 159 const SkColorType color_type) { | 133 const SkColorType color_type) { |
| 160 // Only ARGB888 and RGB565 supported as of now. | 134 // Only ARGB888 and RGB565 supported as of now. |
| 161 bool format_support = ((color_type == kAlpha_8_SkColorType) || | 135 bool format_support = ((color_type == kAlpha_8_SkColorType) || |
| 162 (color_type == kRGB_565_SkColorType) || | 136 (color_type == kRGB_565_SkColorType) || |
| 163 (color_type == kN32_SkColorType)); | 137 (color_type == kN32_SkColorType)); |
| 164 DCHECK(format_support); | 138 DCHECK(format_support); |
| 165 if (!CanCopyToBitmap()) { | 139 if (!CanCopyToBitmap()) { |
| 166 callback.Run(SkBitmap(), content::READBACK_SURFACE_UNAVAILABLE); | 140 callback.Run(SkBitmap(), content::READBACK_SURFACE_UNAVAILABLE); |
| 167 return; | 141 return; |
| 168 } | 142 } |
| 169 | 143 |
| 170 scoped_ptr<cc::CopyOutputRequest> request = | 144 scoped_ptr<cc::CopyOutputRequest> request = |
| 171 cc::CopyOutputRequest::CreateRequest(base::Bind( | 145 cc::CopyOutputRequest::CreateRequest(base::Bind( |
| 172 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, | 146 &DelegatedFrameHost::CopyFromCompositingSurfaceHasResult, |
| 173 output_size, | 147 output_size, |
| 174 color_type, | 148 color_type, |
| 175 callback)); | 149 callback)); |
| 176 if (!src_subrect.IsEmpty()) | 150 if (!src_subrect.IsEmpty()) |
| 177 request->set_area(src_subrect); | 151 request->set_area(src_subrect); |
| 178 client_->RequestCopyOfOutput(request.Pass()); | 152 RequestCopyOfOutput(request.Pass()); |
| 179 } | 153 } |
| 180 | 154 |
| 181 void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame( | 155 void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame( |
| 182 const gfx::Rect& src_subrect, | 156 const gfx::Rect& src_subrect, |
| 183 const scoped_refptr<media::VideoFrame>& target, | 157 const scoped_refptr<media::VideoFrame>& target, |
| 184 const base::Callback<void(bool)>& callback) { | 158 const base::Callback<void(bool)>& callback) { |
| 185 if (!CanCopyToVideoFrame()) { | 159 if (!CanCopyToVideoFrame()) { |
| 186 callback.Run(false); | 160 callback.Run(false); |
| 187 return; | 161 return; |
| 188 } | 162 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 207 subscriber_texture, | 181 subscriber_texture, |
| 208 target, | 182 target, |
| 209 callback)); | 183 callback)); |
| 210 request->set_area(src_subrect); | 184 request->set_area(src_subrect); |
| 211 if (subscriber_texture.get()) { | 185 if (subscriber_texture.get()) { |
| 212 request->SetTextureMailbox( | 186 request->SetTextureMailbox( |
| 213 cc::TextureMailbox(subscriber_texture->mailbox(), | 187 cc::TextureMailbox(subscriber_texture->mailbox(), |
| 214 subscriber_texture->target(), | 188 subscriber_texture->target(), |
| 215 subscriber_texture->sync_point())); | 189 subscriber_texture->sync_point())); |
| 216 } | 190 } |
| 217 client_->RequestCopyOfOutput(request.Pass()); | 191 RequestCopyOfOutput(request.Pass()); |
| 218 } | 192 } |
| 219 | 193 |
| 220 bool DelegatedFrameHost::CanCopyToBitmap() const { | 194 bool DelegatedFrameHost::CanCopyToBitmap() const { |
| 221 return compositor_ && client_->GetLayer()->has_external_content(); | 195 return compositor_ && layer_->has_external_content(); |
| 222 } | 196 } |
| 223 | 197 |
| 224 bool DelegatedFrameHost::CanCopyToVideoFrame() const { | 198 bool DelegatedFrameHost::CanCopyToVideoFrame() const { |
| 225 return compositor_ && client_->GetLayer()->has_external_content(); | 199 return compositor_ && layer_->has_external_content(); |
| 226 } | 200 } |
| 227 | 201 |
| 228 bool DelegatedFrameHost::CanSubscribeFrame() const { | 202 bool DelegatedFrameHost::CanSubscribeFrame() const { |
| 229 return true; | 203 return true; |
| 230 } | 204 } |
| 231 | 205 |
| 232 void DelegatedFrameHost::BeginFrameSubscription( | 206 void DelegatedFrameHost::BeginFrameSubscription( |
| 233 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { | 207 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { |
| 234 frame_subscriber_ = subscriber.Pass(); | 208 frame_subscriber_ = subscriber.Pass(); |
| 235 } | 209 } |
| 236 | 210 |
| 237 void DelegatedFrameHost::EndFrameSubscription() { | 211 void DelegatedFrameHost::EndFrameSubscription() { |
| 238 idle_frame_subscriber_textures_.clear(); | 212 idle_frame_subscriber_textures_.clear(); |
| 239 frame_subscriber_.reset(); | 213 frame_subscriber_.reset(); |
| 240 } | 214 } |
| 241 | 215 |
| 242 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { | 216 bool DelegatedFrameHost::ShouldSkipFrame(gfx::Size size_in_dip) const { |
| 243 // Should skip a frame only when another frame from the renderer is guaranteed | 217 // Should skip a frame only when another frame from the renderer is guaranteed |
| 244 // to replace it. Otherwise may cause hangs when the renderer is waiting for | 218 // to replace it. Otherwise may cause hangs when the renderer is waiting for |
| 245 // the completion of latency infos (such as when taking a Snapshot.) | 219 // the completion of latency infos (such as when taking a Snapshot.) |
| 246 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || | 220 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || |
| 247 can_lock_compositor_ == NO_PENDING_COMMIT || | 221 can_lock_compositor_ == NO_PENDING_COMMIT || |
| 248 !resize_lock_.get()) | 222 !resize_lock_.get()) |
| 249 return false; | 223 return false; |
| 250 | 224 |
| 251 return size_in_dip != resize_lock_->expected_size(); | 225 return size_in_dip != resize_lock_->expected_size(); |
| 252 } | 226 } |
| 253 | 227 |
| 254 void DelegatedFrameHost::WasResized() { | 228 void DelegatedFrameHost::WasResized() { |
| 255 if (client_->DesiredFrameSize() != current_frame_size_in_dip_ && | 229 if (client_->DelegatedFrameHostDesiredSizeInDIP() != |
| 256 client_->GetHost()->is_hidden()) | 230 current_frame_size_in_dip_ && |
| 231 !client_->DelegatedFrameHostIsVisible()) |
| 257 EvictDelegatedFrame(); | 232 EvictDelegatedFrame(); |
| 258 MaybeCreateResizeLock(); | 233 MaybeCreateResizeLock(); |
| 259 } | 234 } |
| 260 | 235 |
| 261 gfx::Size DelegatedFrameHost::GetRequestedRendererSize() const { | 236 gfx::Size DelegatedFrameHost::GetRequestedRendererSize() const { |
| 262 if (resize_lock_) | 237 if (resize_lock_) |
| 263 return resize_lock_->expected_size(); | 238 return resize_lock_->expected_size(); |
| 264 else | 239 else |
| 265 return client_->DesiredFrameSize(); | 240 return client_->DelegatedFrameHostDesiredSizeInDIP(); |
| 266 } | 241 } |
| 267 | 242 |
| 268 void DelegatedFrameHost::CheckResizeLock() { | 243 void DelegatedFrameHost::CheckResizeLock() { |
| 269 if (!resize_lock_ || | 244 if (!resize_lock_ || |
| 270 resize_lock_->expected_size() != current_frame_size_in_dip_) | 245 resize_lock_->expected_size() != current_frame_size_in_dip_) |
| 271 return; | 246 return; |
| 272 | 247 |
| 273 // Since we got the size we were looking for, unlock the compositor. But delay | 248 // Since we got the size we were looking for, unlock the compositor. But delay |
| 274 // the release of the lock until we've kicked a frame with the new texture, to | 249 // the release of the lock until we've kicked a frame with the new texture, to |
| 275 // avoid resizing the UI before we have a chance to draw a "good" frame. | 250 // avoid resizing the UI before we have a chance to draw a "good" frame. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 299 frame, | 274 frame, |
| 300 base::Bind(callback, present_time)); | 275 base::Bind(callback, present_time)); |
| 301 } | 276 } |
| 302 } | 277 } |
| 303 | 278 |
| 304 void DelegatedFrameHost::SwapDelegatedFrame( | 279 void DelegatedFrameHost::SwapDelegatedFrame( |
| 305 uint32 output_surface_id, | 280 uint32 output_surface_id, |
| 306 scoped_ptr<cc::DelegatedFrameData> frame_data, | 281 scoped_ptr<cc::DelegatedFrameData> frame_data, |
| 307 float frame_device_scale_factor, | 282 float frame_device_scale_factor, |
| 308 const std::vector<ui::LatencyInfo>& latency_info) { | 283 const std::vector<ui::LatencyInfo>& latency_info) { |
| 309 RenderWidgetHostImpl* host = client_->GetHost(); | |
| 310 DCHECK(!frame_data->render_pass_list.empty()); | 284 DCHECK(!frame_data->render_pass_list.empty()); |
| 311 | 285 |
| 312 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); | 286 cc::RenderPass* root_pass = frame_data->render_pass_list.back(); |
| 313 | 287 |
| 314 gfx::Size frame_size = root_pass->output_rect.size(); | 288 gfx::Size frame_size = root_pass->output_rect.size(); |
| 315 gfx::Size frame_size_in_dip = | 289 gfx::Size frame_size_in_dip = |
| 316 gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size); | 290 gfx::ConvertSizeToDIP(frame_device_scale_factor, frame_size); |
| 317 | 291 |
| 318 gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect); | 292 gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect); |
| 319 damage_rect.Intersect(gfx::Rect(frame_size)); | 293 damage_rect.Intersect(gfx::Rect(frame_size)); |
| 320 gfx::Rect damage_rect_in_dip = | 294 gfx::Rect damage_rect_in_dip = |
| 321 gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect); | 295 gfx::ConvertRectToDIP(frame_device_scale_factor, damage_rect); |
| 322 | 296 |
| 323 if (ShouldSkipFrame(frame_size_in_dip)) { | 297 if (ShouldSkipFrame(frame_size_in_dip)) { |
| 324 cc::CompositorFrameAck ack; | 298 cc::CompositorFrameAck ack; |
| 325 cc::TransferableResource::ReturnResources(frame_data->resource_list, | 299 cc::TransferableResource::ReturnResources(frame_data->resource_list, |
| 326 &ack.resources); | 300 &ack.resources); |
| 327 | 301 |
| 328 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), | 302 skipped_latency_info_list_.insert(skipped_latency_info_list_.end(), |
| 329 latency_info.begin(), latency_info.end()); | 303 latency_info.begin(), latency_info.end()); |
| 330 | 304 |
| 331 RenderWidgetHostImpl::SendSwapCompositorFrameAck( | 305 client_->DelegatedFrameHostSendCompositorSwapAck(output_surface_id, ack); |
| 332 host->GetRoutingID(), output_surface_id, | |
| 333 host->GetProcess()->GetID(), ack); | |
| 334 skipped_frames_ = true; | 306 skipped_frames_ = true; |
| 335 return; | 307 return; |
| 336 } | 308 } |
| 337 | 309 |
| 338 if (skipped_frames_) { | 310 if (skipped_frames_) { |
| 339 skipped_frames_ = false; | 311 skipped_frames_ = false; |
| 340 damage_rect = gfx::Rect(frame_size); | 312 damage_rect = gfx::Rect(frame_size); |
| 341 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); | 313 damage_rect_in_dip = gfx::Rect(frame_size_in_dip); |
| 342 | 314 |
| 343 // Give the same damage rect to the compositor. | 315 // Give the same damage rect to the compositor. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 surface_factory_ = | 357 surface_factory_ = |
| 386 make_scoped_ptr(new cc::SurfaceFactory(manager, this)); | 358 make_scoped_ptr(new cc::SurfaceFactory(manager, this)); |
| 387 } | 359 } |
| 388 if (surface_id_.is_null() || frame_size != current_surface_size_ || | 360 if (surface_id_.is_null() || frame_size != current_surface_size_ || |
| 389 frame_size_in_dip != current_frame_size_in_dip_) { | 361 frame_size_in_dip != current_frame_size_in_dip_) { |
| 390 if (!surface_id_.is_null()) | 362 if (!surface_id_.is_null()) |
| 391 surface_factory_->Destroy(surface_id_); | 363 surface_factory_->Destroy(surface_id_); |
| 392 surface_id_ = id_allocator_->GenerateId(); | 364 surface_id_ = id_allocator_->GenerateId(); |
| 393 surface_factory_->Create(surface_id_); | 365 surface_factory_->Create(surface_id_); |
| 394 // manager must outlive compositors using it. | 366 // manager must outlive compositors using it. |
| 395 client_->GetLayer()->SetShowSurface( | 367 layer_->SetShowSurface( |
| 396 surface_id_, | 368 surface_id_, |
| 397 base::Bind(&SatisfyCallback, base::Unretained(manager)), | 369 base::Bind(&SatisfyCallback, base::Unretained(manager)), |
| 398 base::Bind(&RequireCallback, base::Unretained(manager)), frame_size, | 370 base::Bind(&RequireCallback, base::Unretained(manager)), frame_size, |
| 399 frame_device_scale_factor, frame_size_in_dip); | 371 frame_device_scale_factor, frame_size_in_dip); |
| 400 current_surface_size_ = frame_size; | 372 current_surface_size_ = frame_size; |
| 401 current_scale_factor_ = frame_device_scale_factor; | 373 current_scale_factor_ = frame_device_scale_factor; |
| 402 } | 374 } |
| 403 scoped_ptr<cc::CompositorFrame> compositor_frame = | 375 scoped_ptr<cc::CompositorFrame> compositor_frame = |
| 404 make_scoped_ptr(new cc::CompositorFrame()); | 376 make_scoped_ptr(new cc::CompositorFrame()); |
| 405 compositor_frame->delegated_frame_data = frame_data.Pass(); | 377 compositor_frame->delegated_frame_data = frame_data.Pass(); |
| 406 | 378 |
| 407 compositor_frame->metadata.latency_info.swap(skipped_latency_info_list_); | 379 compositor_frame->metadata.latency_info.swap(skipped_latency_info_list_); |
| 408 compositor_frame->metadata.latency_info.insert( | 380 compositor_frame->metadata.latency_info.insert( |
| 409 compositor_frame->metadata.latency_info.end(), | 381 compositor_frame->metadata.latency_info.end(), |
| 410 latency_info.begin(), | 382 latency_info.begin(), |
| 411 latency_info.end()); | 383 latency_info.end()); |
| 412 | 384 |
| 413 gfx::Size desired_size = client_->DesiredFrameSize(); | 385 gfx::Size desired_size = client_->DelegatedFrameHostDesiredSizeInDIP(); |
| 414 if (desired_size != frame_size_in_dip && !desired_size.IsEmpty()) | 386 if (desired_size != frame_size_in_dip && !desired_size.IsEmpty()) |
| 415 immediate_ack = true; | 387 immediate_ack = true; |
| 416 | 388 |
| 417 cc::SurfaceFactory::DrawCallback ack_callback; | 389 cc::SurfaceFactory::DrawCallback ack_callback; |
| 418 if (compositor_ && !immediate_ack) { | 390 if (compositor_ && !immediate_ack) { |
| 419 ack_callback = base::Bind(&DelegatedFrameHost::SurfaceDrawn, | 391 ack_callback = base::Bind(&DelegatedFrameHost::SurfaceDrawn, |
| 420 AsWeakPtr(), output_surface_id); | 392 AsWeakPtr(), output_surface_id); |
| 421 } | 393 } |
| 422 surface_factory_->SubmitFrame( | 394 surface_factory_->SubmitFrame( |
| 423 surface_id_, compositor_frame.Pass(), ack_callback); | 395 surface_id_, compositor_frame.Pass(), ack_callback); |
| 424 } else { | 396 } else { |
| 425 if (!resource_collection_.get()) { | 397 if (!resource_collection_.get()) { |
| 426 resource_collection_ = new cc::DelegatedFrameResourceCollection; | 398 resource_collection_ = new cc::DelegatedFrameResourceCollection; |
| 427 resource_collection_->SetClient(this); | 399 resource_collection_->SetClient(this); |
| 428 } | 400 } |
| 429 // If the physical frame size changes, we need a new |frame_provider_|. If | 401 // If the physical frame size changes, we need a new |frame_provider_|. If |
| 430 // the physical frame size is the same, but the size in DIP changed, we | 402 // the physical frame size is the same, but the size in DIP changed, we |
| 431 // need to adjust the scale at which the frames will be drawn, and we do | 403 // need to adjust the scale at which the frames will be drawn, and we do |
| 432 // this by making a new |frame_provider_| also to ensure the scale change | 404 // this by making a new |frame_provider_| also to ensure the scale change |
| 433 // is presented in sync with the new frame content. | 405 // is presented in sync with the new frame content. |
| 434 if (!frame_provider_.get() || | 406 if (!frame_provider_.get() || |
| 435 frame_size != frame_provider_->frame_size() || | 407 frame_size != frame_provider_->frame_size() || |
| 436 frame_size_in_dip != current_frame_size_in_dip_) { | 408 frame_size_in_dip != current_frame_size_in_dip_) { |
| 437 frame_provider_ = new cc::DelegatedFrameProvider( | 409 frame_provider_ = new cc::DelegatedFrameProvider( |
| 438 resource_collection_.get(), frame_data.Pass()); | 410 resource_collection_.get(), frame_data.Pass()); |
| 439 client_->GetLayer()->SetShowDelegatedContent(frame_provider_.get(), | 411 layer_->SetShowDelegatedContent(frame_provider_.get(), |
| 440 frame_size_in_dip); | 412 frame_size_in_dip); |
| 441 } else { | 413 } else { |
| 442 frame_provider_->SetFrameData(frame_data.Pass()); | 414 frame_provider_->SetFrameData(frame_data.Pass()); |
| 443 } | 415 } |
| 444 } | 416 } |
| 445 } | 417 } |
| 446 released_front_lock_ = NULL; | 418 released_front_lock_ = NULL; |
| 447 current_frame_size_in_dip_ = frame_size_in_dip; | 419 current_frame_size_in_dip_ = frame_size_in_dip; |
| 448 CheckResizeLock(); | 420 CheckResizeLock(); |
| 449 | 421 |
| 450 if (!damage_rect_in_dip.IsEmpty()) | 422 if (!damage_rect_in_dip.IsEmpty()) |
| 451 client_->GetLayer()->OnDelegatedFrameDamage(damage_rect_in_dip); | 423 layer_->OnDelegatedFrameDamage(damage_rect_in_dip); |
| 452 | 424 |
| 453 pending_delegated_ack_count_++; | 425 pending_delegated_ack_count_++; |
| 454 | 426 |
| 455 if (immediate_ack) { | 427 if (immediate_ack) { |
| 456 SendDelegatedFrameAck(output_surface_id); | 428 SendDelegatedFrameAck(output_surface_id); |
| 457 } else if (!use_surfaces_) { | 429 } else if (!use_surfaces_) { |
| 458 std::vector<ui::LatencyInfo>::const_iterator it; | 430 std::vector<ui::LatencyInfo>::const_iterator it; |
| 459 for (it = latency_info.begin(); it != latency_info.end(); ++it) | 431 for (it = latency_info.begin(); it != latency_info.end(); ++it) |
| 460 compositor_->SetLatencyInfo(*it); | 432 compositor_->SetLatencyInfo(*it); |
| 461 // If we've previously skipped any latency infos add them. | 433 // If we've previously skipped any latency infos add them. |
| 462 for (it = skipped_latency_info_list_.begin(); | 434 for (it = skipped_latency_info_list_.begin(); |
| 463 it != skipped_latency_info_list_.end(); | 435 it != skipped_latency_info_list_.end(); |
| 464 ++it) | 436 ++it) |
| 465 compositor_->SetLatencyInfo(*it); | 437 compositor_->SetLatencyInfo(*it); |
| 466 skipped_latency_info_list_.clear(); | 438 skipped_latency_info_list_.clear(); |
| 467 AddOnCommitCallbackAndDisableLocks( | 439 AddOnCommitCallbackAndDisableLocks( |
| 468 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, | 440 base::Bind(&DelegatedFrameHost::SendDelegatedFrameAck, |
| 469 AsWeakPtr(), | 441 AsWeakPtr(), |
| 470 output_surface_id)); | 442 output_surface_id)); |
| 471 } else { | 443 } else { |
| 472 AddOnCommitCallbackAndDisableLocks(base::Closure()); | 444 AddOnCommitCallbackAndDisableLocks(base::Closure()); |
| 473 } | 445 } |
| 474 DidReceiveFrameFromRenderer(damage_rect); | 446 DidReceiveFrameFromRenderer(damage_rect); |
| 475 if (frame_provider_.get() || !surface_id_.is_null()) | 447 if (frame_provider_.get() || !surface_id_.is_null()) |
| 476 delegated_frame_evictor_->SwappedFrame(!host->is_hidden()); | 448 delegated_frame_evictor_->SwappedFrame( |
| 449 client_->DelegatedFrameHostIsVisible()); |
| 477 // Note: the frame may have been evicted immediately. | 450 // Note: the frame may have been evicted immediately. |
| 478 } | 451 } |
| 479 | 452 |
| 480 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { | 453 void DelegatedFrameHost::SendDelegatedFrameAck(uint32 output_surface_id) { |
| 481 RenderWidgetHostImpl* host = client_->GetHost(); | |
| 482 cc::CompositorFrameAck ack; | 454 cc::CompositorFrameAck ack; |
| 483 if (!surface_returned_resources_.empty()) | 455 if (!surface_returned_resources_.empty()) |
| 484 ack.resources.swap(surface_returned_resources_); | 456 ack.resources.swap(surface_returned_resources_); |
| 485 if (resource_collection_.get()) | 457 if (resource_collection_.get()) |
| 486 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 458 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); |
| 487 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host->GetRoutingID(), | 459 client_->DelegatedFrameHostSendCompositorSwapAck(output_surface_id, ack); |
| 488 output_surface_id, | |
| 489 host->GetProcess()->GetID(), | |
| 490 ack); | |
| 491 DCHECK_GT(pending_delegated_ack_count_, 0); | 460 DCHECK_GT(pending_delegated_ack_count_, 0); |
| 492 pending_delegated_ack_count_--; | 461 pending_delegated_ack_count_--; |
| 493 } | 462 } |
| 494 | 463 |
| 495 void DelegatedFrameHost::SurfaceDrawn(uint32 output_surface_id, bool drawn) { | 464 void DelegatedFrameHost::SurfaceDrawn(uint32 output_surface_id, bool drawn) { |
| 496 SendDelegatedFrameAck(output_surface_id); | 465 SendDelegatedFrameAck(output_surface_id); |
| 497 } | 466 } |
| 498 | 467 |
| 499 void DelegatedFrameHost::UnusedResourcesAreAvailable() { | 468 void DelegatedFrameHost::UnusedResourcesAreAvailable() { |
| 500 if (pending_delegated_ack_count_) | 469 if (pending_delegated_ack_count_) |
| 501 return; | 470 return; |
| 502 | 471 |
| 503 SendReturnedDelegatedResources(last_output_surface_id_); | 472 SendReturnedDelegatedResources(last_output_surface_id_); |
| 504 } | 473 } |
| 505 | 474 |
| 506 void DelegatedFrameHost::SendReturnedDelegatedResources( | 475 void DelegatedFrameHost::SendReturnedDelegatedResources( |
| 507 uint32 output_surface_id) { | 476 uint32 output_surface_id) { |
| 508 RenderWidgetHostImpl* host = client_->GetHost(); | |
| 509 | |
| 510 cc::CompositorFrameAck ack; | 477 cc::CompositorFrameAck ack; |
| 511 if (!surface_returned_resources_.empty()) { | 478 if (!surface_returned_resources_.empty()) { |
| 512 ack.resources.swap(surface_returned_resources_); | 479 ack.resources.swap(surface_returned_resources_); |
| 513 } else { | 480 } else { |
| 514 DCHECK(resource_collection_.get()); | 481 DCHECK(resource_collection_.get()); |
| 515 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); | 482 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); |
| 516 } | 483 } |
| 517 DCHECK(!ack.resources.empty()); | 484 DCHECK(!ack.resources.empty()); |
| 518 | 485 |
| 519 RenderWidgetHostImpl::SendReclaimCompositorResources( | 486 client_->DelegatedFrameHostSendReclaimCompositorResources(output_surface_id, |
| 520 host->GetRoutingID(), | 487 ack); |
| 521 output_surface_id, | |
| 522 host->GetProcess()->GetID(), | |
| 523 ack); | |
| 524 } | 488 } |
| 525 | 489 |
| 526 void DelegatedFrameHost::ReturnResources( | 490 void DelegatedFrameHost::ReturnResources( |
| 527 const cc::ReturnedResourceArray& resources) { | 491 const cc::ReturnedResourceArray& resources) { |
| 528 if (resources.empty()) | 492 if (resources.empty()) |
| 529 return; | 493 return; |
| 530 std::copy(resources.begin(), | 494 std::copy(resources.begin(), |
| 531 resources.end(), | 495 resources.end(), |
| 532 std::back_inserter(surface_returned_resources_)); | 496 std::back_inserter(surface_returned_resources_)); |
| 533 if (!pending_delegated_ack_count_) | 497 if (!pending_delegated_ack_count_) |
| 534 SendReturnedDelegatedResources(last_output_surface_id_); | 498 SendReturnedDelegatedResources(last_output_surface_id_); |
| 535 } | 499 } |
| 536 | 500 |
| 537 void DelegatedFrameHost::EvictDelegatedFrame() { | 501 void DelegatedFrameHost::EvictDelegatedFrame() { |
| 538 client_->GetLayer()->SetShowSolidColorContent(); | 502 layer_->SetShowSolidColorContent(); |
| 539 frame_provider_ = NULL; | 503 frame_provider_ = NULL; |
| 540 if (!surface_id_.is_null()) { | 504 if (!surface_id_.is_null()) { |
| 541 surface_factory_->Destroy(surface_id_); | 505 surface_factory_->Destroy(surface_id_); |
| 542 surface_id_ = cc::SurfaceId(); | 506 surface_id_ = cc::SurfaceId(); |
| 543 } | 507 } |
| 544 delegated_frame_evictor_->DiscardedFrame(); | 508 delegated_frame_evictor_->DiscardedFrame(); |
| 545 } | 509 } |
| 546 | 510 |
| 547 // static | 511 // static |
| 548 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( | 512 void DelegatedFrameHost::CopyFromCompositingSurfaceHasResult( |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 texture_mailbox.sync_point(), | 827 texture_mailbox.sync_point(), |
| 864 video_frame.get(), | 828 video_frame.get(), |
| 865 finished_callback); | 829 finished_callback); |
| 866 } | 830 } |
| 867 | 831 |
| 868 //////////////////////////////////////////////////////////////////////////////// | 832 //////////////////////////////////////////////////////////////////////////////// |
| 869 // DelegatedFrameHost, ui::CompositorObserver implementation: | 833 // DelegatedFrameHost, ui::CompositorObserver implementation: |
| 870 | 834 |
| 871 void DelegatedFrameHost::OnCompositingDidCommit( | 835 void DelegatedFrameHost::OnCompositingDidCommit( |
| 872 ui::Compositor* compositor) { | 836 ui::Compositor* compositor) { |
| 873 RenderWidgetHostImpl* host = client_->GetHost(); | |
| 874 if (can_lock_compositor_ == NO_PENDING_COMMIT) { | 837 if (can_lock_compositor_ == NO_PENDING_COMMIT) { |
| 875 can_lock_compositor_ = YES_CAN_LOCK; | 838 can_lock_compositor_ = YES_CAN_LOCK; |
| 876 if (resize_lock_.get() && resize_lock_->GrabDeferredLock()) | 839 if (resize_lock_.get() && resize_lock_->GrabDeferredLock()) |
| 877 can_lock_compositor_ = YES_DID_LOCK; | 840 can_lock_compositor_ = YES_DID_LOCK; |
| 878 } | 841 } |
| 879 RunOnCommitCallbacks(); | 842 RunOnCommitCallbacks(); |
| 880 if (resize_lock_ && | 843 if (resize_lock_ && |
| 881 resize_lock_->expected_size() == current_frame_size_in_dip_) { | 844 resize_lock_->expected_size() == current_frame_size_in_dip_) { |
| 882 resize_lock_.reset(); | 845 resize_lock_.reset(); |
| 883 host->WasResized(); | 846 client_->DelegatedFrameHostResizeLockWasReleased(); |
| 884 // We may have had a resize while we had the lock (e.g. if the lock expired, | 847 // We may have had a resize while we had the lock (e.g. if the lock expired, |
| 885 // or if the UI still gave us some resizes), so make sure we grab a new lock | 848 // or if the UI still gave us some resizes), so make sure we grab a new lock |
| 886 // if necessary. | 849 // if necessary. |
| 887 MaybeCreateResizeLock(); | 850 MaybeCreateResizeLock(); |
| 888 } | 851 } |
| 889 } | 852 } |
| 890 | 853 |
| 891 void DelegatedFrameHost::OnCompositingStarted( | 854 void DelegatedFrameHost::OnCompositingStarted( |
| 892 ui::Compositor* compositor, base::TimeTicks start_time) { | 855 ui::Compositor* compositor, base::TimeTicks start_time) { |
| 893 last_draw_ended_ = start_time; | 856 last_draw_ended_ = start_time; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 913 DCHECK_EQ(compositor, compositor_); | 876 DCHECK_EQ(compositor, compositor_); |
| 914 ResetCompositor(); | 877 ResetCompositor(); |
| 915 DCHECK(!compositor_); | 878 DCHECK(!compositor_); |
| 916 } | 879 } |
| 917 | 880 |
| 918 void DelegatedFrameHost::OnUpdateVSyncParameters( | 881 void DelegatedFrameHost::OnUpdateVSyncParameters( |
| 919 base::TimeTicks timebase, | 882 base::TimeTicks timebase, |
| 920 base::TimeDelta interval) { | 883 base::TimeDelta interval) { |
| 921 vsync_timebase_ = timebase; | 884 vsync_timebase_ = timebase; |
| 922 vsync_interval_ = interval; | 885 vsync_interval_ = interval; |
| 923 RenderWidgetHostImpl* host = client_->GetHost(); | 886 if (client_->DelegatedFrameHostIsVisible()) |
| 924 if (client_->IsVisible()) | 887 client_->DelegatedFrameHostUpdateVSyncParameters(timebase, interval); |
| 925 host->UpdateVSyncParameters(timebase, interval); | |
| 926 } | 888 } |
| 927 | 889 |
| 928 //////////////////////////////////////////////////////////////////////////////// | 890 //////////////////////////////////////////////////////////////////////////////// |
| 929 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: | 891 // DelegatedFrameHost, ImageTransportFactoryObserver implementation: |
| 930 | 892 |
| 931 void DelegatedFrameHost::OnLostResources() { | 893 void DelegatedFrameHost::OnLostResources() { |
| 932 RenderWidgetHostImpl* host = client_->GetHost(); | |
| 933 if (frame_provider_.get() || !surface_id_.is_null()) | 894 if (frame_provider_.get() || !surface_id_.is_null()) |
| 934 EvictDelegatedFrame(); | 895 EvictDelegatedFrame(); |
| 935 idle_frame_subscriber_textures_.clear(); | 896 idle_frame_subscriber_textures_.clear(); |
| 936 yuv_readback_pipeline_.reset(); | 897 yuv_readback_pipeline_.reset(); |
| 937 | 898 |
| 938 host->ScheduleComposite(); | 899 client_->DelegatedFrameHostOnLostCompositorResources(); |
| 939 } | 900 } |
| 940 | 901 |
| 941 //////////////////////////////////////////////////////////////////////////////// | 902 //////////////////////////////////////////////////////////////////////////////// |
| 942 // DelegatedFrameHost, private: | 903 // DelegatedFrameHost, private: |
| 943 | 904 |
| 944 DelegatedFrameHost::~DelegatedFrameHost() { | 905 DelegatedFrameHost::~DelegatedFrameHost() { |
| 945 DCHECK(!compositor_); | 906 DCHECK(!compositor_); |
| 946 ImageTransportFactory::GetInstance()->RemoveObserver(this); | 907 ImageTransportFactory::GetInstance()->RemoveObserver(this); |
| 947 | 908 |
| 948 if (!surface_id_.is_null()) | 909 if (!surface_id_.is_null()) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 979 compositor_->AddObserver(this); | 940 compositor_->AddObserver(this); |
| 980 DCHECK(!vsync_manager_.get()); | 941 DCHECK(!vsync_manager_.get()); |
| 981 vsync_manager_ = compositor_->vsync_manager(); | 942 vsync_manager_ = compositor_->vsync_manager(); |
| 982 vsync_manager_->AddObserver(this); | 943 vsync_manager_->AddObserver(this); |
| 983 } | 944 } |
| 984 | 945 |
| 985 void DelegatedFrameHost::ResetCompositor() { | 946 void DelegatedFrameHost::ResetCompositor() { |
| 986 if (!compositor_) | 947 if (!compositor_) |
| 987 return; | 948 return; |
| 988 RunOnCommitCallbacks(); | 949 RunOnCommitCallbacks(); |
| 989 resize_lock_.reset(); | 950 if (resize_lock_) { |
| 990 client_->GetHost()->WasResized(); | 951 resize_lock_.reset(); |
| 952 client_->DelegatedFrameHostResizeLockWasReleased(); |
| 953 } |
| 991 if (compositor_->HasObserver(this)) | 954 if (compositor_->HasObserver(this)) |
| 992 compositor_->RemoveObserver(this); | 955 compositor_->RemoveObserver(this); |
| 993 if (vsync_manager_.get()) { | 956 if (vsync_manager_.get()) { |
| 994 vsync_manager_->RemoveObserver(this); | 957 vsync_manager_->RemoveObserver(this); |
| 995 vsync_manager_ = NULL; | 958 vsync_manager_ = NULL; |
| 996 } | 959 } |
| 997 compositor_ = nullptr; | 960 compositor_ = nullptr; |
| 998 } | 961 } |
| 999 | 962 |
| 1000 void DelegatedFrameHost::LockResources() { | 963 void DelegatedFrameHost::LockResources() { |
| 1001 DCHECK(frame_provider_.get() || !surface_id_.is_null()); | 964 DCHECK(frame_provider_.get() || !surface_id_.is_null()); |
| 1002 delegated_frame_evictor_->LockFrame(); | 965 delegated_frame_evictor_->LockFrame(); |
| 1003 } | 966 } |
| 1004 | 967 |
| 968 void DelegatedFrameHost::RequestCopyOfOutput( |
| 969 scoped_ptr<cc::CopyOutputRequest> request) { |
| 970 if (!request_copy_of_output_callback_for_testing_.is_null()) |
| 971 request_copy_of_output_callback_for_testing_.Run(request.Pass()); |
| 972 else |
| 973 layer_->RequestCopyOfOutput(request.Pass()); |
| 974 } |
| 975 |
| 1005 void DelegatedFrameHost::UnlockResources() { | 976 void DelegatedFrameHost::UnlockResources() { |
| 1006 DCHECK(frame_provider_.get() || !surface_id_.is_null()); | 977 DCHECK(frame_provider_.get() || !surface_id_.is_null()); |
| 1007 delegated_frame_evictor_->UnlockFrame(); | 978 delegated_frame_evictor_->UnlockFrame(); |
| 1008 } | 979 } |
| 1009 | 980 |
| 1010 //////////////////////////////////////////////////////////////////////////////// | 981 //////////////////////////////////////////////////////////////////////////////// |
| 1011 // DelegatedFrameHost, ui::LayerOwnerDelegate implementation: | 982 // DelegatedFrameHost, ui::LayerOwnerDelegate implementation: |
| 1012 | 983 |
| 1013 void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, | 984 void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer, |
| 1014 ui::Layer* new_layer) { | 985 ui::Layer* new_layer) { |
| 1015 // The new_layer is the one that will be used by our Window, so that's the one | 986 // The new_layer is the one that will be used by our Window, so that's the one |
| 1016 // that should keep our frame. old_layer will be returned to the | 987 // that should keep our frame. old_layer will be returned to the |
| 1017 // RecreateLayer caller, and should have a copy. | 988 // RecreateLayer caller, and should have a copy. |
| 1018 if (frame_provider_.get()) { | 989 if (frame_provider_.get()) { |
| 1019 new_layer->SetShowDelegatedContent(frame_provider_.get(), | 990 new_layer->SetShowDelegatedContent(frame_provider_.get(), |
| 1020 current_frame_size_in_dip_); | 991 current_frame_size_in_dip_); |
| 1021 } | 992 } |
| 1022 if (!surface_id_.is_null()) { | 993 if (!surface_id_.is_null()) { |
| 1023 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 994 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
| 1024 cc::SurfaceManager* manager = factory->GetSurfaceManager(); | 995 cc::SurfaceManager* manager = factory->GetSurfaceManager(); |
| 1025 new_layer->SetShowSurface( | 996 new_layer->SetShowSurface( |
| 1026 surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), | 997 surface_id_, base::Bind(&SatisfyCallback, base::Unretained(manager)), |
| 1027 base::Bind(&RequireCallback, base::Unretained(manager)), | 998 base::Bind(&RequireCallback, base::Unretained(manager)), |
| 1028 current_surface_size_, current_scale_factor_, | 999 current_surface_size_, current_scale_factor_, |
| 1029 current_frame_size_in_dip_); | 1000 current_frame_size_in_dip_); |
| 1030 } | 1001 } |
| 1031 } | 1002 } |
| 1032 | 1003 |
| 1033 } // namespace content | 1004 } // namespace content |
| OLD | NEW |