Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: content/browser/devtools/protocol/page_handler.cc

Issue 1463813003: DevTools: optimize screencast for slower devices. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: using sessions now Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/devtools/protocol/page_handler.h" 5 #include "content/browser/devtools/protocol/page_handler.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 } // namespace 89 } // namespace
90 90
91 typedef DevToolsProtocolClient::Response Response; 91 typedef DevToolsProtocolClient::Response Response;
92 92
93 PageHandler::PageHandler() 93 PageHandler::PageHandler()
94 : enabled_(false), 94 : enabled_(false),
95 screencast_enabled_(false), 95 screencast_enabled_(false),
96 screencast_quality_(kDefaultScreenshotQuality), 96 screencast_quality_(kDefaultScreenshotQuality),
97 screencast_max_width_(-1), 97 screencast_max_width_(-1),
98 screencast_max_height_(-1), 98 screencast_max_height_(-1),
99 capture_every_nth_frame_(1),
99 capture_retry_count_(0), 100 capture_retry_count_(0),
100 has_compositor_frame_metadata_(false), 101 has_compositor_frame_metadata_(false),
101 screencast_frame_sent_(0), 102 session_id_(0),
102 screencast_frame_acked_(0), 103 frame_counter_(0),
103 processing_screencast_frame_(false), 104 frames_in_flight_(0),
104 color_picker_(new ColorPicker(base::Bind( 105 color_picker_(new ColorPicker(base::Bind(
105 &PageHandler::OnColorPicked, base::Unretained(this)))), 106 &PageHandler::OnColorPicked, base::Unretained(this)))),
106 host_(nullptr), 107 host_(nullptr),
107 weak_factory_(this) { 108 weak_factory_(this) {
108 } 109 }
109 110
110 PageHandler::~PageHandler() { 111 PageHandler::~PageHandler() {
111 } 112 }
112 113
113 void PageHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { 114 void PageHandler::SetRenderFrameHost(RenderFrameHostImpl* host) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 *result = true; 282 *result = true;
282 #else 283 #else
283 *result = false; 284 *result = false;
284 #endif // defined(OS_ANDROID) 285 #endif // defined(OS_ANDROID)
285 return Response::OK(); 286 return Response::OK();
286 } 287 }
287 288
288 Response PageHandler::StartScreencast(const std::string* format, 289 Response PageHandler::StartScreencast(const std::string* format,
289 const int* quality, 290 const int* quality,
290 const int* max_width, 291 const int* max_width,
291 const int* max_height) { 292 const int* max_height,
293 const int* every_nth_frame) {
292 RenderWidgetHostImpl* widget_host = 294 RenderWidgetHostImpl* widget_host =
293 host_ ? host_->GetRenderWidgetHost() : nullptr; 295 host_ ? host_->GetRenderWidgetHost() : nullptr;
294 if (!widget_host) 296 if (!widget_host)
295 return Response::InternalError("Could not connect to view"); 297 return Response::InternalError("Could not connect to view");
296 298
297 screencast_enabled_ = true; 299 screencast_enabled_ = true;
298 screencast_format_ = format ? *format : kPng; 300 screencast_format_ = format ? *format : kPng;
299 screencast_quality_ = quality ? *quality : kDefaultScreenshotQuality; 301 screencast_quality_ = quality ? *quality : kDefaultScreenshotQuality;
300 if (screencast_quality_ < 0 || screencast_quality_ > 100) 302 if (screencast_quality_ < 0 || screencast_quality_ > 100)
301 screencast_quality_ = kDefaultScreenshotQuality; 303 screencast_quality_ = kDefaultScreenshotQuality;
302 screencast_max_width_ = max_width ? *max_width : -1; 304 screencast_max_width_ = max_width ? *max_width : -1;
303 screencast_max_height_ = max_height ? *max_height : -1; 305 screencast_max_height_ = max_height ? *max_height : -1;
306 ++session_id_;
307 frame_counter_ = 0;
308 frames_in_flight_ = 0;
309 capture_every_nth_frame_ = every_nth_frame ? *every_nth_frame : 1;
304 310
305 bool visible = !widget_host->is_hidden(); 311 bool visible = !widget_host->is_hidden();
306 NotifyScreencastVisibility(visible); 312 NotifyScreencastVisibility(visible);
307 if (visible) { 313 if (visible) {
308 if (has_compositor_frame_metadata_) { 314 if (has_compositor_frame_metadata_) {
309 InnerSwapCompositorFrame(); 315 InnerSwapCompositorFrame();
310 } else { 316 } else {
311 widget_host->Send( 317 widget_host->Send(
312 new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0)); 318 new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0));
313 } 319 }
314 } 320 }
315 return Response::FallThrough(); 321 return Response::FallThrough();
316 } 322 }
317 323
318 Response PageHandler::StopScreencast() { 324 Response PageHandler::StopScreencast() {
319 screencast_enabled_ = false; 325 screencast_enabled_ = false;
320 return Response::FallThrough(); 326 return Response::FallThrough();
321 } 327 }
322 328
323 Response PageHandler::ScreencastFrameAck(int frame_number) { 329 Response PageHandler::ScreencastFrameAck(int session_id) {
324 screencast_frame_acked_ = frame_number; 330 if (session_id == session_id_)
331 --frames_in_flight_;
325 return Response::OK(); 332 return Response::OK();
326 } 333 }
327 334
328 Response PageHandler::HandleJavaScriptDialog(bool accept, 335 Response PageHandler::HandleJavaScriptDialog(bool accept,
329 const std::string* prompt_text) { 336 const std::string* prompt_text) {
330 base::string16 prompt_override; 337 base::string16 prompt_override;
331 if (prompt_text) 338 if (prompt_text)
332 prompt_override = base::UTF8ToUTF16(*prompt_text); 339 prompt_override = base::UTF8ToUTF16(*prompt_text);
333 340
334 WebContentsImpl* web_contents = GetWebContents(); 341 WebContentsImpl* web_contents = GetWebContents();
(...skipping 30 matching lines...) Expand all
365 } 372 }
366 373
367 void PageHandler::NotifyScreencastVisibility(bool visible) { 374 void PageHandler::NotifyScreencastVisibility(bool visible) {
368 if (visible) 375 if (visible)
369 capture_retry_count_ = kCaptureRetryLimit; 376 capture_retry_count_ = kCaptureRetryLimit;
370 client_->ScreencastVisibilityChanged( 377 client_->ScreencastVisibilityChanged(
371 ScreencastVisibilityChangedParams::Create()->set_visible(visible)); 378 ScreencastVisibilityChangedParams::Create()->set_visible(visible));
372 } 379 }
373 380
374 void PageHandler::InnerSwapCompositorFrame() { 381 void PageHandler::InnerSwapCompositorFrame() {
375 if (screencast_frame_sent_ - screencast_frame_acked_ >
376 kMaxScreencastFramesInFlight || processing_screencast_frame_) {
377 return;
378 }
379
380 if (!host_ || !host_->GetView()) 382 if (!host_ || !host_->GetView())
381 return; 383 return;
382 384
385 if (frames_in_flight_ > kMaxScreencastFramesInFlight)
386 return;
387
388 if (++frame_counter_ % capture_every_nth_frame_)
389 return;
390
383 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( 391 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
384 host_->GetView()); 392 host_->GetView());
385 // TODO(vkuzkokov): do not use previous frame metadata. 393 // TODO(vkuzkokov): do not use previous frame metadata.
386 cc::CompositorFrameMetadata& metadata = last_compositor_frame_metadata_; 394 cc::CompositorFrameMetadata& metadata = last_compositor_frame_metadata_;
387 395
388 gfx::SizeF viewport_size_dip = gfx::ScaleSize( 396 gfx::SizeF viewport_size_dip = gfx::ScaleSize(
389 metadata.scrollable_viewport_size, metadata.page_scale_factor); 397 metadata.scrollable_viewport_size, metadata.page_scale_factor);
390 gfx::SizeF screen_size_dip = 398 gfx::SizeF screen_size_dip =
391 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()), 399 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()),
392 1 / metadata.device_scale_factor); 400 1 / metadata.device_scale_factor);
(...skipping 12 matching lines...) Expand all
405 scale = std::min(scale, max_height_dip / screen_size_dip.height()); 413 scale = std::min(scale, max_height_dip / screen_size_dip.height());
406 } 414 }
407 415
408 if (scale <= 0) 416 if (scale <= 0)
409 scale = 0.1; 417 scale = 0.1;
410 418
411 gfx::Size snapshot_size_dip(gfx::ToRoundedSize( 419 gfx::Size snapshot_size_dip(gfx::ToRoundedSize(
412 gfx::ScaleSize(viewport_size_dip, scale))); 420 gfx::ScaleSize(viewport_size_dip, scale)));
413 421
414 if (snapshot_size_dip.width() > 0 && snapshot_size_dip.height() > 0) { 422 if (snapshot_size_dip.width() > 0 && snapshot_size_dip.height() > 0) {
415 processing_screencast_frame_ = true;
416 gfx::Rect viewport_bounds_dip(gfx::ToRoundedSize(viewport_size_dip)); 423 gfx::Rect viewport_bounds_dip(gfx::ToRoundedSize(viewport_size_dip));
417 view->CopyFromCompositingSurface( 424 view->CopyFromCompositingSurface(
418 viewport_bounds_dip, 425 viewport_bounds_dip,
419 snapshot_size_dip, 426 snapshot_size_dip,
420 base::Bind(&PageHandler::ScreencastFrameCaptured, 427 base::Bind(&PageHandler::ScreencastFrameCaptured,
421 weak_factory_.GetWeakPtr(), 428 weak_factory_.GetWeakPtr(),
422 last_compositor_frame_metadata_), 429 last_compositor_frame_metadata_),
423 kN32_SkColorType); 430 kN32_SkColorType);
431 frames_in_flight_++;
424 } 432 }
425 } 433 }
426 434
427 void PageHandler::ScreencastFrameCaptured( 435 void PageHandler::ScreencastFrameCaptured(
428 const cc::CompositorFrameMetadata& metadata, 436 const cc::CompositorFrameMetadata& metadata,
429 const SkBitmap& bitmap, 437 const SkBitmap& bitmap,
430 ReadbackResponse response) { 438 ReadbackResponse response) {
431 if (response != READBACK_SUCCESS) { 439 if (response != READBACK_SUCCESS) {
432 processing_screencast_frame_ = false;
433 if (capture_retry_count_) { 440 if (capture_retry_count_) {
434 --capture_retry_count_; 441 --capture_retry_count_;
435 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 442 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
436 FROM_HERE, base::Bind(&PageHandler::InnerSwapCompositorFrame, 443 FROM_HERE, base::Bind(&PageHandler::InnerSwapCompositorFrame,
437 weak_factory_.GetWeakPtr()), 444 weak_factory_.GetWeakPtr()),
438 base::TimeDelta::FromMilliseconds(kFrameRetryDelayMs)); 445 base::TimeDelta::FromMilliseconds(kFrameRetryDelayMs));
439 } 446 }
447 --frames_in_flight_;
440 return; 448 return;
441 } 449 }
442 base::PostTaskAndReplyWithResult( 450 base::PostTaskAndReplyWithResult(
443 base::WorkerPool::GetTaskRunner(true).get(), 451 base::WorkerPool::GetTaskRunner(true).get(),
444 FROM_HERE, 452 FROM_HERE,
445 base::Bind(&EncodeScreencastFrame, 453 base::Bind(&EncodeScreencastFrame,
446 bitmap, screencast_format_, screencast_quality_), 454 bitmap, screencast_format_, screencast_quality_),
447 base::Bind(&PageHandler::ScreencastFrameEncoded, 455 base::Bind(&PageHandler::ScreencastFrameEncoded,
448 weak_factory_.GetWeakPtr(), metadata, base::Time::Now())); 456 weak_factory_.GetWeakPtr(), metadata, base::Time::Now()));
449 } 457 }
450 458
451 void PageHandler::ScreencastFrameEncoded( 459 void PageHandler::ScreencastFrameEncoded(
452 const cc::CompositorFrameMetadata& metadata, 460 const cc::CompositorFrameMetadata& metadata,
453 const base::Time& timestamp, 461 const base::Time& timestamp,
454 const std::string& data) { 462 const std::string& data) {
455 processing_screencast_frame_ = false;
456
457 // Consider metadata empty in case it has no device scale factor. 463 // Consider metadata empty in case it has no device scale factor.
458 if (metadata.device_scale_factor == 0 || !host_ || data.empty()) 464 if (metadata.device_scale_factor == 0 || !host_ || data.empty()) {
465 --frames_in_flight_;
459 return; 466 return;
467 }
460 468
461 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( 469 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
462 host_->GetView()); 470 host_->GetView());
463 if (!view) 471 if (!view) {
472 --frames_in_flight_;
464 return; 473 return;
474 }
465 475
466 gfx::SizeF screen_size_dip = 476 gfx::SizeF screen_size_dip =
467 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()), 477 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()),
468 1 / metadata.device_scale_factor); 478 1 / metadata.device_scale_factor);
469 scoped_refptr<ScreencastFrameMetadata> param_metadata = 479 scoped_refptr<ScreencastFrameMetadata> param_metadata =
470 ScreencastFrameMetadata::Create() 480 ScreencastFrameMetadata::Create()
471 ->set_page_scale_factor(metadata.page_scale_factor) 481 ->set_page_scale_factor(metadata.page_scale_factor)
472 ->set_offset_top(metadata.location_bar_content_translation.y()) 482 ->set_offset_top(metadata.location_bar_content_translation.y())
473 ->set_device_width(screen_size_dip.width()) 483 ->set_device_width(screen_size_dip.width())
474 ->set_device_height(screen_size_dip.height()) 484 ->set_device_height(screen_size_dip.height())
475 ->set_scroll_offset_x(metadata.root_scroll_offset.x()) 485 ->set_scroll_offset_x(metadata.root_scroll_offset.x())
476 ->set_scroll_offset_y(metadata.root_scroll_offset.y()) 486 ->set_scroll_offset_y(metadata.root_scroll_offset.y())
477 ->set_timestamp(timestamp.ToDoubleT()); 487 ->set_timestamp(timestamp.ToDoubleT());
478 client_->ScreencastFrame(ScreencastFrameParams::Create() 488 client_->ScreencastFrame(ScreencastFrameParams::Create()
479 ->set_data(data) 489 ->set_data(data)
480 ->set_metadata(param_metadata) 490 ->set_metadata(param_metadata)
481 ->set_frame_number(++screencast_frame_sent_)); 491 ->set_session_id(session_id_));
482 } 492 }
483 493
484 void PageHandler::ScreenshotCaptured(DevToolsCommandId command_id, 494 void PageHandler::ScreenshotCaptured(DevToolsCommandId command_id,
485 const unsigned char* png_data, 495 const unsigned char* png_data,
486 size_t png_size) { 496 size_t png_size) {
487 if (!png_data || !png_size) { 497 if (!png_data || !png_size) {
488 client_->SendError(command_id, 498 client_->SendError(command_id,
489 Response::InternalError("Unable to capture screenshot")); 499 Response::InternalError("Unable to capture screenshot"));
490 return; 500 return;
491 } 501 }
492 502
493 std::string base_64_data; 503 std::string base_64_data;
494 base::Base64Encode( 504 base::Base64Encode(
495 base::StringPiece(reinterpret_cast<const char*>(png_data), png_size), 505 base::StringPiece(reinterpret_cast<const char*>(png_data), png_size),
496 &base_64_data); 506 &base_64_data);
497 507
498 client_->SendCaptureScreenshotResponse(command_id, 508 client_->SendCaptureScreenshotResponse(command_id,
499 CaptureScreenshotResponse::Create()->set_data(base_64_data)); 509 CaptureScreenshotResponse::Create()->set_data(base_64_data));
500 } 510 }
501 511
502 void PageHandler::OnColorPicked(int r, int g, int b, int a) { 512 void PageHandler::OnColorPicked(int r, int g, int b, int a) {
503 scoped_refptr<dom::RGBA> color = 513 scoped_refptr<dom::RGBA> color =
504 dom::RGBA::Create()->set_r(r)->set_g(g)->set_b(b)->set_a(a); 514 dom::RGBA::Create()->set_r(r)->set_g(g)->set_b(b)->set_a(a);
505 client_->ColorPicked(ColorPickedParams::Create()->set_color(color)); 515 client_->ColorPicked(ColorPickedParams::Create()->set_color(color));
506 } 516 }
507 517
508 } // namespace page 518 } // namespace page
509 } // namespace devtools 519 } // namespace devtools
510 } // namespace content 520 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/protocol/page_handler.h ('k') | third_party/WebKit/Source/core/inspector/InspectorPageAgent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698