| Index: content/browser/renderer_host/render_widget_host_view_win.cc
|
| diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc
|
| index c982cc38b652c617132a17b8d065e9474f339049..51b9c4ae87c7d9510d4ec56924f877a82fdcc10b 100644
|
| --- a/content/browser/renderer_host/render_widget_host_view_win.cc
|
| +++ b/content/browser/renderer_host/render_widget_host_view_win.cc
|
| @@ -50,6 +50,7 @@
|
| #include "content/public/common/content_switches.h"
|
| #include "content/public/common/page_zoom.h"
|
| #include "content/public/common/process_type.h"
|
| +#include "media/base/video_util.h"
|
| #include "skia/ext/skia_utils_win.h"
|
| #include "third_party/skia/include/core/SkRegion.h"
|
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderline.h"
|
| @@ -314,6 +315,28 @@ void GetScreenInfoForWindow(WebKit::WebScreenInfo* results,
|
| results->deviceScaleFactor = ui::win::GetDeviceScaleFactor();
|
| }
|
|
|
| +void CopySnapshotToVideoFrame(const scoped_refptr<media::VideoFrame>& target,
|
| + const gfx::Rect& region_in_frame,
|
| + const base::Callback<void(bool)>& callback,
|
| + bool succeed,
|
| + const SkBitmap& bitmap) {
|
| + if (!succeed) {
|
| + callback.Run(false);
|
| + return;
|
| + }
|
| +
|
| + DCHECK(region_in_frame.size() == gfx::Size(bitmap.width(), bitmap.height()));
|
| + {
|
| + SkAutoLockPixels lock(bitmap);
|
| + media::CopyRGBToVideoFrame(
|
| + reinterpret_cast<const uint8*>(bitmap.getPixels()),
|
| + bitmap.rowBytes(),
|
| + region_in_frame,
|
| + target.get());
|
| + }
|
| + callback.Run(true);
|
| +}
|
| +
|
| } // namespace
|
|
|
| const wchar_t kRenderWidgetHostHWNDClass[] = L"Chrome_RenderWidgetHostHWND";
|
| @@ -841,14 +864,19 @@ void RenderWidgetHostViewWin::CopyFromCompositingSurface(
|
| const base::Callback<void(bool, const SkBitmap&)>& callback) {
|
| base::ScopedClosureRunner scoped_callback_runner(
|
| base::Bind(callback, false, SkBitmap()));
|
| - if (!accelerated_surface_.get())
|
| - return;
|
| -
|
| if (dst_size.IsEmpty() || src_subrect.IsEmpty())
|
| return;
|
|
|
| scoped_callback_runner.Release();
|
| - accelerated_surface_->AsyncCopyTo(src_subrect, dst_size, callback);
|
| +
|
| + if (!accelerated_surface_.get()) {
|
| + // If we don't have an accelerated surface then copying from browser side
|
| + // will fail, so try a slower copy from renderer side instead.
|
| + render_widget_host_->GetSnapshotFromRenderer(
|
| + src_subrect, dst_size, callback);
|
| + } else {
|
| + accelerated_surface_->AsyncCopyTo(src_subrect, dst_size, callback);
|
| + }
|
| }
|
|
|
| void RenderWidgetHostViewWin::CopyFromCompositingSurfaceToVideoFrame(
|
| @@ -856,8 +884,6 @@ void RenderWidgetHostViewWin::CopyFromCompositingSurfaceToVideoFrame(
|
| const scoped_refptr<media::VideoFrame>& target,
|
| const base::Callback<void(bool)>& callback) {
|
| base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
|
| - if (!accelerated_surface_.get())
|
| - return;
|
|
|
| if (!target || target->format() != media::VideoFrame::YV12)
|
| return;
|
| @@ -866,7 +892,28 @@ void RenderWidgetHostViewWin::CopyFromCompositingSurfaceToVideoFrame(
|
| return;
|
|
|
| scoped_callback_runner.Release();
|
| - accelerated_surface_->AsyncCopyToVideoFrame(src_subrect, target, callback);
|
| +
|
| + if (!accelerated_surface_.get()) {
|
| + // Compute the dest size we want after the letterboxing resize. Make the
|
| + // coordinates and sizes even because we letterbox in YUV space
|
| + // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
|
| + // line up correctly.
|
| + gfx::Rect region_in_frame =
|
| + media::ComputeLetterboxRegion(gfx::Rect(target->coded_size()),
|
| + src_subrect.size());
|
| + region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
|
| + region_in_frame.y() & ~1,
|
| + region_in_frame.width() & ~1,
|
| + region_in_frame.height() & ~1);
|
| +
|
| + // If we don't have an accelerated surface then copying from browser side
|
| + // will fail, so try a slower copy from renderer side instead.
|
| + render_widget_host_->GetSnapshotFromRenderer(
|
| + src_subrect, region_in_frame.size(), base::Bind(
|
| + CopySnapshotToVideoFrame, target, region_in_frame, callback));
|
| + } else {
|
| + accelerated_surface_->AsyncCopyToVideoFrame(src_subrect, target, callback);
|
| + }
|
| }
|
|
|
| bool RenderWidgetHostViewWin::CanCopyToVideoFrame() const {
|
|
|