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 10a068167d8f9a3f46aa65ee9ae75c2bd0c86a7c..998bd0d52a64dade09ec834be5eb600329f912fa 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() { |
| @@ -321,6 +322,17 @@ void RenderWidgetHostViewChildFrame::OnSwapCompositorFrame( |
| DCHECK_LT(ack_pending_count_, 1000U); |
| surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame), |
| ack_callback); |
| + |
| + ProcessFrameSwappedCallbacks(); |
| +} |
| + |
| +void RenderWidgetHostViewChildFrame::ProcessFrameSwappedCallbacks() { |
| + // 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. |
| + FrameSwappedCallbackList process_callbacks; |
| + process_callbacks.swap(frame_swapped_callbacks_); |
| + for (scoped_ptr<base::Closure>& callback : process_callbacks) |
| + callback->Run(); |
| } |
| void RenderWidgetHostViewChildFrame::GetScreenInfo( |
| @@ -422,12 +434,49 @@ bool RenderWidgetHostViewChildFrame::PostProcessEventForPluginIme( |
| } |
| #endif // defined(OS_MACOSX) |
| +void RenderWidgetHostViewChildFrame::RegisterFrameSwappedCallback( |
| + scoped_ptr<base::Closure> callback) { |
| + frame_swapped_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()) { |
| + // Defer submitting the copy request until after a frame is drawn, at which |
| + // point we should be guaranteed that the surface is available. |
| + RegisterFrameSwappedCallback(make_scoped_ptr(new base::Closure(base::Bind( |
| + &RenderWidgetHostViewChildFrame::SubmitSurfaceCopyRequest, AsWeakPtr(), |
| + src_subrect, output_size, callback, preferred_color_type)))); |
| + // If a composite is already scheduled, the following call will do nothing. |
| + // If no composite is scheduled, and there is no current surface, this will |
| + // initiate a composite. |
| + // TODO(piman): Is this reasoning correct? |
| + host_->ScheduleComposite(); |
|
piman
2016/01/29 22:28:54
Is there a reason why the renderer would not gener
wjmaclean
2016/02/01 15:36:04
Ok, I've removed this. There was some discussion a
|
| + 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( |