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

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: just count frames 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 frame_counter_(0),
102 screencast_frame_acked_(0), 103 frames_in_flight_(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 frame_counter_ = 0;
306 frames_in_flight_ = 0;
dgozman 2015/11/21 02:03:23 Let's pass session id around.
307 capture_every_nth_frame_ = every_nth_frame ? *every_nth_frame : 1;
304 308
305 bool visible = !widget_host->is_hidden(); 309 bool visible = !widget_host->is_hidden();
306 NotifyScreencastVisibility(visible); 310 NotifyScreencastVisibility(visible);
307 if (visible) { 311 if (visible) {
308 if (has_compositor_frame_metadata_) { 312 if (has_compositor_frame_metadata_) {
309 InnerSwapCompositorFrame(); 313 InnerSwapCompositorFrame();
310 } else { 314 } else {
311 widget_host->Send( 315 widget_host->Send(
312 new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0)); 316 new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0));
313 } 317 }
314 } 318 }
315 return Response::FallThrough(); 319 return Response::FallThrough();
316 } 320 }
317 321
318 Response PageHandler::StopScreencast() { 322 Response PageHandler::StopScreencast() {
319 screencast_enabled_ = false; 323 screencast_enabled_ = false;
320 return Response::FallThrough(); 324 return Response::FallThrough();
321 } 325 }
322 326
323 Response PageHandler::ScreencastFrameAck(int frame_number) { 327 Response PageHandler::ScreencastFrameAck() {
324 screencast_frame_acked_ = frame_number; 328 --frames_in_flight_;
325 return Response::OK(); 329 return Response::OK();
326 } 330 }
327 331
328 Response PageHandler::HandleJavaScriptDialog(bool accept, 332 Response PageHandler::HandleJavaScriptDialog(bool accept,
329 const std::string* prompt_text) { 333 const std::string* prompt_text) {
330 base::string16 prompt_override; 334 base::string16 prompt_override;
331 if (prompt_text) 335 if (prompt_text)
332 prompt_override = base::UTF8ToUTF16(*prompt_text); 336 prompt_override = base::UTF8ToUTF16(*prompt_text);
333 337
334 WebContentsImpl* web_contents = GetWebContents(); 338 WebContentsImpl* web_contents = GetWebContents();
(...skipping 30 matching lines...) Expand all
365 } 369 }
366 370
367 void PageHandler::NotifyScreencastVisibility(bool visible) { 371 void PageHandler::NotifyScreencastVisibility(bool visible) {
368 if (visible) 372 if (visible)
369 capture_retry_count_ = kCaptureRetryLimit; 373 capture_retry_count_ = kCaptureRetryLimit;
370 client_->ScreencastVisibilityChanged( 374 client_->ScreencastVisibilityChanged(
371 ScreencastVisibilityChangedParams::Create()->set_visible(visible)); 375 ScreencastVisibilityChangedParams::Create()->set_visible(visible));
372 } 376 }
373 377
374 void PageHandler::InnerSwapCompositorFrame() { 378 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()) 379 if (!host_ || !host_->GetView())
381 return; 380 return;
382 381
382 if (frames_in_flight_ > kMaxScreencastFramesInFlight)
383 return;
384
385 if (++frame_counter_ % capture_every_nth_frame_)
386 return;
387
388 frames_in_flight_++;
dgozman 2015/11/21 02:03:23 Move this into last |if| in this function.
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 =
391 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()), 398 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()),
392 1 / metadata.device_scale_factor); 399 1 / metadata.device_scale_factor);
(...skipping 12 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_),
423 kN32_SkColorType); 429 kN32_SkColorType);
424 } 430 }
425 } 431 }
426 432
427 void PageHandler::ScreencastFrameCaptured( 433 void PageHandler::ScreencastFrameCaptured(
428 const cc::CompositorFrameMetadata& metadata, 434 const cc::CompositorFrameMetadata& metadata,
429 const SkBitmap& bitmap, 435 const SkBitmap& bitmap,
430 ReadbackResponse response) { 436 ReadbackResponse response) {
431 if (response != READBACK_SUCCESS) { 437 if (response != READBACK_SUCCESS) {
432 processing_screencast_frame_ = false;
433 if (capture_retry_count_) { 438 if (capture_retry_count_) {
434 --capture_retry_count_; 439 --capture_retry_count_;
435 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 440 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
436 FROM_HERE, base::Bind(&PageHandler::InnerSwapCompositorFrame, 441 FROM_HERE, base::Bind(&PageHandler::InnerSwapCompositorFrame,
437 weak_factory_.GetWeakPtr()), 442 weak_factory_.GetWeakPtr()),
438 base::TimeDelta::FromMilliseconds(kFrameRetryDelayMs)); 443 base::TimeDelta::FromMilliseconds(kFrameRetryDelayMs));
439 } 444 }
445 --frames_in_flight_;
440 return; 446 return;
441 } 447 }
442 base::PostTaskAndReplyWithResult( 448 base::PostTaskAndReplyWithResult(
443 base::WorkerPool::GetTaskRunner(true).get(), 449 base::WorkerPool::GetTaskRunner(true).get(),
444 FROM_HERE, 450 FROM_HERE,
445 base::Bind(&EncodeScreencastFrame, 451 base::Bind(&EncodeScreencastFrame,
446 bitmap, screencast_format_, screencast_quality_), 452 bitmap, screencast_format_, screencast_quality_),
447 base::Bind(&PageHandler::ScreencastFrameEncoded, 453 base::Bind(&PageHandler::ScreencastFrameEncoded,
448 weak_factory_.GetWeakPtr(), metadata, base::Time::Now())); 454 weak_factory_.GetWeakPtr(), metadata, base::Time::Now()));
449 } 455 }
450 456
451 void PageHandler::ScreencastFrameEncoded( 457 void PageHandler::ScreencastFrameEncoded(
452 const cc::CompositorFrameMetadata& metadata, 458 const cc::CompositorFrameMetadata& metadata,
453 const base::Time& timestamp, 459 const base::Time& timestamp,
454 const std::string& data) { 460 const std::string& data) {
455 processing_screencast_frame_ = false;
456
457 // Consider metadata empty in case it has no device scale factor. 461 // Consider metadata empty in case it has no device scale factor.
458 if (metadata.device_scale_factor == 0 || !host_ || data.empty()) 462 if (metadata.device_scale_factor == 0 || !host_ || data.empty()) {
463 --frames_in_flight_;
459 return; 464 return;
465 }
460 466
461 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( 467 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
462 host_->GetView()); 468 host_->GetView());
463 if (!view) 469 if (!view) {
470 --frames_in_flight_;
464 return; 471 return;
472 }
465 473
466 gfx::SizeF screen_size_dip = 474 gfx::SizeF screen_size_dip =
467 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()), 475 gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()),
468 1 / metadata.device_scale_factor); 476 1 / metadata.device_scale_factor);
469 scoped_refptr<ScreencastFrameMetadata> param_metadata = 477 scoped_refptr<ScreencastFrameMetadata> param_metadata =
470 ScreencastFrameMetadata::Create() 478 ScreencastFrameMetadata::Create()
471 ->set_page_scale_factor(metadata.page_scale_factor) 479 ->set_page_scale_factor(metadata.page_scale_factor)
472 ->set_offset_top(metadata.location_bar_content_translation.y()) 480 ->set_offset_top(metadata.location_bar_content_translation.y())
473 ->set_device_width(screen_size_dip.width()) 481 ->set_device_width(screen_size_dip.width())
474 ->set_device_height(screen_size_dip.height()) 482 ->set_device_height(screen_size_dip.height())
475 ->set_scroll_offset_x(metadata.root_scroll_offset.x()) 483 ->set_scroll_offset_x(metadata.root_scroll_offset.x())
476 ->set_scroll_offset_y(metadata.root_scroll_offset.y()) 484 ->set_scroll_offset_y(metadata.root_scroll_offset.y())
477 ->set_timestamp(timestamp.ToDoubleT()); 485 ->set_timestamp(timestamp.ToDoubleT());
478 client_->ScreencastFrame(ScreencastFrameParams::Create() 486 client_->ScreencastFrame(ScreencastFrameParams::Create()
479 ->set_data(data) 487 ->set_data(data)
480 ->set_metadata(param_metadata) 488 ->set_metadata(param_metadata));
481 ->set_frame_number(++screencast_frame_sent_));
482 } 489 }
483 490
484 void PageHandler::ScreenshotCaptured(DevToolsCommandId command_id, 491 void PageHandler::ScreenshotCaptured(DevToolsCommandId command_id,
485 const unsigned char* png_data, 492 const unsigned char* png_data,
486 size_t png_size) { 493 size_t png_size) {
487 if (!png_data || !png_size) { 494 if (!png_data || !png_size) {
488 client_->SendError(command_id, 495 client_->SendError(command_id,
489 Response::InternalError("Unable to capture screenshot")); 496 Response::InternalError("Unable to capture screenshot"));
490 return; 497 return;
491 } 498 }
492 499
493 std::string base_64_data; 500 std::string base_64_data;
494 base::Base64Encode( 501 base::Base64Encode(
495 base::StringPiece(reinterpret_cast<const char*>(png_data), png_size), 502 base::StringPiece(reinterpret_cast<const char*>(png_data), png_size),
496 &base_64_data); 503 &base_64_data);
497 504
498 client_->SendCaptureScreenshotResponse(command_id, 505 client_->SendCaptureScreenshotResponse(command_id,
499 CaptureScreenshotResponse::Create()->set_data(base_64_data)); 506 CaptureScreenshotResponse::Create()->set_data(base_64_data));
500 } 507 }
501 508
502 void PageHandler::OnColorPicked(int r, int g, int b, int a) { 509 void PageHandler::OnColorPicked(int r, int g, int b, int a) {
503 scoped_refptr<dom::RGBA> color = 510 scoped_refptr<dom::RGBA> color =
504 dom::RGBA::Create()->set_r(r)->set_g(g)->set_b(b)->set_a(a); 511 dom::RGBA::Create()->set_r(r)->set_g(g)->set_b(b)->set_a(a);
505 client_->ColorPicked(ColorPickedParams::Create()->set_color(color)); 512 client_->ColorPicked(ColorPickedParams::Create()->set_color(color));
506 } 513 }
507 514
508 } // namespace page 515 } // namespace page
509 } // namespace devtools 516 } // namespace devtools
510 } // namespace content 517 } // 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