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

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: Created 5 years, 1 month 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 screencast_frame_sent_(0),
102 screencast_frame_acked_(0), 103 screencast_frame_acked_(0),
103 processing_screencast_frame_(false),
104 color_picker_(new ColorPicker(base::Bind( 104 color_picker_(new ColorPicker(base::Bind(
105 &PageHandler::OnColorPicked, base::Unretained(this)))), 105 &PageHandler::OnColorPicked, base::Unretained(this)))),
106 host_(nullptr), 106 host_(nullptr),
107 weak_factory_(this) { 107 weak_factory_(this) {
108 } 108 }
109 109
110 PageHandler::~PageHandler() { 110 PageHandler::~PageHandler() {
111 } 111 }
112 112
113 void PageHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { 113 void PageHandler::SetRenderFrameHost(RenderFrameHostImpl* host) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 *result = true; 281 *result = true;
282 #else 282 #else
283 *result = false; 283 *result = false;
284 #endif // defined(OS_ANDROID) 284 #endif // defined(OS_ANDROID)
285 return Response::OK(); 285 return Response::OK();
286 } 286 }
287 287
288 Response PageHandler::StartScreencast(const std::string* format, 288 Response PageHandler::StartScreencast(const std::string* format,
289 const int* quality, 289 const int* quality,
290 const int* max_width, 290 const int* max_width,
291 const int* max_height) { 291 const int* max_height,
292 const int* every_nth_frame) {
292 RenderWidgetHostImpl* widget_host = 293 RenderWidgetHostImpl* widget_host =
293 host_ ? host_->GetRenderWidgetHost() : nullptr; 294 host_ ? host_->GetRenderWidgetHost() : nullptr;
294 if (!widget_host) 295 if (!widget_host)
295 return Response::InternalError("Could not connect to view"); 296 return Response::InternalError("Could not connect to view");
296 297
297 screencast_enabled_ = true; 298 screencast_enabled_ = true;
298 screencast_format_ = format ? *format : kPng; 299 screencast_format_ = format ? *format : kPng;
299 screencast_quality_ = quality ? *quality : kDefaultScreenshotQuality; 300 screencast_quality_ = quality ? *quality : kDefaultScreenshotQuality;
300 if (screencast_quality_ < 0 || screencast_quality_ > 100) 301 if (screencast_quality_ < 0 || screencast_quality_ > 100)
301 screencast_quality_ = kDefaultScreenshotQuality; 302 screencast_quality_ = kDefaultScreenshotQuality;
302 screencast_max_width_ = max_width ? *max_width : -1; 303 screencast_max_width_ = max_width ? *max_width : -1;
303 screencast_max_height_ = max_height ? *max_height : -1; 304 screencast_max_height_ = max_height ? *max_height : -1;
305 screencast_frame_acked_ = screencast_frame_sent_;
306 capture_every_nth_frame_ = every_nth_frame ? *every_nth_frame : 1;
304 307
305 bool visible = !widget_host->is_hidden(); 308 bool visible = !widget_host->is_hidden();
306 NotifyScreencastVisibility(visible); 309 NotifyScreencastVisibility(visible);
307 if (visible) { 310 if (visible) {
308 if (has_compositor_frame_metadata_) { 311 if (has_compositor_frame_metadata_) {
309 InnerSwapCompositorFrame(); 312 InnerSwapCompositorFrame();
310 } else { 313 } else {
311 widget_host->Send( 314 widget_host->Send(
312 new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0)); 315 new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0));
313 } 316 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 368 }
366 369
367 void PageHandler::NotifyScreencastVisibility(bool visible) { 370 void PageHandler::NotifyScreencastVisibility(bool visible) {
368 if (visible) 371 if (visible)
369 capture_retry_count_ = kCaptureRetryLimit; 372 capture_retry_count_ = kCaptureRetryLimit;
370 client_->ScreencastVisibilityChanged( 373 client_->ScreencastVisibilityChanged(
371 ScreencastVisibilityChangedParams::Create()->set_visible(visible)); 374 ScreencastVisibilityChangedParams::Create()->set_visible(visible));
372 } 375 }
373 376
374 void PageHandler::InnerSwapCompositorFrame() { 377 void PageHandler::InnerSwapCompositorFrame() {
378 if (!host_ || !host_->GetView())
379 return;
380
375 if (screencast_frame_sent_ - screencast_frame_acked_ > 381 if (screencast_frame_sent_ - screencast_frame_acked_ >
376 kMaxScreencastFramesInFlight || processing_screencast_frame_) { 382 kMaxScreencastFramesInFlight) {
377 return; 383 return;
378 } 384 }
379 385
380 if (!host_ || !host_->GetView()) 386 static int global_frame_counter = 0;
dgozman 2015/11/20 22:53:23 With two different screencasts active it may happe
pfeldman 2015/11/20 23:18:25 Yep.
387 if (++global_frame_counter % capture_every_nth_frame_)
381 return; 388 return;
382 389
383 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( 390 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
384 host_->GetView()); 391 host_->GetView());
385 // TODO(vkuzkokov): do not use previous frame metadata. 392 // TODO(vkuzkokov): do not use previous frame metadata.
386 cc::CompositorFrameMetadata& metadata = last_compositor_frame_metadata_; 393 cc::CompositorFrameMetadata& metadata = last_compositor_frame_metadata_;
387 394
388 gfx::SizeF viewport_size_dip = gfx::ScaleSize( 395 gfx::SizeF viewport_size_dip = gfx::ScaleSize(
389 metadata.scrollable_viewport_size, metadata.page_scale_factor); 396 metadata.scrollable_viewport_size, metadata.page_scale_factor);
390 gfx::SizeF screen_size_dip = 397 gfx::SizeF screen_size_dip =
(...skipping 14 matching lines...) Expand all
405 scale = std::min(scale, max_height_dip / screen_size_dip.height()); 412 scale = std::min(scale, max_height_dip / screen_size_dip.height());
406 } 413 }
407 414
408 if (scale <= 0) 415 if (scale <= 0)
409 scale = 0.1; 416 scale = 0.1;
410 417
411 gfx::Size snapshot_size_dip(gfx::ToRoundedSize( 418 gfx::Size snapshot_size_dip(gfx::ToRoundedSize(
412 gfx::ScaleSize(viewport_size_dip, scale))); 419 gfx::ScaleSize(viewport_size_dip, scale)));
413 420
414 if (snapshot_size_dip.width() > 0 && snapshot_size_dip.height() > 0) { 421 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)); 422 gfx::Rect viewport_bounds_dip(gfx::ToRoundedSize(viewport_size_dip));
417 view->CopyFromCompositingSurface( 423 view->CopyFromCompositingSurface(
418 viewport_bounds_dip, 424 viewport_bounds_dip,
419 snapshot_size_dip, 425 snapshot_size_dip,
420 base::Bind(&PageHandler::ScreencastFrameCaptured, 426 base::Bind(&PageHandler::ScreencastFrameCaptured,
421 weak_factory_.GetWeakPtr(), 427 weak_factory_.GetWeakPtr(),
422 last_compositor_frame_metadata_), 428 last_compositor_frame_metadata_,
429 ++screencast_frame_sent_),
423 kN32_SkColorType); 430 kN32_SkColorType);
424 } 431 }
425 } 432 }
426 433
427 void PageHandler::ScreencastFrameCaptured( 434 void PageHandler::ScreencastFrameCaptured(
428 const cc::CompositorFrameMetadata& metadata, 435 const cc::CompositorFrameMetadata& metadata,
436 int frame_number,
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 --screencast_frame_sent_;
dgozman 2015/11/20 22:53:23 This violates the assumption of increasing screenc
pfeldman 2015/11/20 23:18:25 Not really.
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,
457 frame_number, base::Time::Now()));
449 } 458 }
450 459
451 void PageHandler::ScreencastFrameEncoded( 460 void PageHandler::ScreencastFrameEncoded(
452 const cc::CompositorFrameMetadata& metadata, 461 const cc::CompositorFrameMetadata& metadata,
462 int frame_number,
453 const base::Time& timestamp, 463 const base::Time& timestamp,
454 const std::string& data) { 464 const std::string& data) {
455 processing_screencast_frame_ = false;
456
457 // Consider metadata empty in case it has no device scale factor. 465 // Consider metadata empty in case it has no device scale factor.
458 if (metadata.device_scale_factor == 0 || !host_ || data.empty()) 466 if (metadata.device_scale_factor == 0 || !host_ || data.empty()) {
467 --screencast_frame_sent_;
459 return; 468 return;
469 }
460 470
461 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( 471 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
462 host_->GetView()); 472 host_->GetView());
463 if (!view) 473 if (!view) {
474 --screencast_frame_sent_;
464 return; 475 return;
476 }
465 477
466 gfx::SizeF screen_size_dip = 478 gfx::SizeF screen_size_dip =
467 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()), 479 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()),
468 1 / metadata.device_scale_factor); 480 1 / metadata.device_scale_factor);
469 scoped_refptr<ScreencastFrameMetadata> param_metadata = 481 scoped_refptr<ScreencastFrameMetadata> param_metadata =
470 ScreencastFrameMetadata::Create() 482 ScreencastFrameMetadata::Create()
471 ->set_page_scale_factor(metadata.page_scale_factor) 483 ->set_page_scale_factor(metadata.page_scale_factor)
472 ->set_offset_top(metadata.location_bar_content_translation.y()) 484 ->set_offset_top(metadata.location_bar_content_translation.y())
473 ->set_device_width(screen_size_dip.width()) 485 ->set_device_width(screen_size_dip.width())
474 ->set_device_height(screen_size_dip.height()) 486 ->set_device_height(screen_size_dip.height())
475 ->set_scroll_offset_x(metadata.root_scroll_offset.x()) 487 ->set_scroll_offset_x(metadata.root_scroll_offset.x())
476 ->set_scroll_offset_y(metadata.root_scroll_offset.y()) 488 ->set_scroll_offset_y(metadata.root_scroll_offset.y())
477 ->set_timestamp(timestamp.ToDoubleT()); 489 ->set_timestamp(timestamp.ToDoubleT());
478 client_->ScreencastFrame(ScreencastFrameParams::Create() 490 client_->ScreencastFrame(ScreencastFrameParams::Create()
479 ->set_data(data) 491 ->set_data(data)
480 ->set_metadata(param_metadata) 492 ->set_metadata(param_metadata)
481 ->set_frame_number(++screencast_frame_sent_)); 493 ->set_frame_number(frame_number));
482 } 494 }
483 495
484 void PageHandler::ScreenshotCaptured(DevToolsCommandId command_id, 496 void PageHandler::ScreenshotCaptured(DevToolsCommandId command_id,
485 const unsigned char* png_data, 497 const unsigned char* png_data,
486 size_t png_size) { 498 size_t png_size) {
487 if (!png_data || !png_size) { 499 if (!png_data || !png_size) {
488 client_->SendError(command_id, 500 client_->SendError(command_id,
489 Response::InternalError("Unable to capture screenshot")); 501 Response::InternalError("Unable to capture screenshot"));
490 return; 502 return;
491 } 503 }
492 504
493 std::string base_64_data; 505 std::string base_64_data;
494 base::Base64Encode( 506 base::Base64Encode(
495 base::StringPiece(reinterpret_cast<const char*>(png_data), png_size), 507 base::StringPiece(reinterpret_cast<const char*>(png_data), png_size),
496 &base_64_data); 508 &base_64_data);
497 509
498 client_->SendCaptureScreenshotResponse(command_id, 510 client_->SendCaptureScreenshotResponse(command_id,
499 CaptureScreenshotResponse::Create()->set_data(base_64_data)); 511 CaptureScreenshotResponse::Create()->set_data(base_64_data));
500 } 512 }
501 513
502 void PageHandler::OnColorPicked(int r, int g, int b, int a) { 514 void PageHandler::OnColorPicked(int r, int g, int b, int a) {
503 scoped_refptr<dom::RGBA> color = 515 scoped_refptr<dom::RGBA> color =
504 dom::RGBA::Create()->set_r(r)->set_g(g)->set_b(b)->set_a(a); 516 dom::RGBA::Create()->set_r(r)->set_g(g)->set_b(b)->set_a(a);
505 client_->ColorPicked(ColorPickedParams::Create()->set_color(color)); 517 client_->ColorPicked(ColorPickedParams::Create()->set_color(color));
506 } 518 }
507 519
508 } // namespace page 520 } // namespace page
509 } // namespace devtools 521 } // namespace devtools
510 } // namespace content 522 } // 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