Index: content/browser/aura/browser_compositor_output_surface_capturer.cc |
diff --git a/content/browser/aura/browser_compositor_output_surface_capturer.cc b/content/browser/aura/browser_compositor_output_surface_capturer.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..be9ad487a8fc29ee62ca805b1da450cbaff7585e |
--- /dev/null |
+++ b/content/browser/aura/browser_compositor_output_surface_capturer.cc |
@@ -0,0 +1,142 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/aura/browser_compositor_output_surface_capturer.h" |
+ |
+#include "base/bind.h" |
+#include "base/location.h" |
+#include "base/message_loop/message_loop_proxy.h" |
+#include "content/browser/aura/browser_compositor_output_surface.h" |
+#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
+#include "media/base/video_frame.h" |
+#include "ui/compositor/compositor.h" |
+ |
+namespace content { |
+ |
+BrowserCompositorOutputSurfaceCapturer::BrowserCompositorOutputSurfaceCapturer( |
+ IDMap<BrowserCompositorOutputSurface>* output_surface_map, |
+ int output_surface_id, |
+ SurfaceCapturer::Client* client) |
+ : output_surface_map_(output_surface_map), |
+ output_surface_id_(output_surface_id), |
+ client_ptr_factory_(client), |
+ client_(client_ptr_factory_.GetWeakPtr()); |
hshi1
2013/08/15 19:40:18
typo: ';' -> ','
|
+ ui_compositor_message_loop_proxy_(base::MessageLoopProxy::current()) { |
+ compositor_impl_message_loop_proxy_ = |
+ ui::Compositor::GetCompositorMessageLoop(); |
+ if (!compositor_impl_message_loop_proxy_) |
+ compositor_impl_message_loop_proxy_ = ui_compositor_message_loop_proxy_; |
+} |
+ |
+BrowserCompositorOutputSurfaceCapturer:: |
+ ~BrowserCompositorOutputSurfaceCapturer() { |
+ DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); |
+ DCHECK(!capturer_); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::Initialize( |
+ media::VideoFrame::Format format) { |
+ DCHECK(ui_compositor_message_loop_proxy_->BelongsToCurrentThread()); |
+ ui_compositor_message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &BrowserCompositorOutputSurfaceCapturer::DoInitializeOnImplThread, |
+ base::Unretained(this), |
+ format)); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::Capture( |
+ const scoped_refptr<media::VideoFrame>& frame) { |
+ DCHECK(ui_compositor_message_loop_proxy_->BelongsToCurrentThread()); |
+ ui_compositor_message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&BrowserCompositorOutputSurfaceCapturer::Capture, |
+ base::Unretained(this), |
+ frame)); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::Destroy() { |
+ DCHECK(ui_compositor_message_loop_proxy_->BelongsToCurrentThread()); |
+ client_ptr_factory_.InvalidateWeakPtrs(); |
+ // Post |this| pointer as owned so we delete this after call. |
+ ui_compositor_message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&BrowserCompositorOutputSurfaceCapturer::Destroy, |
+ base::Owned(this))); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::NotifyCaptureParameters( |
+ const gfx::Size& buffer_size, |
+ const gfx::Rect& visible_rect) { |
+ DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); |
+ |
+ ui_compositor_message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&SurfaceCapturer::Client::NotifyCaptureParameters, |
+ client_, |
+ buffer_size, |
+ visible_rect)); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::NotifyError(Error error) { |
+ DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); |
+ ui_compositor_message_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&SurfaceCapturer::Client::NotifyError, |
+ client_, |
+ error)); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::NotifySwapBuffersOnImplThread() { |
danakj
2013/08/15 21:39:41
Why are you capturing the compositor's output afte
sheu
2013/08/15 21:48:05
I'm doing this for the purposes of being able to c
danakj
2013/08/15 21:50:18
Can we extend CopyOutputRequest to satisfy this ra
|
+ DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); |
+ if (input_frames_.empty()) |
+ return; |
+ |
+ capturer_->Capture(input_frames_.front()); |
+ input_frames_.pop_front(); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::DoDestroyOnImplThread() { |
+ DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); |
+ BrowserCompositorOutputSurface* surface = |
+ output_surface_map_->Lookup(output_surface_id_); |
+ if (surface) |
+ surface->RemoveCapturer(this); |
+ if (capturer_) |
+ capturer_.release()->Destroy(); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::DoInitializeOnImplThread( |
+ media::VideoFrame::Format format) { |
+ DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); |
+ DCHECK(!capturer_); |
+ |
+ BrowserCompositorOutputSurface* surface = |
+ output_surface_map_->Lookup(output_surface_id_); |
+ if (!surface) { |
+ NotifyError(kPlatformFailureError); |
+ return; |
+ } |
+ CommandBufferProxyImpl* command_buffer = |
+ surface->GetContext3DCommandBufferImpl()->GetCommandBufferProxy(); |
+ if (!command_buffer) { |
+ NotifyError(kPlatformFailureError); |
+ return; |
+ } |
+ capturer_ = command_buffer->CreateSurfaceCapturer(this).Pass(); |
+ if (!capturer_) { |
+ NotifyError(kPlatformFailureError); |
+ return; |
+ } |
+ surface->AddCapturer(this); |
+ capturer_->Initialize(format); |
+} |
+ |
+void BrowserCompositorOutputSurfaceCapturer::DoCaptureOnImplThread( |
+ const scoped_refptr<media::VideoFrame>& frame) { |
+ DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); |
+ input_frames_.push_back(frame); |
+} |
+ |
+} // namespace content |