| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/renderer_host/render_widget_host_view_android.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_android.h" |
| 6 | 6 |
| 7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
| 15 #include "base/metrics/histogram.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 16 #include "base/threading/worker_pool.h" | 17 #include "base/threading/worker_pool.h" |
| 17 #include "cc/base/latency_info_swap_promise.h" | 18 #include "cc/base/latency_info_swap_promise.h" |
| 18 #include "cc/layers/delegated_frame_provider.h" | 19 #include "cc/layers/delegated_frame_provider.h" |
| 19 #include "cc/layers/delegated_renderer_layer.h" | 20 #include "cc/layers/delegated_renderer_layer.h" |
| 20 #include "cc/layers/layer.h" | 21 #include "cc/layers/layer.h" |
| 21 #include "cc/layers/texture_layer.h" | 22 #include "cc/layers/texture_layer.h" |
| 22 #include "cc/output/compositor_frame.h" | 23 #include "cc/output/compositor_frame.h" |
| 23 #include "cc/output/compositor_frame_ack.h" | 24 #include "cc/output/compositor_frame_ack.h" |
| 24 #include "cc/output/copy_output_request.h" | 25 #include "cc/output/copy_output_request.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 #include "ui/gfx/android/java_bitmap.h" | 58 #include "ui/gfx/android/java_bitmap.h" |
| 58 #include "ui/gfx/display.h" | 59 #include "ui/gfx/display.h" |
| 59 #include "ui/gfx/screen.h" | 60 #include "ui/gfx/screen.h" |
| 60 #include "ui/gfx/size_conversions.h" | 61 #include "ui/gfx/size_conversions.h" |
| 61 | 62 |
| 62 namespace content { | 63 namespace content { |
| 63 | 64 |
| 64 namespace { | 65 namespace { |
| 65 | 66 |
| 66 const int kUndefinedOutputSurfaceId = -1; | 67 const int kUndefinedOutputSurfaceId = -1; |
| 68 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime"; |
| 67 | 69 |
| 68 void InsertSyncPointAndAckForCompositor( | 70 void InsertSyncPointAndAckForCompositor( |
| 69 int renderer_host_id, | 71 int renderer_host_id, |
| 70 uint32 output_surface_id, | 72 uint32 output_surface_id, |
| 71 int route_id, | 73 int route_id, |
| 72 const gpu::Mailbox& return_mailbox, | 74 const gpu::Mailbox& return_mailbox, |
| 73 const gfx::Size return_size) { | 75 const gfx::Size return_size) { |
| 74 cc::CompositorFrameAck ack; | 76 cc::CompositorFrameAck ack; |
| 75 ack.gl_frame_data.reset(new cc::GLFrameData()); | 77 ack.gl_frame_data.reset(new cc::GLFrameData()); |
| 76 if (!return_mailbox.IsZero()) { | 78 if (!return_mailbox.IsZero()) { |
| 77 ack.gl_frame_data->mailbox = return_mailbox; | 79 ack.gl_frame_data->mailbox = return_mailbox; |
| 78 ack.gl_frame_data->size = return_size; | 80 ack.gl_frame_data->size = return_size; |
| 79 ack.gl_frame_data->sync_point = | 81 ack.gl_frame_data->sync_point = |
| 80 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint(); | 82 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint(); |
| 81 } | 83 } |
| 82 RenderWidgetHostImpl::SendSwapCompositorFrameAck( | 84 RenderWidgetHostImpl::SendSwapCompositorFrameAck( |
| 83 route_id, output_surface_id, renderer_host_id, ack); | 85 route_id, output_surface_id, renderer_host_id, ack); |
| 84 } | 86 } |
| 85 | 87 |
| 86 // Sends an acknowledgement to the renderer of a processed IME event. | 88 // Sends an acknowledgement to the renderer of a processed IME event. |
| 87 void SendImeEventAck(RenderWidgetHostImpl* host) { | 89 void SendImeEventAck(RenderWidgetHostImpl* host) { |
| 88 host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID())); | 90 host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID())); |
| 89 } | 91 } |
| 90 | 92 |
| 91 void CopyFromCompositingSurfaceFinished( | 93 void CopyFromCompositingSurfaceFinished( |
| 92 const base::Callback<void(bool, const SkBitmap&)>& callback, | 94 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 93 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 95 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
| 94 scoped_ptr<SkBitmap> bitmap, | 96 scoped_ptr<SkBitmap> bitmap, |
| 97 const base::TimeTicks& start_time, |
| 95 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 98 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
| 96 bool result) { | 99 bool result) { |
| 97 bitmap_pixels_lock.reset(); | 100 bitmap_pixels_lock.reset(); |
| 98 release_callback->Run(0, false); | 101 release_callback->Run(0, false); |
| 102 UMA_HISTOGRAM_TIMES(kAsyncReadBackString, |
| 103 base::TimeTicks::Now() - start_time); |
| 99 callback.Run(result, *bitmap); | 104 callback.Run(result, *bitmap); |
| 100 } | 105 } |
| 101 | 106 |
| 102 bool UsingDelegatedRenderer() { | 107 bool UsingDelegatedRenderer() { |
| 103 bool using_delegated_renderer = false; | 108 bool using_delegated_renderer = false; |
| 104 | 109 |
| 105 using_delegated_renderer |= CommandLine::ForCurrentProcess()->HasSwitch( | 110 using_delegated_renderer |= CommandLine::ForCurrentProcess()->HasSwitch( |
| 106 switches::kEnableDelegatedRenderer); | 111 switches::kEnableDelegatedRenderer); |
| 107 | 112 |
| 108 using_delegated_renderer &= !CommandLine::ForCurrentProcess()->HasSwitch( | 113 using_delegated_renderer &= !CommandLine::ForCurrentProcess()->HasSwitch( |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) { | 627 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) { |
| 623 RenderWidgetHostViewBase::SetBackground(background); | 628 RenderWidgetHostViewBase::SetBackground(background); |
| 624 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background)); | 629 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background)); |
| 625 } | 630 } |
| 626 | 631 |
| 627 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface( | 632 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface( |
| 628 const gfx::Rect& src_subrect, | 633 const gfx::Rect& src_subrect, |
| 629 const gfx::Size& dst_size, | 634 const gfx::Size& dst_size, |
| 630 const base::Callback<void(bool, const SkBitmap&)>& callback, | 635 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 631 bool readback_config_rgb565) { | 636 bool readback_config_rgb565) { |
| 637 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 632 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) { | 638 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) { |
| 633 callback.Run(false, SkBitmap()); | 639 callback.Run(false, SkBitmap()); |
| 634 return; | 640 return; |
| 635 } | 641 } |
| 636 ImageTransportFactoryAndroid* factory = | 642 ImageTransportFactoryAndroid* factory = |
| 637 ImageTransportFactoryAndroid::GetInstance(); | 643 ImageTransportFactoryAndroid::GetInstance(); |
| 638 GLHelper* gl_helper = factory->GetGLHelper(); | 644 GLHelper* gl_helper = factory->GetGLHelper(); |
| 639 if (!gl_helper) | 645 if (!gl_helper) |
| 640 return; | 646 return; |
| 641 bool check_rgb565_support = gl_helper->CanUseRgb565Readback(); | 647 bool check_rgb565_support = gl_helper->CanUseRgb565Readback(); |
| 642 if (readback_config_rgb565 && !check_rgb565_support) { | 648 if (readback_config_rgb565 && !check_rgb565_support) { |
| 643 LOG(ERROR) << "Readbackformat rgb565 not supported"; | 649 LOG(ERROR) << "Readbackformat rgb565 not supported"; |
| 644 callback.Run(false, SkBitmap()); | 650 callback.Run(false, SkBitmap()); |
| 645 return; | 651 return; |
| 646 } | 652 } |
| 647 const gfx::Display& display = | 653 const gfx::Display& display = |
| 648 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); | 654 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); |
| 649 float device_scale_factor = display.device_scale_factor(); | 655 float device_scale_factor = display.device_scale_factor(); |
| 650 | 656 |
| 651 DCHECK_EQ(device_scale_factor, | 657 DCHECK_EQ(device_scale_factor, |
| 652 ui::GetImageScale(GetScaleFactorForView(this))); | 658 ui::GetImageScale(GetScaleFactorForView(this))); |
| 653 | 659 |
| 654 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size); | 660 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size); |
| 655 gfx::Rect src_subrect_in_pixel = | 661 gfx::Rect src_subrect_in_pixel = |
| 656 ConvertRectToPixel(device_scale_factor, src_subrect); | 662 ConvertRectToPixel(device_scale_factor, src_subrect); |
| 657 | 663 |
| 658 if (using_synchronous_compositor_) { | 664 if (using_synchronous_compositor_) { |
| 659 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback); | 665 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback); |
| 666 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous", |
| 667 base::TimeTicks::Now() - start_time); |
| 660 return; | 668 return; |
| 661 } | 669 } |
| 662 scoped_ptr<cc::CopyOutputRequest> request; | 670 scoped_ptr<cc::CopyOutputRequest> request; |
| 663 if (src_subrect_in_pixel.size() == dst_size_in_pixel) { | 671 if (src_subrect_in_pixel.size() == dst_size_in_pixel) { |
| 664 request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind( | 672 request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind( |
| 665 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult, | 673 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult, |
| 666 dst_size_in_pixel, | 674 dst_size_in_pixel, |
| 675 start_time, |
| 667 callback)); | 676 callback)); |
| 668 } else { | 677 } else { |
| 669 request = cc::CopyOutputRequest::CreateRequest(base::Bind( | 678 request = cc::CopyOutputRequest::CreateRequest(base::Bind( |
| 670 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult, | 679 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult, |
| 671 dst_size_in_pixel, | 680 dst_size_in_pixel, |
| 672 readback_config_rgb565, | 681 readback_config_rgb565, |
| 682 start_time, |
| 673 callback)); | 683 callback)); |
| 674 } | 684 } |
| 675 request->set_area(src_subrect_in_pixel); | 685 request->set_area(src_subrect_in_pixel); |
| 676 layer_->RequestCopyOfOutput(request.Pass()); | 686 layer_->RequestCopyOfOutput(request.Pass()); |
| 677 } | 687 } |
| 678 | 688 |
| 679 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame( | 689 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame( |
| 680 const gfx::Rect& src_subrect, | 690 const gfx::Rect& src_subrect, |
| 681 const scoped_refptr<media::VideoFrame>& target, | 691 const scoped_refptr<media::VideoFrame>& target, |
| 682 const base::Callback<void(bool)>& callback) { | 692 const base::Callback<void(bool)>& callback) { |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 if (delegated_renderer_layer_.get()) | 1386 if (delegated_renderer_layer_.get()) |
| 1377 DestroyDelegatedContent(); | 1387 DestroyDelegatedContent(); |
| 1378 texture_id_in_layer_ = 0; | 1388 texture_id_in_layer_ = 0; |
| 1379 RunAckCallbacks(); | 1389 RunAckCallbacks(); |
| 1380 } | 1390 } |
| 1381 | 1391 |
| 1382 // static | 1392 // static |
| 1383 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult( | 1393 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult( |
| 1384 const gfx::Size& dst_size_in_pixel, | 1394 const gfx::Size& dst_size_in_pixel, |
| 1385 bool readback_config_rgb565, | 1395 bool readback_config_rgb565, |
| 1396 const base::TimeTicks& start_time, |
| 1386 const base::Callback<void(bool, const SkBitmap&)>& callback, | 1397 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 1387 scoped_ptr<cc::CopyOutputResult> result) { | 1398 scoped_ptr<cc::CopyOutputResult> result) { |
| 1388 DCHECK(result->HasTexture()); | 1399 DCHECK(result->HasTexture()); |
| 1389 base::ScopedClosureRunner scoped_callback_runner( | 1400 base::ScopedClosureRunner scoped_callback_runner( |
| 1390 base::Bind(callback, false, SkBitmap())); | 1401 base::Bind(callback, false, SkBitmap())); |
| 1391 | 1402 |
| 1392 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty()) | 1403 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty()) |
| 1393 return; | 1404 return; |
| 1394 | 1405 |
| 1395 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | 1406 scoped_ptr<SkBitmap> bitmap(new SkBitmap); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 texture_mailbox.sync_point(), | 1438 texture_mailbox.sync_point(), |
| 1428 result->size(), | 1439 result->size(), |
| 1429 gfx::Rect(result->size()), | 1440 gfx::Rect(result->size()), |
| 1430 dst_size_in_pixel, | 1441 dst_size_in_pixel, |
| 1431 pixels, | 1442 pixels, |
| 1432 readback_config_rgb565, | 1443 readback_config_rgb565, |
| 1433 base::Bind(&CopyFromCompositingSurfaceFinished, | 1444 base::Bind(&CopyFromCompositingSurfaceFinished, |
| 1434 callback, | 1445 callback, |
| 1435 base::Passed(&release_callback), | 1446 base::Passed(&release_callback), |
| 1436 base::Passed(&bitmap), | 1447 base::Passed(&bitmap), |
| 1448 start_time, |
| 1437 base::Passed(&bitmap_pixels_lock))); | 1449 base::Passed(&bitmap_pixels_lock))); |
| 1438 } | 1450 } |
| 1439 | 1451 |
| 1440 // static | 1452 // static |
| 1441 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult( | 1453 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult( |
| 1442 const gfx::Size& dst_size_in_pixel, | 1454 const gfx::Size& dst_size_in_pixel, |
| 1455 const base::TimeTicks& start_time, |
| 1443 const base::Callback<void(bool, const SkBitmap&)>& callback, | 1456 const base::Callback<void(bool, const SkBitmap&)>& callback, |
| 1444 scoped_ptr<cc::CopyOutputResult> result) { | 1457 scoped_ptr<cc::CopyOutputResult> result) { |
| 1445 DCHECK(result->HasBitmap()); | 1458 DCHECK(result->HasBitmap()); |
| 1446 base::ScopedClosureRunner scoped_callback_runner( | 1459 base::ScopedClosureRunner scoped_callback_runner( |
| 1447 base::Bind(callback, false, SkBitmap())); | 1460 base::Bind(callback, false, SkBitmap())); |
| 1448 | 1461 |
| 1449 if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty()) | 1462 if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty()) |
| 1450 return; | 1463 return; |
| 1451 | 1464 |
| 1452 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | 1465 scoped_ptr<SkBitmap> source = result->TakeBitmap(); |
| 1453 DCHECK(source); | 1466 DCHECK(source); |
| 1454 if (!source) | 1467 if (!source) |
| 1455 return; | 1468 return; |
| 1456 | 1469 |
| 1457 DCHECK_EQ(source->width(), dst_size_in_pixel.width()); | 1470 DCHECK_EQ(source->width(), dst_size_in_pixel.width()); |
| 1458 DCHECK_EQ(source->height(), dst_size_in_pixel.height()); | 1471 DCHECK_EQ(source->height(), dst_size_in_pixel.height()); |
| 1459 | 1472 |
| 1460 ignore_result(scoped_callback_runner.Release()); | 1473 ignore_result(scoped_callback_runner.Release()); |
| 1474 UMA_HISTOGRAM_TIMES(kAsyncReadBackString, |
| 1475 base::TimeTicks::Now() - start_time); |
| 1476 |
| 1461 callback.Run(true, *source); | 1477 callback.Run(true, *source); |
| 1462 } | 1478 } |
| 1463 | 1479 |
| 1464 // static | 1480 // static |
| 1465 void RenderWidgetHostViewPort::GetDefaultScreenInfo( | 1481 void RenderWidgetHostViewPort::GetDefaultScreenInfo( |
| 1466 blink::WebScreenInfo* results) { | 1482 blink::WebScreenInfo* results) { |
| 1467 const gfx::Display& display = | 1483 const gfx::Display& display = |
| 1468 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); | 1484 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); |
| 1469 results->rect = display.bounds(); | 1485 results->rect = display.bounds(); |
| 1470 // TODO(husky): Remove any system controls from availableRect. | 1486 // TODO(husky): Remove any system controls from availableRect. |
| 1471 results->availableRect = display.work_area(); | 1487 results->availableRect = display.work_area(); |
| 1472 results->deviceScaleFactor = display.device_scale_factor(); | 1488 results->deviceScaleFactor = display.device_scale_factor(); |
| 1473 gfx::DeviceDisplayInfo info; | 1489 gfx::DeviceDisplayInfo info; |
| 1474 results->depth = info.GetBitsPerPixel(); | 1490 results->depth = info.GetBitsPerPixel(); |
| 1475 results->depthPerComponent = info.GetBitsPerComponent(); | 1491 results->depthPerComponent = info.GetBitsPerComponent(); |
| 1476 results->isMonochrome = (results->depthPerComponent == 0); | 1492 results->isMonochrome = (results->depthPerComponent == 0); |
| 1477 } | 1493 } |
| 1478 | 1494 |
| 1479 //////////////////////////////////////////////////////////////////////////////// | 1495 //////////////////////////////////////////////////////////////////////////////// |
| 1480 // RenderWidgetHostView, public: | 1496 // RenderWidgetHostView, public: |
| 1481 | 1497 |
| 1482 // static | 1498 // static |
| 1483 RenderWidgetHostView* | 1499 RenderWidgetHostView* |
| 1484 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) { | 1500 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) { |
| 1485 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget); | 1501 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget); |
| 1486 return new RenderWidgetHostViewAndroid(rwhi, NULL); | 1502 return new RenderWidgetHostViewAndroid(rwhi, NULL); |
| 1487 } | 1503 } |
| 1488 | 1504 |
| 1489 } // namespace content | 1505 } // namespace content |
| OLD | NEW |