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

Unified Diff: content/browser/media/capture/aura_window_capture_machine.cc

Issue 1942493002: Short-term fix for Aura Desktop/Window capture. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2704
Patch Set: Created 4 years, 8 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/media/capture/aura_window_capture_machine.cc
diff --git a/content/browser/media/capture/aura_window_capture_machine.cc b/content/browser/media/capture/aura_window_capture_machine.cc
index 1ff155742ca23a6076972d99623c01b0261fb4d9..864243efee3a07bae69332451b2783106ab2d390 100644
--- a/content/browser/media/capture/aura_window_capture_machine.cc
+++ b/content/browser/media/capture/aura_window_capture_machine.cc
@@ -80,8 +80,11 @@ bool AuraWindowCaptureMachine::InternalStart(
UpdateCaptureSize();
// Start observing compositor updates.
- if (desktop_window_->GetHost())
- desktop_window_->GetHost()->compositor()->AddObserver(this);
+ aura::WindowTreeHost* const host = desktop_window_->GetHost();
+ ui::Compositor* const compositor = host ? host->compositor() : nullptr;
+ if (!compositor)
+ return false;
+ compositor->AddAnimationObserver(this);
power_save_blocker_.reset(
PowerSaveBlocker::Create(
@@ -111,10 +114,10 @@ void AuraWindowCaptureMachine::InternalStop(const base::Closure& callback) {
// Stop observing compositor and window events.
if (desktop_window_) {
- aura::WindowTreeHost* window_host = desktop_window_->GetHost();
- // In the host destructor the compositor is destroyed before the window.
- if (window_host && window_host->compositor())
- window_host->compositor()->RemoveObserver(this);
+ if (aura::WindowTreeHost* host = desktop_window_->GetHost()) {
+ if (ui::Compositor* compositor = host->compositor())
+ compositor->RemoveAnimationObserver(this);
+ }
desktop_window_->RemoveObserver(this);
desktop_window_ = NULL;
cursor_renderer_.reset();
@@ -130,7 +133,7 @@ void AuraWindowCaptureMachine::MaybeCaptureForRefresh() {
// Use of Unretained() is safe here since this task must run
// before InternalStop().
base::Unretained(this),
- false));
+ base::TimeTicks()));
}
void AuraWindowCaptureMachine::SetWindow(aura::Window* window) {
@@ -160,7 +163,7 @@ void AuraWindowCaptureMachine::UpdateCaptureSize() {
cursor_renderer_->Clear();
}
-void AuraWindowCaptureMachine::Capture(bool dirty) {
+void AuraWindowCaptureMachine::Capture(base::TimeTicks event_time) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Do not capture if the desktop window is already destroyed.
@@ -174,15 +177,20 @@ void AuraWindowCaptureMachine::Capture(bool dirty) {
// timestamps and damage regions, to leverage the frame timestamp rewriting
// logic. http://crbug.com/492839
const base::TimeTicks start_time = base::TimeTicks::Now();
- const media::VideoCaptureOracle::Event event =
- dirty ? media::VideoCaptureOracle::kCompositorUpdate
- : media::VideoCaptureOracle::kActiveRefreshRequest;
+ media::VideoCaptureOracle::Event event;
+ if (event_time.is_null()) {
+ event = media::VideoCaptureOracle::kActiveRefreshRequest;
+ event_time = start_time;
+ } else {
+ event = media::VideoCaptureOracle::kCompositorUpdate;
+ }
if (oracle_proxy_->ObserveEventAndDecideCapture(
- event, gfx::Rect(), start_time, &frame, &capture_frame_cb)) {
+ event, gfx::Rect(), event_time, &frame, &capture_frame_cb)) {
std::unique_ptr<cc::CopyOutputRequest> request =
cc::CopyOutputRequest::CreateRequest(base::Bind(
&AuraWindowCaptureMachine::DidCopyOutput,
- weak_factory_.GetWeakPtr(), frame, start_time, capture_frame_cb));
+ weak_factory_.GetWeakPtr(), frame, event_time, start_time,
+ capture_frame_cb));
gfx::Rect window_rect = gfx::Rect(desktop_window_->bounds().width(),
desktop_window_->bounds().height());
request->set_area(window_rect);
@@ -192,6 +200,7 @@ void AuraWindowCaptureMachine::Capture(bool dirty) {
void AuraWindowCaptureMachine::DidCopyOutput(
scoped_refptr<media::VideoFrame> video_frame,
+ base::TimeTicks event_time,
base::TimeTicks start_time,
const CaptureFrameCallback& capture_frame_cb,
std::unique_ptr<cc::CopyOutputResult> result) {
@@ -200,9 +209,9 @@ void AuraWindowCaptureMachine::DidCopyOutput(
static bool first_call = true;
const bool succeeded = ProcessCopyOutputResponse(
- video_frame, start_time, capture_frame_cb, std::move(result));
+ video_frame, event_time, capture_frame_cb, std::move(result));
- base::TimeDelta capture_time = base::TimeTicks::Now() - start_time;
+ const base::TimeDelta capture_time = base::TimeTicks::Now() - start_time;
// The two UMA_ blocks must be put in its own scope since it creates a static
// variable which expected constant histogram name.
@@ -227,18 +236,28 @@ void AuraWindowCaptureMachine::DidCopyOutput(
// If ProcessCopyOutputResponse() failed, it will not run |capture_frame_cb|,
// so do that now.
if (!succeeded)
- capture_frame_cb.Run(video_frame, start_time, false);
+ capture_frame_cb.Run(video_frame, event_time, false);
}
bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks start_time,
+ base::TimeTicks event_time,
const CaptureFrameCallback& capture_frame_cb,
std::unique_ptr<cc::CopyOutputResult> result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (result->IsEmpty() || result->size().IsEmpty() || !desktop_window_)
+ if (!desktop_window_) {
+ VLOG(1) << "Ignoring CopyOutputResult: Capture target has gone away.";
+ return false;
+ }
+ if (result->IsEmpty()) {
+ VLOG(1) << "CopyOutputRequest failed: No texture or bitmap in result.";
return false;
+ }
+ if (result->size().IsEmpty()) {
+ VLOG(1) << "CopyOutputRequest failed: Zero-area texture/bitmap result.";
+ return false;
+ }
DCHECK(video_frame);
// Compute the dest size we want after the letterboxing resize. Make the
@@ -253,20 +272,26 @@ bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
region_in_frame.y() & ~1,
region_in_frame.width() & ~1,
region_in_frame.height() & ~1);
- if (region_in_frame.IsEmpty())
+ if (region_in_frame.IsEmpty()) {
+ VLOG(1) << "Aborting capture: Computed empty letterboxed content region.";
return false;
+ }
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
GLHelper* gl_helper = factory->GetGLHelper();
- if (!gl_helper)
+ if (!gl_helper) {
+ VLOG(1) << "Aborting capture: No GLHelper available for YUV readback.";
return false;
+ }
cc::TextureMailbox texture_mailbox;
std::unique_ptr<cc::SingleReleaseCallback> release_callback;
result->TakeTexture(&texture_mailbox, &release_callback);
DCHECK(texture_mailbox.IsTexture());
- if (!texture_mailbox.IsTexture())
+ if (!texture_mailbox.IsTexture()) {
+ VLOG(1) << "Aborting capture: Failed to take texture from mailbox.";
return false;
+ }
gfx::Rect result_rect(result->size());
if (!yuv_readback_pipeline_ ||
@@ -287,7 +312,7 @@ bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
texture_mailbox.mailbox(), texture_mailbox.sync_token(),
video_frame.get(), region_in_frame.origin(),
base::Bind(&CopyOutputFinishedForVideo, weak_factory_.GetWeakPtr(),
- start_time, capture_frame_cb, video_frame,
+ event_time, capture_frame_cb, video_frame,
base::Passed(&release_callback)));
return true;
}
@@ -297,7 +322,7 @@ using CaptureFrameCallback =
void AuraWindowCaptureMachine::CopyOutputFinishedForVideo(
base::WeakPtr<AuraWindowCaptureMachine> machine,
- base::TimeTicks start_time,
+ base::TimeTicks event_time,
const CaptureFrameCallback& capture_frame_cb,
const scoped_refptr<media::VideoFrame>& target,
std::unique_ptr<cc::SingleReleaseCallback> release_callback,
@@ -313,10 +338,11 @@ void AuraWindowCaptureMachine::CopyOutputFinishedForVideo(
if (machine->cursor_renderer_ && result)
machine->cursor_renderer_->RenderOnVideoFrame(target);
} else {
+ VLOG(1) << "Aborting capture: AuraWindowCaptureMachine has gone away.";
result = false;
}
- capture_frame_cb.Run(target, start_time, result);
+ capture_frame_cb.Run(target, event_time, result);
}
void AuraWindowCaptureMachine::OnWindowBoundsChanged(
@@ -345,7 +371,10 @@ void AuraWindowCaptureMachine::OnWindowAddedToRootWindow(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(window == desktop_window_);
- window->GetHost()->compositor()->AddObserver(this);
+ if (aura::WindowTreeHost* host = window->GetHost()) {
+ if (ui::Compositor* compositor = host->compositor())
+ compositor->AddAnimationObserver(this);
+ }
}
void AuraWindowCaptureMachine::OnWindowRemovingFromRootWindow(
@@ -354,20 +383,36 @@ void AuraWindowCaptureMachine::OnWindowRemovingFromRootWindow(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(window == desktop_window_);
- window->GetHost()->compositor()->RemoveObserver(this);
+ if (aura::WindowTreeHost* host = window->GetHost()) {
+ if (ui::Compositor* compositor = host->compositor())
+ compositor->RemoveAnimationObserver(this);
+ }
}
-void AuraWindowCaptureMachine::OnCompositingEnded(
- ui::Compositor* compositor) {
+void AuraWindowCaptureMachine::OnAnimationStep(base::TimeTicks timestamp) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // TODO(miu): The CopyOutputRequest should be made earlier, at WillCommit().
+ DCHECK(!timestamp.is_null());
+
+ // HACK: The compositor invokes this observer method to step layer animation
+ // forward. Scheduling frame capture was not the intention, and so invoking
+ // this method does not actually indicate the content has changed. However,
+ // this is the only reliable way to ensure all screen changes are captured, as
+ // of this writing.
+ // http://crbug.com/600031
+ //
+ // TODO(miu): Need a better observer callback interface from the compositor
+ // for this use case. The solution here will always capture frames at the
+ // maximum framerate, which means CPU/GPU is being wasted on redundant
+ // captures and quality/smoothness of animating content will suffer
+ // significantly.
// http://crbug.com/492839
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&AuraWindowCaptureMachine::Capture, weak_factory_.GetWeakPtr(),
- true));
+ Capture(timestamp);
+}
+
+void AuraWindowCaptureMachine::OnCompositingShuttingDown(
+ ui::Compositor* compositor) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ compositor->RemoveAnimationObserver(this);
}
} // namespace content
« 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