OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/browser/aura/browser_compositor_output_surface_capturer.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/location.h" | |
9 #include "base/message_loop/message_loop_proxy.h" | |
10 #include "content/browser/aura/browser_compositor_output_surface.h" | |
11 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" | |
12 #include "media/base/video_frame.h" | |
13 #include "ui/compositor/compositor.h" | |
14 | |
15 namespace content { | |
16 | |
17 BrowserCompositorOutputSurfaceCapturer::BrowserCompositorOutputSurfaceCapturer( | |
18 IDMap<BrowserCompositorOutputSurface>* output_surface_map, | |
19 int output_surface_id, | |
20 SurfaceCapturer::Client* client) | |
21 : output_surface_map_(output_surface_map), | |
22 output_surface_id_(output_surface_id), | |
23 client_ptr_factory_(client), | |
24 client_(client_ptr_factory_.GetWeakPtr()); | |
hshi1
2013/08/15 19:40:18
typo: ';' -> ','
| |
25 ui_compositor_message_loop_proxy_(base::MessageLoopProxy::current()) { | |
26 compositor_impl_message_loop_proxy_ = | |
27 ui::Compositor::GetCompositorMessageLoop(); | |
28 if (!compositor_impl_message_loop_proxy_) | |
29 compositor_impl_message_loop_proxy_ = ui_compositor_message_loop_proxy_; | |
30 } | |
31 | |
32 BrowserCompositorOutputSurfaceCapturer:: | |
33 ~BrowserCompositorOutputSurfaceCapturer() { | |
34 DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); | |
35 DCHECK(!capturer_); | |
36 } | |
37 | |
38 void BrowserCompositorOutputSurfaceCapturer::Initialize( | |
39 media::VideoFrame::Format format) { | |
40 DCHECK(ui_compositor_message_loop_proxy_->BelongsToCurrentThread()); | |
41 ui_compositor_message_loop_proxy_->PostTask( | |
42 FROM_HERE, | |
43 base::Bind( | |
44 &BrowserCompositorOutputSurfaceCapturer::DoInitializeOnImplThread, | |
45 base::Unretained(this), | |
46 format)); | |
47 } | |
48 | |
49 void BrowserCompositorOutputSurfaceCapturer::Capture( | |
50 const scoped_refptr<media::VideoFrame>& frame) { | |
51 DCHECK(ui_compositor_message_loop_proxy_->BelongsToCurrentThread()); | |
52 ui_compositor_message_loop_proxy_->PostTask( | |
53 FROM_HERE, | |
54 base::Bind(&BrowserCompositorOutputSurfaceCapturer::Capture, | |
55 base::Unretained(this), | |
56 frame)); | |
57 } | |
58 | |
59 void BrowserCompositorOutputSurfaceCapturer::Destroy() { | |
60 DCHECK(ui_compositor_message_loop_proxy_->BelongsToCurrentThread()); | |
61 client_ptr_factory_.InvalidateWeakPtrs(); | |
62 // Post |this| pointer as owned so we delete this after call. | |
63 ui_compositor_message_loop_proxy_->PostTask( | |
64 FROM_HERE, | |
65 base::Bind(&BrowserCompositorOutputSurfaceCapturer::Destroy, | |
66 base::Owned(this))); | |
67 } | |
68 | |
69 void BrowserCompositorOutputSurfaceCapturer::NotifyCaptureParameters( | |
70 const gfx::Size& buffer_size, | |
71 const gfx::Rect& visible_rect) { | |
72 DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); | |
73 | |
74 ui_compositor_message_loop_proxy_->PostTask( | |
75 FROM_HERE, | |
76 base::Bind(&SurfaceCapturer::Client::NotifyCaptureParameters, | |
77 client_, | |
78 buffer_size, | |
79 visible_rect)); | |
80 } | |
81 | |
82 void BrowserCompositorOutputSurfaceCapturer::NotifyError(Error error) { | |
83 DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); | |
84 ui_compositor_message_loop_proxy_->PostTask( | |
85 FROM_HERE, | |
86 base::Bind(&SurfaceCapturer::Client::NotifyError, | |
87 client_, | |
88 error)); | |
89 } | |
90 | |
91 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
| |
92 DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); | |
93 if (input_frames_.empty()) | |
94 return; | |
95 | |
96 capturer_->Capture(input_frames_.front()); | |
97 input_frames_.pop_front(); | |
98 } | |
99 | |
100 void BrowserCompositorOutputSurfaceCapturer::DoDestroyOnImplThread() { | |
101 DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); | |
102 BrowserCompositorOutputSurface* surface = | |
103 output_surface_map_->Lookup(output_surface_id_); | |
104 if (surface) | |
105 surface->RemoveCapturer(this); | |
106 if (capturer_) | |
107 capturer_.release()->Destroy(); | |
108 } | |
109 | |
110 void BrowserCompositorOutputSurfaceCapturer::DoInitializeOnImplThread( | |
111 media::VideoFrame::Format format) { | |
112 DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); | |
113 DCHECK(!capturer_); | |
114 | |
115 BrowserCompositorOutputSurface* surface = | |
116 output_surface_map_->Lookup(output_surface_id_); | |
117 if (!surface) { | |
118 NotifyError(kPlatformFailureError); | |
119 return; | |
120 } | |
121 CommandBufferProxyImpl* command_buffer = | |
122 surface->GetContext3DCommandBufferImpl()->GetCommandBufferProxy(); | |
123 if (!command_buffer) { | |
124 NotifyError(kPlatformFailureError); | |
125 return; | |
126 } | |
127 capturer_ = command_buffer->CreateSurfaceCapturer(this).Pass(); | |
128 if (!capturer_) { | |
129 NotifyError(kPlatformFailureError); | |
130 return; | |
131 } | |
132 surface->AddCapturer(this); | |
133 capturer_->Initialize(format); | |
134 } | |
135 | |
136 void BrowserCompositorOutputSurfaceCapturer::DoCaptureOnImplThread( | |
137 const scoped_refptr<media::VideoFrame>& frame) { | |
138 DCHECK(compositor_impl_message_loop_proxy_->BelongsToCurrentThread()); | |
139 input_frames_.push_back(frame); | |
140 } | |
141 | |
142 } // namespace content | |
OLD | NEW |