Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(326)

Side by Side Diff: content/browser/media/capture/aura_window_capture_machine.cc

Issue 1922143004: Short-term fix for Aura Desktop/Window capture. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/media/capture/aura_window_capture_machine.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/media/capture/aura_window_capture_machine.h" 5 #include "content/browser/media/capture/aura_window_capture_machine.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 return false; 73 return false;
74 74
75 DCHECK(oracle_proxy); 75 DCHECK(oracle_proxy);
76 oracle_proxy_ = oracle_proxy; 76 oracle_proxy_ = oracle_proxy;
77 capture_params_ = params; 77 capture_params_ = params;
78 78
79 // Update capture size. 79 // Update capture size.
80 UpdateCaptureSize(); 80 UpdateCaptureSize();
81 81
82 // Start observing compositor updates. 82 // Start observing compositor updates.
83 if (desktop_window_->GetHost()) 83 if (aura::WindowTreeHost* host = desktop_window_->GetHost()) {
84 desktop_window_->GetHost()->compositor()->AddObserver(this); 84 if (ui::Compositor* compositor = host->compositor())
85 compositor->AddAnimationObserver(this);
86 }
GeorgeZ 2016/04/27 16:44:34 The function may return false if host or composito
miu 2016/04/27 19:01:24 Done.
85 87
86 power_save_blocker_.reset( 88 power_save_blocker_.reset(
87 PowerSaveBlocker::Create( 89 PowerSaveBlocker::Create(
88 PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, 90 PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
89 PowerSaveBlocker::kReasonOther, 91 PowerSaveBlocker::kReasonOther,
90 "DesktopCaptureDevice is running").release()); 92 "DesktopCaptureDevice is running").release());
91 93
92 return true; 94 return true;
93 } 95 }
94 96
95 void AuraWindowCaptureMachine::Stop(const base::Closure& callback) { 97 void AuraWindowCaptureMachine::Stop(const base::Closure& callback) {
96 // Stops the capture machine asynchronously. 98 // Stops the capture machine asynchronously.
97 BrowserThread::PostTask( 99 BrowserThread::PostTask(
98 BrowserThread::UI, FROM_HERE, base::Bind( 100 BrowserThread::UI, FROM_HERE, base::Bind(
99 &AuraWindowCaptureMachine::InternalStop, 101 &AuraWindowCaptureMachine::InternalStop,
100 base::Unretained(this), 102 base::Unretained(this),
101 callback)); 103 callback));
102 } 104 }
103 105
104 void AuraWindowCaptureMachine::InternalStop(const base::Closure& callback) { 106 void AuraWindowCaptureMachine::InternalStop(const base::Closure& callback) {
105 DCHECK_CURRENTLY_ON(BrowserThread::UI); 107 DCHECK_CURRENTLY_ON(BrowserThread::UI);
106 108
107 // Cancel any and all outstanding callbacks owned by external modules. 109 // Cancel any and all outstanding callbacks owned by external modules.
108 weak_factory_.InvalidateWeakPtrs(); 110 weak_factory_.InvalidateWeakPtrs();
109 111
110 power_save_blocker_.reset(); 112 power_save_blocker_.reset();
111 113
112 // Stop observing compositor and window events. 114 // Stop observing compositor and window events.
113 if (desktop_window_) { 115 if (desktop_window_) {
114 aura::WindowTreeHost* window_host = desktop_window_->GetHost(); 116 if (aura::WindowTreeHost* host = desktop_window_->GetHost()) {
115 // In the host destructor the compositor is destroyed before the window. 117 if (ui::Compositor* compositor = host->compositor())
116 if (window_host && window_host->compositor()) 118 compositor->RemoveAnimationObserver(this);
117 window_host->compositor()->RemoveObserver(this); 119 }
118 desktop_window_->RemoveObserver(this); 120 desktop_window_->RemoveObserver(this);
119 desktop_window_ = NULL; 121 desktop_window_ = NULL;
120 cursor_renderer_.reset(); 122 cursor_renderer_.reset();
121 } 123 }
122 124
123 callback.Run(); 125 callback.Run();
124 } 126 }
125 127
126 void AuraWindowCaptureMachine::MaybeCaptureForRefresh() { 128 void AuraWindowCaptureMachine::MaybeCaptureForRefresh() {
127 BrowserThread::PostTask( 129 BrowserThread::PostTask(
128 BrowserThread::UI, FROM_HERE, 130 BrowserThread::UI, FROM_HERE,
129 base::Bind(&AuraWindowCaptureMachine::Capture, 131 base::Bind(&AuraWindowCaptureMachine::Capture,
130 // Use of Unretained() is safe here since this task must run 132 // Use of Unretained() is safe here since this task must run
131 // before InternalStop(). 133 // before InternalStop().
132 base::Unretained(this), 134 base::Unretained(this),
133 false)); 135 base::TimeTicks()));
134 } 136 }
135 137
136 void AuraWindowCaptureMachine::SetWindow(aura::Window* window) { 138 void AuraWindowCaptureMachine::SetWindow(aura::Window* window) {
137 DCHECK_CURRENTLY_ON(BrowserThread::UI); 139 DCHECK_CURRENTLY_ON(BrowserThread::UI);
138 140
139 DCHECK(!desktop_window_); 141 DCHECK(!desktop_window_);
140 desktop_window_ = window; 142 desktop_window_ = window;
141 cursor_renderer_.reset(new CursorRendererAura(window, kCursorAlwaysEnabled)); 143 cursor_renderer_.reset(new CursorRendererAura(window, kCursorAlwaysEnabled));
142 144
143 // Start observing window events. 145 // Start observing window events.
144 desktop_window_->AddObserver(this); 146 desktop_window_->AddObserver(this);
145 147
146 // We must store this for the UMA reporting in DidCopyOutput() as 148 // We must store this for the UMA reporting in DidCopyOutput() as
147 // desktop_window_ might be destroyed at that point. 149 // desktop_window_ might be destroyed at that point.
148 screen_capture_ = window->IsRootWindow(); 150 screen_capture_ = window->IsRootWindow();
149 IncrementDesktopCaptureCounter(screen_capture_ ? SCREEN_CAPTURER_CREATED 151 IncrementDesktopCaptureCounter(screen_capture_ ? SCREEN_CAPTURER_CREATED
150 : WINDOW_CAPTURER_CREATED); 152 : WINDOW_CAPTURER_CREATED);
151 } 153 }
152 154
153 void AuraWindowCaptureMachine::UpdateCaptureSize() { 155 void AuraWindowCaptureMachine::UpdateCaptureSize() {
154 DCHECK_CURRENTLY_ON(BrowserThread::UI); 156 DCHECK_CURRENTLY_ON(BrowserThread::UI);
155 if (oracle_proxy_ && desktop_window_) { 157 if (oracle_proxy_ && desktop_window_) {
156 ui::Layer* layer = desktop_window_->layer(); 158 ui::Layer* layer = desktop_window_->layer();
157 oracle_proxy_->UpdateCaptureSize(ui::ConvertSizeToPixel( 159 oracle_proxy_->UpdateCaptureSize(ui::ConvertSizeToPixel(
158 layer, layer->bounds().size())); 160 layer, layer->bounds().size()));
159 } 161 }
160 cursor_renderer_->Clear(); 162 cursor_renderer_->Clear();
161 } 163 }
162 164
163 void AuraWindowCaptureMachine::Capture(bool dirty) { 165 void AuraWindowCaptureMachine::Capture(base::TimeTicks event_time) {
164 DCHECK_CURRENTLY_ON(BrowserThread::UI); 166 DCHECK_CURRENTLY_ON(BrowserThread::UI);
165 167
166 // Do not capture if the desktop window is already destroyed. 168 // Do not capture if the desktop window is already destroyed.
167 if (!desktop_window_) 169 if (!desktop_window_)
168 return; 170 return;
169 171
170 scoped_refptr<media::VideoFrame> frame; 172 scoped_refptr<media::VideoFrame> frame;
171 media::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; 173 media::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
172 174
173 // TODO(miu): Need to fix this so the compositor is providing the presentation 175 // TODO(miu): Need to fix this so the compositor is providing the presentation
174 // timestamps and damage regions, to leverage the frame timestamp rewriting 176 // timestamps and damage regions, to leverage the frame timestamp rewriting
175 // logic. http://crbug.com/492839 177 // logic. http://crbug.com/492839
176 const base::TimeTicks start_time = base::TimeTicks::Now(); 178 const base::TimeTicks start_time = base::TimeTicks::Now();
177 const media::VideoCaptureOracle::Event event = 179 media::VideoCaptureOracle::Event event;
178 dirty ? media::VideoCaptureOracle::kCompositorUpdate 180 if (event_time.is_null()) {
179 : media::VideoCaptureOracle::kActiveRefreshRequest; 181 event = media::VideoCaptureOracle::kActiveRefreshRequest;
182 event_time = start_time;
183 } else {
184 event = media::VideoCaptureOracle::kCompositorUpdate;
185 }
180 if (oracle_proxy_->ObserveEventAndDecideCapture( 186 if (oracle_proxy_->ObserveEventAndDecideCapture(
181 event, gfx::Rect(), start_time, &frame, &capture_frame_cb)) { 187 event, gfx::Rect(), event_time, &frame, &capture_frame_cb)) {
182 std::unique_ptr<cc::CopyOutputRequest> request = 188 std::unique_ptr<cc::CopyOutputRequest> request =
183 cc::CopyOutputRequest::CreateRequest(base::Bind( 189 cc::CopyOutputRequest::CreateRequest(base::Bind(
184 &AuraWindowCaptureMachine::DidCopyOutput, 190 &AuraWindowCaptureMachine::DidCopyOutput,
185 weak_factory_.GetWeakPtr(), frame, start_time, capture_frame_cb)); 191 weak_factory_.GetWeakPtr(), frame, event_time, start_time,
192 capture_frame_cb));
186 gfx::Rect window_rect = gfx::Rect(desktop_window_->bounds().width(), 193 gfx::Rect window_rect = gfx::Rect(desktop_window_->bounds().width(),
187 desktop_window_->bounds().height()); 194 desktop_window_->bounds().height());
188 request->set_area(window_rect); 195 request->set_area(window_rect);
189 desktop_window_->layer()->RequestCopyOfOutput(std::move(request)); 196 desktop_window_->layer()->RequestCopyOfOutput(std::move(request));
190 } 197 }
191 } 198 }
192 199
193 void AuraWindowCaptureMachine::DidCopyOutput( 200 void AuraWindowCaptureMachine::DidCopyOutput(
194 scoped_refptr<media::VideoFrame> video_frame, 201 scoped_refptr<media::VideoFrame> video_frame,
202 base::TimeTicks event_time,
195 base::TimeTicks start_time, 203 base::TimeTicks start_time,
196 const CaptureFrameCallback& capture_frame_cb, 204 const CaptureFrameCallback& capture_frame_cb,
197 std::unique_ptr<cc::CopyOutputResult> result) { 205 std::unique_ptr<cc::CopyOutputResult> result) {
198 DCHECK_CURRENTLY_ON(BrowserThread::UI); 206 DCHECK_CURRENTLY_ON(BrowserThread::UI);
199 207
200 static bool first_call = true; 208 static bool first_call = true;
201 209
202 const bool succeeded = ProcessCopyOutputResponse( 210 const bool succeeded = ProcessCopyOutputResponse(
203 video_frame, start_time, capture_frame_cb, std::move(result)); 211 video_frame, event_time, capture_frame_cb, std::move(result));
204 212
205 base::TimeDelta capture_time = base::TimeTicks::Now() - start_time; 213 const base::TimeDelta capture_time = base::TimeTicks::Now() - start_time;
206 214
207 // The two UMA_ blocks must be put in its own scope since it creates a static 215 // The two UMA_ blocks must be put in its own scope since it creates a static
208 // variable which expected constant histogram name. 216 // variable which expected constant histogram name.
209 if (screen_capture_) { 217 if (screen_capture_) {
210 UMA_HISTOGRAM_TIMES(kUmaScreenCaptureTime, capture_time); 218 UMA_HISTOGRAM_TIMES(kUmaScreenCaptureTime, capture_time);
211 } else { 219 } else {
212 UMA_HISTOGRAM_TIMES(kUmaWindowCaptureTime, capture_time); 220 UMA_HISTOGRAM_TIMES(kUmaWindowCaptureTime, capture_time);
213 } 221 }
214 222
215 if (first_call) { 223 if (first_call) {
216 first_call = false; 224 first_call = false;
217 if (screen_capture_) { 225 if (screen_capture_) {
218 IncrementDesktopCaptureCounter(succeeded ? FIRST_SCREEN_CAPTURE_SUCCEEDED 226 IncrementDesktopCaptureCounter(succeeded ? FIRST_SCREEN_CAPTURE_SUCCEEDED
219 : FIRST_SCREEN_CAPTURE_FAILED); 227 : FIRST_SCREEN_CAPTURE_FAILED);
220 } else { 228 } else {
221 IncrementDesktopCaptureCounter(succeeded 229 IncrementDesktopCaptureCounter(succeeded
222 ? FIRST_WINDOW_CAPTURE_SUCCEEDED 230 ? FIRST_WINDOW_CAPTURE_SUCCEEDED
223 : FIRST_WINDOW_CAPTURE_FAILED); 231 : FIRST_WINDOW_CAPTURE_FAILED);
224 } 232 }
225 } 233 }
226 234
227 // If ProcessCopyOutputResponse() failed, it will not run |capture_frame_cb|, 235 // If ProcessCopyOutputResponse() failed, it will not run |capture_frame_cb|,
228 // so do that now. 236 // so do that now.
229 if (!succeeded) 237 if (!succeeded)
230 capture_frame_cb.Run(video_frame, start_time, false); 238 capture_frame_cb.Run(video_frame, event_time, false);
231 } 239 }
232 240
233 bool AuraWindowCaptureMachine::ProcessCopyOutputResponse( 241 bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
234 scoped_refptr<media::VideoFrame> video_frame, 242 scoped_refptr<media::VideoFrame> video_frame,
235 base::TimeTicks start_time, 243 base::TimeTicks event_time,
236 const CaptureFrameCallback& capture_frame_cb, 244 const CaptureFrameCallback& capture_frame_cb,
237 std::unique_ptr<cc::CopyOutputResult> result) { 245 std::unique_ptr<cc::CopyOutputResult> result) {
238 DCHECK_CURRENTLY_ON(BrowserThread::UI); 246 DCHECK_CURRENTLY_ON(BrowserThread::UI);
239 247
240 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_window_) 248 if (!desktop_window_) {
249 VLOG(1) << "Ignoring CopyOutputResult: Capture target has gone away.";
241 return false; 250 return false;
251 }
252 if (result->IsEmpty()) {
253 VLOG(1) << "CopyOutputRequest failed: No texture or bitmap in result.";
254 return false;
255 }
256 if (result->size().IsEmpty()) {
257 VLOG(1) << "CopyOutputRequest failed: Zero-area texture/bitmap result.";
258 return false;
259 }
242 DCHECK(video_frame); 260 DCHECK(video_frame);
243 261
244 // Compute the dest size we want after the letterboxing resize. Make the 262 // Compute the dest size we want after the letterboxing resize. Make the
245 // coordinates and sizes even because we letterbox in YUV space 263 // coordinates and sizes even because we letterbox in YUV space
246 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to 264 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
247 // line up correctly. 265 // line up correctly.
248 // The video frame's visible_rect() and the result's size() are both physical 266 // The video frame's visible_rect() and the result's size() are both physical
249 // pixels. 267 // pixels.
250 gfx::Rect region_in_frame = media::ComputeLetterboxRegion( 268 gfx::Rect region_in_frame = media::ComputeLetterboxRegion(
251 video_frame->visible_rect(), result->size()); 269 video_frame->visible_rect(), result->size());
252 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, 270 region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
253 region_in_frame.y() & ~1, 271 region_in_frame.y() & ~1,
254 region_in_frame.width() & ~1, 272 region_in_frame.width() & ~1,
255 region_in_frame.height() & ~1); 273 region_in_frame.height() & ~1);
256 if (region_in_frame.IsEmpty()) 274 if (region_in_frame.IsEmpty()) {
275 VLOG(1) << "Aborting capture: Computed empty letterboxed content region.";
257 return false; 276 return false;
277 }
258 278
259 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 279 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
260 display_compositor::GLHelper* gl_helper = factory->GetGLHelper(); 280 display_compositor::GLHelper* gl_helper = factory->GetGLHelper();
261 if (!gl_helper) 281 if (!gl_helper) {
282 VLOG(1) << "Aborting capture: No GLHelper available for YUV readback.";
262 return false; 283 return false;
284 }
263 285
264 cc::TextureMailbox texture_mailbox; 286 cc::TextureMailbox texture_mailbox;
265 std::unique_ptr<cc::SingleReleaseCallback> release_callback; 287 std::unique_ptr<cc::SingleReleaseCallback> release_callback;
266 result->TakeTexture(&texture_mailbox, &release_callback); 288 result->TakeTexture(&texture_mailbox, &release_callback);
267 DCHECK(texture_mailbox.IsTexture()); 289 DCHECK(texture_mailbox.IsTexture());
268 if (!texture_mailbox.IsTexture()) 290 if (!texture_mailbox.IsTexture()) {
291 VLOG(1) << "Aborting capture: Failed to take texture from mailbox.";
269 return false; 292 return false;
293 }
270 294
271 gfx::Rect result_rect(result->size()); 295 gfx::Rect result_rect(result->size());
272 if (!yuv_readback_pipeline_ || 296 if (!yuv_readback_pipeline_ ||
273 yuv_readback_pipeline_->scaler()->SrcSize() != result_rect.size() || 297 yuv_readback_pipeline_->scaler()->SrcSize() != result_rect.size() ||
274 yuv_readback_pipeline_->scaler()->SrcSubrect() != result_rect || 298 yuv_readback_pipeline_->scaler()->SrcSubrect() != result_rect ||
275 yuv_readback_pipeline_->scaler()->DstSize() != region_in_frame.size()) { 299 yuv_readback_pipeline_->scaler()->DstSize() != region_in_frame.size()) {
276 yuv_readback_pipeline_.reset(gl_helper->CreateReadbackPipelineYUV( 300 yuv_readback_pipeline_.reset(gl_helper->CreateReadbackPipelineYUV(
277 display_compositor::GLHelper::SCALER_QUALITY_FAST, result_rect.size(), 301 display_compositor::GLHelper::SCALER_QUALITY_FAST, result_rect.size(),
278 result_rect, region_in_frame.size(), true, true)); 302 result_rect, region_in_frame.size(), true, true));
279 } 303 }
280 304
281 cursor_renderer_->SnapshotCursorState(region_in_frame); 305 cursor_renderer_->SnapshotCursorState(region_in_frame);
282 yuv_readback_pipeline_->ReadbackYUV( 306 yuv_readback_pipeline_->ReadbackYUV(
283 texture_mailbox.mailbox(), texture_mailbox.sync_token(), 307 texture_mailbox.mailbox(), texture_mailbox.sync_token(),
284 video_frame->visible_rect(), 308 video_frame->visible_rect(),
285 video_frame->stride(media::VideoFrame::kYPlane), 309 video_frame->stride(media::VideoFrame::kYPlane),
286 video_frame->data(media::VideoFrame::kYPlane), 310 video_frame->data(media::VideoFrame::kYPlane),
287 video_frame->stride(media::VideoFrame::kUPlane), 311 video_frame->stride(media::VideoFrame::kUPlane),
288 video_frame->data(media::VideoFrame::kUPlane), 312 video_frame->data(media::VideoFrame::kUPlane),
289 video_frame->stride(media::VideoFrame::kVPlane), 313 video_frame->stride(media::VideoFrame::kVPlane),
290 video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(), 314 video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(),
291 base::Bind(&CopyOutputFinishedForVideo, weak_factory_.GetWeakPtr(), 315 base::Bind(&CopyOutputFinishedForVideo, weak_factory_.GetWeakPtr(),
292 start_time, capture_frame_cb, video_frame, 316 event_time, capture_frame_cb, video_frame,
293 base::Passed(&release_callback))); 317 base::Passed(&release_callback)));
294 media::LetterboxYUV(video_frame.get(), region_in_frame); 318 media::LetterboxYUV(video_frame.get(), region_in_frame);
295 return true; 319 return true;
296 } 320 }
297 321
298 using CaptureFrameCallback = 322 using CaptureFrameCallback =
299 media::ThreadSafeCaptureOracle::CaptureFrameCallback; 323 media::ThreadSafeCaptureOracle::CaptureFrameCallback;
300 324
301 void AuraWindowCaptureMachine::CopyOutputFinishedForVideo( 325 void AuraWindowCaptureMachine::CopyOutputFinishedForVideo(
302 base::WeakPtr<AuraWindowCaptureMachine> machine, 326 base::WeakPtr<AuraWindowCaptureMachine> machine,
303 base::TimeTicks start_time, 327 base::TimeTicks event_time,
304 const CaptureFrameCallback& capture_frame_cb, 328 const CaptureFrameCallback& capture_frame_cb,
305 const scoped_refptr<media::VideoFrame>& target, 329 const scoped_refptr<media::VideoFrame>& target,
306 std::unique_ptr<cc::SingleReleaseCallback> release_callback, 330 std::unique_ptr<cc::SingleReleaseCallback> release_callback,
307 bool result) { 331 bool result) {
308 DCHECK_CURRENTLY_ON(BrowserThread::UI); 332 DCHECK_CURRENTLY_ON(BrowserThread::UI);
309 333
310 release_callback->Run(gpu::SyncToken(), false); 334 release_callback->Run(gpu::SyncToken(), false);
311 335
312 // Render the cursor and deliver the captured frame if the 336 // Render the cursor and deliver the captured frame if the
313 // AuraWindowCaptureMachine has not been stopped (i.e., the WeakPtr is 337 // AuraWindowCaptureMachine has not been stopped (i.e., the WeakPtr is
314 // still valid). 338 // still valid).
315 if (machine) { 339 if (machine) {
316 if (machine->cursor_renderer_ && result) 340 if (machine->cursor_renderer_ && result)
317 machine->cursor_renderer_->RenderOnVideoFrame(target); 341 machine->cursor_renderer_->RenderOnVideoFrame(target);
318 } else { 342 } else {
343 VLOG(1) << "Aborting capture: AuraWindowCaptureMachine has gone away.";
319 result = false; 344 result = false;
320 } 345 }
321 346
322 capture_frame_cb.Run(target, start_time, result); 347 capture_frame_cb.Run(target, event_time, result);
323 } 348 }
324 349
325 void AuraWindowCaptureMachine::OnWindowBoundsChanged( 350 void AuraWindowCaptureMachine::OnWindowBoundsChanged(
326 aura::Window* window, 351 aura::Window* window,
327 const gfx::Rect& old_bounds, 352 const gfx::Rect& old_bounds,
328 const gfx::Rect& new_bounds) { 353 const gfx::Rect& new_bounds) {
329 DCHECK_CURRENTLY_ON(BrowserThread::UI); 354 DCHECK_CURRENTLY_ON(BrowserThread::UI);
330 DCHECK(desktop_window_ && window == desktop_window_); 355 DCHECK(desktop_window_ && window == desktop_window_);
331 356
332 // Post a task to update capture size after first returning to the event loop. 357 // Post a task to update capture size after first returning to the event loop.
333 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( 358 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
334 &AuraWindowCaptureMachine::UpdateCaptureSize, 359 &AuraWindowCaptureMachine::UpdateCaptureSize,
335 weak_factory_.GetWeakPtr())); 360 weak_factory_.GetWeakPtr()));
336 } 361 }
337 362
338 void AuraWindowCaptureMachine::OnWindowDestroying(aura::Window* window) { 363 void AuraWindowCaptureMachine::OnWindowDestroying(aura::Window* window) {
339 DCHECK_CURRENTLY_ON(BrowserThread::UI); 364 DCHECK_CURRENTLY_ON(BrowserThread::UI);
340 365
341 InternalStop(base::Bind(&base::DoNothing)); 366 InternalStop(base::Bind(&base::DoNothing));
342 367
343 oracle_proxy_->ReportError(FROM_HERE, "OnWindowDestroying()"); 368 oracle_proxy_->ReportError(FROM_HERE, "OnWindowDestroying()");
344 } 369 }
345 370
346 void AuraWindowCaptureMachine::OnWindowAddedToRootWindow( 371 void AuraWindowCaptureMachine::OnWindowAddedToRootWindow(
347 aura::Window* window) { 372 aura::Window* window) {
348 DCHECK_CURRENTLY_ON(BrowserThread::UI); 373 DCHECK_CURRENTLY_ON(BrowserThread::UI);
349 DCHECK(window == desktop_window_); 374 DCHECK(window == desktop_window_);
350 375
351 window->GetHost()->compositor()->AddObserver(this); 376 if (aura::WindowTreeHost* host = window->GetHost()) {
377 if (ui::Compositor* compositor = host->compositor())
378 compositor->AddAnimationObserver(this);
379 }
352 } 380 }
353 381
354 void AuraWindowCaptureMachine::OnWindowRemovingFromRootWindow( 382 void AuraWindowCaptureMachine::OnWindowRemovingFromRootWindow(
355 aura::Window* window, 383 aura::Window* window,
356 aura::Window* new_root) { 384 aura::Window* new_root) {
357 DCHECK_CURRENTLY_ON(BrowserThread::UI); 385 DCHECK_CURRENTLY_ON(BrowserThread::UI);
358 DCHECK(window == desktop_window_); 386 DCHECK(window == desktop_window_);
359 387
360 window->GetHost()->compositor()->RemoveObserver(this); 388 if (aura::WindowTreeHost* host = window->GetHost()) {
389 if (ui::Compositor* compositor = host->compositor())
390 compositor->RemoveAnimationObserver(this);
391 }
361 } 392 }
362 393
363 void AuraWindowCaptureMachine::OnCompositingEnded( 394 void AuraWindowCaptureMachine::OnAnimationStep(base::TimeTicks timestamp) {
395 DCHECK_CURRENTLY_ON(BrowserThread::UI);
396 DCHECK(!timestamp.is_null());
397
398 // HACK: The compositor invokes this observer method to step layer animation
399 // forward. Scheduling frame capture was not the intention, and so invoking
400 // this method does not actually indicate the content has changed. However,
401 // this is the only reliable way to ensure all screen changes are captured, as
402 // of this writing.
403 // http://crbug.com/600031
404 //
405 // TODO(miu): Need a better observer callback interface from the compositor
406 // for this use case. The solution here will always capture frames at the
407 // maximum framerate, which means CPU/GPU is being wasted on redundant
408 // captures and quality/smoothness of animating content will suffer
409 // significantly.
410 // http://crbug.com/492839
411 Capture(timestamp);
412 }
413
414 void AuraWindowCaptureMachine::OnCompositingShuttingDown(
364 ui::Compositor* compositor) { 415 ui::Compositor* compositor) {
365 DCHECK_CURRENTLY_ON(BrowserThread::UI); 416 DCHECK_CURRENTLY_ON(BrowserThread::UI);
366 417 compositor->RemoveAnimationObserver(this);
367 // TODO(miu): The CopyOutputRequest should be made earlier, at WillCommit().
368 // http://crbug.com/492839
369 BrowserThread::PostTask(
370 BrowserThread::UI,
371 FROM_HERE,
372 base::Bind(&AuraWindowCaptureMachine::Capture, weak_factory_.GetWeakPtr(),
373 true));
374 } 418 }
375 419
376 } // namespace content 420 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/capture/aura_window_capture_machine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698