Chromium Code Reviews| Index: content/browser/frame_host/render_widget_host_view_child_frame.cc |
| diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc |
| index 98119d15bd0a7ee829b5fddbc1880148857ecf50..80e07791756cfebfa4042d75fc21a8bf800353fb 100644 |
| --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc |
| +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc |
| @@ -9,6 +9,8 @@ |
| #include <vector> |
| #include "build/build_config.h" |
| +#include "cc/output/copy_output_request.h" |
| +#include "cc/output/copy_output_result.h" |
| #include "cc/surfaces/surface.h" |
| #include "cc/surfaces/surface_factory.h" |
| #include "cc/surfaces/surface_manager.h" |
| @@ -84,8 +86,7 @@ bool RenderWidgetHostViewChildFrame::HasFocus() const { |
| } |
| bool RenderWidgetHostViewChildFrame::IsSurfaceAvailableForCopy() const { |
| - NOTIMPLEMENTED(); |
| - return false; |
| + return surface_factory_ && !surface_id_.is_null(); |
| } |
| void RenderWidgetHostViewChildFrame::Show() { |
| @@ -254,6 +255,13 @@ void RenderWidgetHostViewChildFrame::SurfaceDrawn(uint32_t output_surface_id, |
| output_surface_id, ack)); |
| } |
| ack_pending_count_--; |
| + |
| + // We only use callbacks once, therefore we make a new list for registration |
| + // before we start, and discard the old list entries when we are done. |
| + FrameDrawnCallbackList process_callbacks; |
| + process_callbacks.swap(frame_drawn_callbacks_); |
| + for (scoped_ptr<base::Closure>& callback : process_callbacks) |
| + callback->Run(); |
| } |
| void RenderWidgetHostViewChildFrame::OnSwapCompositorFrame( |
| @@ -425,12 +433,44 @@ bool RenderWidgetHostViewChildFrame::PostProcessEventForPluginIme( |
| } |
| #endif // defined(OS_MACOSX) |
| +void RenderWidgetHostViewChildFrame::RegisterFrameDrawnCallback( |
| + scoped_ptr<base::Closure> callback) { |
| + frame_drawn_callbacks_.push_back(std::move(callback)); |
| +} |
| + |
| void RenderWidgetHostViewChildFrame::CopyFromCompositingSurface( |
| - const gfx::Rect& /* src_subrect */, |
| - const gfx::Size& /* dst_size */, |
| + const gfx::Rect& src_subrect, |
| + const gfx::Size& output_size, |
| const ReadbackRequestCallback& callback, |
| - const SkColorType /* preferred_color_type */) { |
| - callback.Run(SkBitmap(), READBACK_FAILED); |
| + const SkColorType preferred_color_type) { |
| + if (!IsSurfaceAvailableForCopy()) { |
|
ncarter (slow)
2016/01/27 21:08:24
This behavior goes somewhat against the intended c
wjmaclean
2016/01/27 21:28:01
I guess having a surface ID may not be enough, but
|
| + // Defer submitting the copy request until after a frame is drawn, at which |
| + // point we should be guaranteed that the surface is available. |
| + RegisterFrameDrawnCallback(make_scoped_ptr(new base::Closure(base::Bind( |
|
piman
2016/01/29 04:29:46
Why waiting for the frame to be *drawn* (SurfaceDr
wjmaclean
2016/01/29 21:01:57
I didn't realize that would happen, thanks for poi
|
| + &RenderWidgetHostViewChildFrame::SubmitSurfaceCopyRequest, AsWeakPtr(), |
| + src_subrect, output_size, callback, preferred_color_type)))); |
| + return; |
| + } |
| + |
| + SubmitSurfaceCopyRequest(src_subrect, output_size, callback, |
| + preferred_color_type); |
| +} |
| + |
| +void RenderWidgetHostViewChildFrame::SubmitSurfaceCopyRequest( |
| + const gfx::Rect& src_subrect, |
| + const gfx::Size& output_size, |
| + const ReadbackRequestCallback& callback, |
| + const SkColorType preferred_color_type) { |
| + DCHECK(IsSurfaceAvailableForCopy()); |
| + |
| + scoped_ptr<cc::CopyOutputRequest> request = |
| + cc::CopyOutputRequest::CreateRequest( |
| + base::Bind(&CopyFromCompositingSurfaceHasResult, output_size, |
| + preferred_color_type, callback)); |
| + if (!src_subrect.IsEmpty()) |
| + request->set_area(src_subrect); |
| + |
| + surface_factory_->RequestCopyOfSurface(surface_id_, std::move(request)); |
| } |
| void RenderWidgetHostViewChildFrame::CopyFromCompositingSurfaceToVideoFrame( |