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

Unified Diff: content/renderer/render_widget.cc

Issue 23694031: Fix race conditions in window snapshot code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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
Index: content/renderer/render_widget.cc
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 0447d97c16c8514f9abfa7689bf236e5aa122bbd..ce8b45d56d7e1f9dd867b503214be6066ca5a988 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -368,6 +368,35 @@ bool RenderWidget::UsingSynchronousRendererCompositor() const {
#endif
}
+void RenderWidget::ScheduleCompositeWithForcedRedraw() {
+ ScheduleCompositeImpl(true);
+}
+
+void RenderWidget::ScheduleCompositeImpl(bool force_redraw) {
+ if (compositor_ && force_redraw) {
+ // Regardless of whether threaded compositing is enabled, always
+ // use this mechanism to force the compositor to redraw. However,
+ // the invalidation code path below is still needed for the
+ // non-threaded case.
+ compositor_->SetNeedsForcedRedraw();
+ }
+
+ if (RenderThreadImpl::current()->compositor_message_loop_proxy().get() &&
+ compositor_) {
+ if (!force_redraw) {
+ compositor_->setNeedsRedraw();
+ }
+ } else {
+ // TODO(nduca): replace with something a little less hacky. The reason this
+ // hack is still used is because the Invalidate-DoDeferredUpdate loop
+ // contains a lot of host-renderer synchronization logic that is still
+ // important for the accelerated compositing case. The option of simply
+ // duplicating all that code is less desirable than "faking out" the
+ // invalidation path using a magical damage rect.
+ didInvalidateRect(WebRect(0, 0, 1, 1));
+ }
+}
+
bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
@@ -616,6 +645,7 @@ void RenderWidget::OnUpdateRectAck() {
// If swapbuffers is still pending, then defer the update until the
// swapbuffers occurs.
if (num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) {
+ LOG(INFO) << "EarlyOut_SwapStillPending";
TRACE_EVENT0("renderer", "EarlyOut_SwapStillPending");
return;
}
@@ -768,6 +798,7 @@ void RenderWidget::OnViewContextSwapBuffersComplete() {
// When compositing deactivates, we reset the swapbuffers pending count. The
// swapbuffers acks may still arrive, however.
if (num_swapbuffers_complete_pending_ == 0) {
+ LOG(INFO) << "EarlyOut_ZeroSwapbuffersPending";
TRACE_EVENT0("renderer", "EarlyOut_ZeroSwapbuffersPending");
return;
}
@@ -783,6 +814,7 @@ void RenderWidget::OnViewContextSwapBuffersComplete() {
// If update reply is still pending, then defer the update until that reply
// occurs.
if (update_reply_pending_) {
+ LOG(INFO) << "EarlyOut_UpdateReplyPending";
TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending");
return;
}
@@ -792,6 +824,7 @@ void RenderWidget::OnViewContextSwapBuffersComplete() {
// posted, there may be software rendering work pending. In that case, don't
// early out.
if (!is_accelerated_compositing_active_ && invalidation_task_posted_) {
+ LOG(INFO) << "EarlyOut_AcceleratedCompositingOff";
TRACE_EVENT0("renderer", "EarlyOut_AcceleratedCompositingOff");
return;
}
@@ -801,6 +834,7 @@ void RenderWidget::OnViewContextSwapBuffersComplete() {
// callback coming back after we've navigated away from the page that
// generated it.
if (!animation_update_pending_ && !paint_aggregator_.HasPendingUpdate()) {
+ LOG(INFO) << "EarlyOut_NoPendingUpdate";
TRACE_EVENT0("renderer", "EarlyOut_NoPendingUpdate");
return;
}
@@ -1085,6 +1119,7 @@ void RenderWidget::PaintDebugBorder(const gfx::Rect& rect,
void RenderWidget::AnimationCallback() {
TRACE_EVENT0("renderer", "RenderWidget::AnimationCallback");
if (!animation_update_pending_) {
+ LOG(INFO) << "EarlyOut_NoAnimationUpdatePending";
TRACE_EVENT0("renderer", "EarlyOut_NoAnimationUpdatePending");
return;
}
@@ -1135,6 +1170,7 @@ void RenderWidget::AnimateIfNeeded() {
}
return;
}
+ LOG(INFO) << "EarlyOut_AnimatedTooRecently";
TRACE_EVENT0("renderer", "EarlyOut_AnimatedTooRecently");
if (!animation_timer_.IsRunning()) {
// This code uses base::Time::Now() to calculate the floor and next fire
@@ -1180,15 +1216,18 @@ void RenderWidget::DoDeferredUpdate() {
return;
if (!init_complete_) {
+ LOG(INFO) << "EarlyOut_InitNotComplete";
TRACE_EVENT0("renderer", "EarlyOut_InitNotComplete");
return;
}
if (update_reply_pending_) {
+ LOG(INFO) << "EarlyOut_UpdateReplyPending";
TRACE_EVENT0("renderer", "EarlyOut_UpdateReplyPending");
return;
}
if (is_accelerated_compositing_active_ &&
num_swapbuffers_complete_pending_ >= kMaxSwapBuffersPending) {
+ LOG(INFO) << "EarlyOut_MaxSwapBuffersPending";
TRACE_EVENT0("renderer", "EarlyOut_MaxSwapBuffersPending");
return;
}
@@ -1197,6 +1236,7 @@ void RenderWidget::DoDeferredUpdate() {
if (is_hidden_ || size_.IsEmpty() || is_swapped_out_) {
paint_aggregator_.ClearPendingUpdate();
needs_repainting_on_restore_ = true;
+ LOG(INFO) << "EarlyOut_NotVisible";
TRACE_EVENT0("renderer", "EarlyOut_NotVisible");
return;
}
@@ -1225,6 +1265,7 @@ void RenderWidget::DoDeferredUpdate() {
// Suppress painting if nothing is dirty. This has to be done after updating
// animations running layout as these may generate further invalidations.
if (!paint_aggregator_.HasPendingUpdate()) {
+ LOG(INFO) << "EarlyOut_NoPendingUpdate";
TRACE_EVENT0("renderer", "EarlyOut_NoPendingUpdate");
InstrumentDidCancelFrame();
return;
@@ -1656,18 +1697,7 @@ void RenderWidget::didCompleteSwapBuffers() {
}
void RenderWidget::scheduleComposite() {
- if (RenderThreadImpl::current()->compositor_message_loop_proxy().get() &&
- compositor_) {
- compositor_->setNeedsRedraw();
- } else {
- // TODO(nduca): replace with something a little less hacky. The reason this
- // hack is still used is because the Invalidate-DoDeferredUpdate loop
- // contains a lot of host-renderer synchronization logic that is still
- // important for the accelerated compositing case. The option of simply
- // duplicating all that code is less desirable than "faking out" the
- // invalidation path using a magical damage rect.
- didInvalidateRect(WebRect(0, 0, 1, 1));
- }
+ ScheduleCompositeImpl(false);
}
void RenderWidget::scheduleAnimation() {

Powered by Google App Engine
This is Rietveld 408576698