summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/aura/compositor_resize_lock.cc65
-rw-r--r--content/browser/aura/compositor_resize_lock.h46
-rw-r--r--content/browser/aura/image_transport_factory.h2
-rw-r--r--content/browser/aura/resize_lock.cc35
-rw-r--r--content/browser/aura/resize_lock.h37
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc193
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h46
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura_unittest.cc117
-rw-r--r--content/content_browser.gypi4
9 files changed, 419 insertions, 126 deletions
diff --git a/content/browser/aura/compositor_resize_lock.cc b/content/browser/aura/compositor_resize_lock.cc
new file mode 100644
index 0000000..e80baba
--- /dev/null
+++ b/content/browser/aura/compositor_resize_lock.cc
@@ -0,0 +1,65 @@
+// Copyright 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/compositor_resize_lock.h"
+
+#include "base/debug/trace_event.h"
+#include "content/public/browser/browser_thread.h"
+#include "ui/aura/root_window.h"
+#include "ui/compositor/compositor.h"
+
+namespace content {
+
+CompositorResizeLock::CompositorResizeLock(aura::RootWindow* root_window,
+ const gfx::Size new_size,
+ bool defer_compositor_lock,
+ const base::TimeDelta& timeout)
+ : ResizeLock(new_size, defer_compositor_lock),
+ root_window_(root_window),
+ weak_ptr_factory_(this),
+ cancelled_(false) {
+ DCHECK(root_window_);
+
+ TRACE_EVENT_ASYNC_BEGIN2("ui", "CompositorResizeLock", this,
+ "width", expected_size().width(),
+ "height", expected_size().height());
+ root_window_->HoldPointerMoves();
+
+ BrowserThread::PostDelayedTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&CompositorResizeLock::CancelLock,
+ weak_ptr_factory_.GetWeakPtr()),
+ timeout);
+}
+
+CompositorResizeLock::~CompositorResizeLock() {
+ CancelLock();
+ TRACE_EVENT_ASYNC_END2("ui", "CompositorResizeLock", this,
+ "width", expected_size().width(),
+ "height", expected_size().height());
+}
+
+bool CompositorResizeLock::GrabDeferredLock() {
+ return ResizeLock::GrabDeferredLock();
+}
+
+void CompositorResizeLock::UnlockCompositor() {
+ ResizeLock::UnlockCompositor();
+ compositor_lock_ = NULL;
+}
+
+void CompositorResizeLock::LockCompositor() {
+ ResizeLock::LockCompositor();
+ compositor_lock_ = root_window_->compositor()->GetCompositorLock();
+}
+
+void CompositorResizeLock::CancelLock() {
+ if (cancelled_)
+ return;
+ cancelled_ = true;
+ UnlockCompositor();
+ root_window_->ReleasePointerMoves();
+}
+
+} // namespace content
diff --git a/content/browser/aura/compositor_resize_lock.h b/content/browser/aura/compositor_resize_lock.h
new file mode 100644
index 0000000..51787e4
--- /dev/null
+++ b/content/browser/aura/compositor_resize_lock.h
@@ -0,0 +1,46 @@
+// Copyright 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.
+
+#ifndef CONTENT_BROWSER_AURA_RESIZE_LOCK_AURA_H_
+#define CONTENT_BROWSER_AURA_RESIZE_LOCK_AURA_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "content/browser/aura/resize_lock.h"
+
+namespace aura { class RootWindow; }
+
+namespace ui { class CompositorLock; }
+
+namespace content {
+
+// Used to prevent further resizes while a resize is pending.
+class CompositorResizeLock : public ResizeLock {
+ public:
+ CompositorResizeLock(aura::RootWindow* root_window,
+ const gfx::Size new_size,
+ bool defer_compositor_lock,
+ const base::TimeDelta& timeout);
+ virtual ~CompositorResizeLock();
+
+ virtual bool GrabDeferredLock() OVERRIDE;
+ virtual void UnlockCompositor() OVERRIDE;
+
+ protected:
+ virtual void LockCompositor() OVERRIDE;
+ void CancelLock();
+
+ private:
+ aura::RootWindow* root_window_;
+ scoped_refptr<ui::CompositorLock> compositor_lock_;
+ base::WeakPtrFactory<CompositorResizeLock> weak_ptr_factory_;
+ bool cancelled_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompositorResizeLock);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_AURA_RESIZE_LOCK_AURA_H_
diff --git a/content/browser/aura/image_transport_factory.h b/content/browser/aura/image_transport_factory.h
index e5964809..7cd2523 100644
--- a/content/browser/aura/image_transport_factory.h
+++ b/content/browser/aura/image_transport_factory.h
@@ -28,7 +28,7 @@ namespace content {
class GLHelper;
// This class provides a way to get notified when surface handles get lost.
-class ImageTransportFactoryObserver {
+class CONTENT_EXPORT ImageTransportFactoryObserver {
public:
virtual ~ImageTransportFactoryObserver() {}
diff --git a/content/browser/aura/resize_lock.cc b/content/browser/aura/resize_lock.cc
new file mode 100644
index 0000000..4c8cd95
--- /dev/null
+++ b/content/browser/aura/resize_lock.cc
@@ -0,0 +1,35 @@
+// Copyright 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/resize_lock.h"
+
+namespace content {
+
+ResizeLock::ResizeLock(const gfx::Size new_size, bool defer_compositor_lock)
+ : new_size_(new_size),
+ defer_compositor_lock_(defer_compositor_lock) {
+ if (!defer_compositor_lock_)
+ LockCompositor();
+}
+
+ResizeLock::~ResizeLock() {
+ UnlockCompositor();
+}
+
+bool ResizeLock::GrabDeferredLock() {
+ if (!defer_compositor_lock_)
+ return false;
+ LockCompositor();
+ return true;
+}
+
+void ResizeLock::UnlockCompositor() {
+ defer_compositor_lock_ = false;
+}
+
+void ResizeLock::LockCompositor() {
+ defer_compositor_lock_ = false;
+}
+
+} // namespace content
diff --git a/content/browser/aura/resize_lock.h b/content/browser/aura/resize_lock.h
new file mode 100644
index 0000000..cff9822
--- /dev/null
+++ b/content/browser/aura/resize_lock.h
@@ -0,0 +1,37 @@
+// Copyright 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.
+
+#ifndef CONTENT_BROWSER_AURA_RESIZE_LOCK_H_
+#define CONTENT_BROWSER_AURA_RESIZE_LOCK_H_
+
+#include "base/basictypes.h"
+#include "content/common/content_export.h"
+#include "ui/gfx/size.h"
+
+namespace content {
+
+class CONTENT_EXPORT ResizeLock {
+ public:
+ virtual ~ResizeLock();
+
+ virtual bool GrabDeferredLock();
+ virtual void UnlockCompositor();
+
+ const gfx::Size& expected_size() const { return new_size_; }
+
+ protected:
+ ResizeLock(const gfx::Size new_size, bool defer_compositor_lock);
+
+ virtual void LockCompositor();
+
+ private:
+ gfx::Size new_size_;
+ bool defer_compositor_lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResizeLock);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_AURA_RESIZE_LOCK_H_
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index d998867..7abad81 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -19,6 +19,7 @@
#include "cc/resources/texture_mailbox.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
+#include "content/browser/aura/compositor_resize_lock.h"
#include "content/browser/renderer_host/backing_store_aura.h"
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/overscroll_controller.h"
@@ -573,73 +574,6 @@ class RenderWidgetHostViewAura::TransientWindowObserver
#endif
-class RenderWidgetHostViewAura::ResizeLock {
- public:
- ResizeLock(aura::RootWindow* root_window,
- const gfx::Size new_size,
- bool defer_compositor_lock)
- : root_window_(root_window),
- new_size_(new_size),
- compositor_lock_(defer_compositor_lock ?
- NULL :
- root_window_->compositor()->GetCompositorLock()),
- weak_ptr_factory_(this),
- defer_compositor_lock_(defer_compositor_lock) {
- TRACE_EVENT_ASYNC_BEGIN2("ui", "ResizeLock", this,
- "width", new_size_.width(),
- "height", new_size_.height());
- root_window_->HoldPointerMoves();
-
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&RenderWidgetHostViewAura::ResizeLock::CancelLock,
- weak_ptr_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs));
- }
-
- ~ResizeLock() {
- CancelLock();
- TRACE_EVENT_ASYNC_END2("ui", "ResizeLock", this,
- "width", new_size_.width(),
- "height", new_size_.height());
- }
-
- void UnlockCompositor() {
- defer_compositor_lock_ = false;
- compositor_lock_ = NULL;
- }
-
- void CancelLock() {
- if (!root_window_)
- return;
- UnlockCompositor();
- root_window_->ReleasePointerMoves();
- root_window_ = NULL;
- }
-
- const gfx::Size& expected_size() const {
- return new_size_;
- }
-
- bool GrabDeferredLock() {
- if (root_window_ && defer_compositor_lock_) {
- compositor_lock_ = root_window_->compositor()->GetCompositorLock();
- defer_compositor_lock_ = false;
- return true;
- }
- return false;
- }
-
- private:
- aura::RootWindow* root_window_;
- gfx::Size new_size_;
- scoped_refptr<ui::CompositorLock> compositor_lock_;
- base::WeakPtrFactory<ResizeLock> weak_ptr_factory_;
- bool defer_compositor_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(ResizeLock);
-};
-
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, public:
@@ -656,6 +590,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
can_compose_inline_(true),
has_composition_text_(false),
last_output_surface_id_(0),
+ skipped_frames_(false),
last_swapped_surface_scale_factor_(1.f),
paint_canvas_(NULL),
synthetic_move_sent_(false),
@@ -811,39 +746,69 @@ void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
}
void RenderWidgetHostViewAura::MaybeCreateResizeLock() {
- gfx::Size desired_size = window_->bounds().size();
- if (!host_->should_auto_resize() &&
- !resize_lock_.get() &&
- desired_size != current_frame_size_ &&
- host_->is_accelerated_compositing_active()) {
- aura::RootWindow* root_window = window_->GetRootWindow();
- ui::Compositor* compositor = root_window ?
- root_window->compositor() : NULL;
- if (root_window && compositor) {
- // Listen to changes in the compositor lock state.
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
-
-// On Windows while resizing, the the resize locks makes us mis-paint a white
-// vertical strip (including the non-client area) if the content composition is
-// lagging the UI composition. So here we disable the throttling so that the UI
-// bits can draw ahead of the content thereby reducing the amount of whiteout.
-// Because this causes the content to be drawn at wrong sizes while resizing
-// we compensate by blocking the UI thread in Compositor::Draw() by issuing a
-// FinishAllRendering() if we are resizing.
-#if !defined (OS_WIN)
- bool defer_compositor_lock =
- can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
- can_lock_compositor_ == NO_PENDING_COMMIT;
-
- if (can_lock_compositor_ == YES)
- can_lock_compositor_ = YES_DID_LOCK;
-
- resize_lock_.reset(new ResizeLock(root_window, desired_size,
- defer_compositor_lock));
+ if (!ShouldCreateResizeLock())
+ return;
+ DCHECK(window_->GetRootWindow());
+ DCHECK(window_->GetRootWindow()->compositor());
+
+ // Listen to changes in the compositor lock state.
+ ui::Compositor* compositor = window_->GetRootWindow()->compositor();
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
+
+ bool defer_compositor_lock =
+ can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
+ can_lock_compositor_ == NO_PENDING_COMMIT;
+
+ if (can_lock_compositor_ == YES)
+ can_lock_compositor_ = YES_DID_LOCK;
+
+ resize_lock_ = CreateResizeLock(defer_compositor_lock);
+}
+
+bool RenderWidgetHostViewAura::ShouldCreateResizeLock() {
+ // On Windows while resizing, the the resize locks makes us mis-paint a white
+ // vertical strip (including the non-client area) if the content composition
+ // is lagging the UI composition. So here we disable the throttling so that
+ // the UI bits can draw ahead of the content thereby reducing the amount of
+ // whiteout. Because this causes the content to be drawn at wrong sizes while
+ // resizing we compensate by blocking the UI thread in Compositor::Draw() by
+ // issuing a FinishAllRendering() if we are resizing.
+#if defined (OS_WIN)
+ return false;
#endif
- }
- }
+
+ if (resize_lock_)
+ return false;
+
+ if (host_->should_auto_resize())
+ return false;
+ if (!host_->is_accelerated_compositing_active())
+ return false;
+
+ gfx::Size desired_size = window_->bounds().size();
+ if (desired_size == current_frame_size_)
+ return false;
+
+ aura::RootWindow* root_window = window_->GetRootWindow();
+ if (!root_window)
+ return false;
+
+ ui::Compositor* compositor = root_window->compositor();
+ if (!compositor)
+ return false;
+
+ return true;
+}
+
+scoped_ptr<ResizeLock> RenderWidgetHostViewAura::CreateResizeLock(
+ bool defer_compositor_lock) {
+ gfx::Size desired_size = window_->bounds().size();
+ return scoped_ptr<ResizeLock>(new CompositorResizeLock(
+ window_->GetRootWindow(),
+ desired_size,
+ defer_compositor_lock,
+ base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)));
}
gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
@@ -1440,17 +1405,25 @@ void RenderWidgetHostViewAura::SwapDelegatedFrame(
scoped_ptr<cc::DelegatedFrameData> frame_data,
float frame_device_scale_factor,
const ui::LatencyInfo& latency_info) {
+ gfx::Size frame_size;
gfx::Size frame_size_in_dip;
+ gfx::Rect damage_rect;
gfx::Rect damage_rect_in_dip;
+
if (!frame_data->render_pass_list.empty()) {
cc::RenderPass* root_pass = frame_data->render_pass_list.back();
- frame_size_in_dip = ConvertSizeToDIP(frame_device_scale_factor,
- root_pass->output_rect.size());
- damage_rect_in_dip = ConvertRectToDIP(
- frame_device_scale_factor,
- gfx::ToEnclosingRect(root_pass->damage_rect));
+
+ frame_size = root_pass->output_rect.size();
+ frame_size_in_dip = ConvertSizeToDIP(frame_device_scale_factor, frame_size);
+
+ damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect);
+ damage_rect.Intersect(gfx::Rect(frame_size));
+ damage_rect_in_dip = ConvertRectToDIP(frame_device_scale_factor,
+ damage_rect);
}
+
framebuffer_holder_ = NULL;
+
if (ShouldSkipFrame(frame_size_in_dip)) {
cc::CompositorFrameAck ack;
cc::TransferableResource::ReturnResources(frame_data->resource_list,
@@ -1458,8 +1431,20 @@ void RenderWidgetHostViewAura::SwapDelegatedFrame(
RenderWidgetHostImpl::SendSwapCompositorFrameAck(
host_->GetRoutingID(), output_surface_id,
host_->GetProcess()->GetID(), ack);
+ skipped_frames_ = true;
return;
}
+
+ if (skipped_frames_) {
+ skipped_frames_ = false;
+ damage_rect = gfx::Rect(frame_size);
+ damage_rect_in_dip = gfx::Rect(frame_size_in_dip);
+
+ // Give the same damage rect to the compositor.
+ cc::RenderPass* root_pass = frame_data->render_pass_list.back();
+ root_pass->damage_rect = damage_rect;
+ }
+
if (output_surface_id != last_output_surface_id_) {
// Resource ids are scoped by the output surface.
// If the originating output surface doesn't match the last one, it
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 7f03b09..5b3853f 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -59,9 +59,10 @@ namespace content {
class MemoryHolder;
class RenderWidgetHostImpl;
class RenderWidgetHostView;
+class ResizeLock;
// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
-class RenderWidgetHostViewAura
+class CONTENT_EXPORT RenderWidgetHostViewAura
: public RenderWidgetHostViewBase,
public ui::CompositorObserver,
public ui::TextInputClient,
@@ -337,26 +338,21 @@ class RenderWidgetHostViewAura
protected:
friend class RenderWidgetHostView;
+ virtual ~RenderWidgetHostViewAura();
- // Should construct only via RenderWidgetHostView::CreateViewForWidget.
+ // Should be constructed via RenderWidgetHostView::CreateViewForWidget.
explicit RenderWidgetHostViewAura(RenderWidgetHost* host);
RenderWidgetHostViewFrameSubscriber* frame_subscriber() const {
return frame_subscriber_.get();
}
- private:
- FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SetCompositionText);
- FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventState);
- FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventSyncAsync);
- FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SwapNotifiesWindow);
+ virtual bool ShouldCreateResizeLock();
+ virtual scoped_ptr<ResizeLock> CreateResizeLock(bool defer_compositor_lock);
- class WindowObserver;
- friend class WindowObserver;
-#if defined(OS_WIN)
- class TransientWindowObserver;
- friend class TransientWindowObserver;
-#endif
+ // Exposed for tests.
+ aura::Window* window() { return window_; }
+ gfx::Size current_frame_size() const { return current_frame_size_; }
// Overridden from ui::CompositorObserver:
virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE;
@@ -370,6 +366,21 @@ class RenderWidgetHostViewAura
base::TimeTicks timebase,
base::TimeDelta interval) OVERRIDE;
+ private:
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SetCompositionText);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventState);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventSyncAsync);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SwapNotifiesWindow);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
+ SkippedDelegatedFrames);
+
+ class WindowObserver;
+ friend class WindowObserver;
+#if defined(OS_WIN)
+ class TransientWindowObserver;
+ friend class TransientWindowObserver;
+#endif
+
// Overridden from ImageTransportFactoryObserver:
virtual void OnLostResources() OVERRIDE;
@@ -385,8 +396,6 @@ class RenderWidgetHostViewAura
virtual gfx::Point GetLastTouchEventLocation() const OVERRIDE;
virtual void FatalAccessibilityTreeError() OVERRIDE;
- virtual ~RenderWidgetHostViewAura();
-
void UpdateCursorIfOverSelf();
bool ShouldSkipFrame(gfx::Size size_in_dip) const;
@@ -599,6 +608,10 @@ class RenderWidgetHostViewAura
// Pending damage from previous frames that we skipped.
SkRegion skipped_damage_;
+ // True after a delegated frame has been skipped, until a frame is not
+ // skipped.
+ bool skipped_frames_;
+
// The size of the last frame that was swapped (even if we skipped it).
// Used to determine when the skipped_damage_ needs to be reset due to
// size changes between front- and backbuffer.
@@ -630,9 +643,6 @@ class RenderWidgetHostViewAura
// software backing store is updated.
bool accelerated_compositing_state_changed_;
- // Used to prevent further resizes while a resize is pending.
- class ResizeLock;
-
// This lock is the one waiting for a frame of the right size to come back
// from the renderer/GPU process. It is set from the moment the aura window
// got resized, to the moment we committed the renderer frame of the same
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index 5d999f9..8fb69c7 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -11,6 +11,7 @@
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_metadata.h"
#include "cc/output/gl_frame_data.h"
+#include "content/browser/aura/resize_lock.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -37,6 +38,8 @@
#include "ui/base/events/event_utils.h"
#include "ui/base/ui_base_types.h"
+using testing::_;
+
namespace content {
namespace {
class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
@@ -76,6 +79,41 @@ class TestWindowObserver : public aura::WindowObserver {
DISALLOW_COPY_AND_ASSIGN(TestWindowObserver);
};
+class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
+ public:
+ FakeRenderWidgetHostViewAura(RenderWidgetHost* widget)
+ : RenderWidgetHostViewAura(widget), has_resize_lock_(false) {}
+
+ virtual ~FakeRenderWidgetHostViewAura() {}
+
+ virtual bool ShouldCreateResizeLock() OVERRIDE {
+ gfx::Size desired_size = window()->bounds().size();
+ return desired_size != current_frame_size();
+ }
+
+ virtual scoped_ptr<ResizeLock> CreateResizeLock(bool defer_compositor_lock)
+ OVERRIDE {
+ gfx::Size desired_size = window()->bounds().size();
+ return scoped_ptr<ResizeLock>(
+ new FakeResizeLock(desired_size, defer_compositor_lock));
+ }
+
+ void RunOnCompositingDidCommit() {
+ OnCompositingDidCommit(window()->GetRootWindow()->compositor());
+ }
+
+ // A lock that doesn't actually do anything to the compositor, and does not
+ // time out.
+ class FakeResizeLock : public ResizeLock {
+ public:
+ FakeResizeLock(const gfx::Size new_size, bool defer_compositor_lock)
+ : ResizeLock(new_size, defer_compositor_lock) {}
+ };
+
+ bool has_resize_lock_;
+ gfx::Size last_frame_size_;
+};
+
class RenderWidgetHostViewAuraTest : public testing::Test {
public:
RenderWidgetHostViewAuraTest()
@@ -103,8 +141,9 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
widget_host_ = new RenderWidgetHostImpl(
&delegate_, process_host, MSG_ROUTING_NONE, false);
widget_host_->Init();
- view_ = static_cast<RenderWidgetHostViewAura*>(
- RenderWidgetHostView::CreateViewForWidget(widget_host_));
+ widget_host_->OnMessageReceived(
+ ViewHostMsg_DidActivateAcceleratedCompositing(0, true));
+ view_ = new FakeRenderWidgetHostViewAura(widget_host_);
}
virtual void TearDown() {
@@ -139,7 +178,7 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
// Tests should set these to NULL if they've already triggered their
// destruction.
RenderWidgetHostImpl* widget_host_;
- RenderWidgetHostViewAura* view_;
+ FakeRenderWidgetHostViewAura* view_;
IPC::TestSink* sink_;
@@ -733,4 +772,76 @@ TEST_F(RenderWidgetHostViewAuraTest, SwapNotifiesWindow) {
view_->window_->RemoveObserver(&observer);
}
+// Skipped frames should not drop their damage.
+TEST_F(RenderWidgetHostViewAuraTest, SkippedDelegatedFrames) {
+ gfx::Rect view_rect(100, 100);
+ gfx::Size frame_size = view_rect.size();
+
+ view_->InitAsChild(NULL);
+ view_->GetNativeView()->SetDefaultParentByRootWindow(
+ parent_view_->GetNativeView()->GetRootWindow(), gfx::Rect());
+ view_->SetSize(view_rect.size());
+
+ MockWindowObserver observer;
+ view_->window_->AddObserver(&observer);
+
+ // A full frame of damage.
+ EXPECT_CALL(observer, OnWindowPaintScheduled(view_->window_, view_rect));
+ view_->OnSwapCompositorFrame(
+ 0, MakeDelegatedFrame(1.f, frame_size, view_rect));
+ testing::Mock::VerifyAndClearExpectations(&observer);
+ view_->RunOnCompositingDidCommit();
+
+ // A partial damage frame.
+ gfx::Rect partial_view_rect(30, 30, 20, 20);
+ EXPECT_CALL(observer,
+ OnWindowPaintScheduled(view_->window_, partial_view_rect));
+ view_->OnSwapCompositorFrame(
+ 0, MakeDelegatedFrame(1.f, frame_size, partial_view_rect));
+ testing::Mock::VerifyAndClearExpectations(&observer);
+ view_->RunOnCompositingDidCommit();
+
+ // Lock the compositor. Now we should drop frames.
+ view_rect = gfx::Rect(150, 150);
+ view_->SetSize(view_rect.size());
+ view_->MaybeCreateResizeLock();
+
+ // This frame is dropped.
+ gfx::Rect dropped_damage_rect_1(10, 20, 30, 40);
+ EXPECT_CALL(observer, OnWindowPaintScheduled(_, _)).Times(0);
+ view_->OnSwapCompositorFrame(
+ 0, MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_1));
+ testing::Mock::VerifyAndClearExpectations(&observer);
+ view_->RunOnCompositingDidCommit();
+
+ gfx::Rect dropped_damage_rect_2(40, 50, 10, 20);
+ EXPECT_CALL(observer, OnWindowPaintScheduled(_, _)).Times(0);
+ view_->OnSwapCompositorFrame(
+ 0, MakeDelegatedFrame(1.f, frame_size, dropped_damage_rect_2));
+ testing::Mock::VerifyAndClearExpectations(&observer);
+ view_->RunOnCompositingDidCommit();
+
+ // Unlock the compositor. This frame should damage everything.
+ frame_size = view_rect.size();
+
+ gfx::Rect new_damage_rect(5, 6, 10, 10);
+ EXPECT_CALL(observer,
+ OnWindowPaintScheduled(view_->window_, view_rect));
+ view_->OnSwapCompositorFrame(
+ 0, MakeDelegatedFrame(1.f, frame_size, new_damage_rect));
+ testing::Mock::VerifyAndClearExpectations(&observer);
+ view_->RunOnCompositingDidCommit();
+
+ // A partial damage frame, this should not be dropped.
+ EXPECT_CALL(observer,
+ OnWindowPaintScheduled(view_->window_, partial_view_rect));
+ view_->OnSwapCompositorFrame(
+ 0, MakeDelegatedFrame(1.f, frame_size, partial_view_rect));
+ testing::Mock::VerifyAndClearExpectations(&observer);
+ view_->RunOnCompositingDidCommit();
+
+
+ view_->window_->RemoveObserver(&observer);
+}
+
} // namespace content
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index f97f544..49bd34d 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -291,6 +291,8 @@
'browser/aura/browser_compositor_output_surface.h',
'browser/aura/browser_compositor_output_surface_proxy.cc',
'browser/aura/browser_compositor_output_surface_proxy.h',
+ 'browser/aura/compositor_resize_lock.cc',
+ 'browser/aura/compositor_resize_lock.h',
'browser/aura/gpu_process_transport_factory.cc',
'browser/aura/gpu_process_transport_factory.h',
'browser/aura/image_transport_factory.cc',
@@ -299,6 +301,8 @@
'browser/aura/no_transport_image_transport_factory.h',
'browser/aura/reflector_impl.cc',
'browser/aura/reflector_impl.h',
+ 'browser/aura/resize_lock.cc',
+ 'browser/aura/resize_lock.h',
'browser/aura/software_browser_compositor_output_surface.cc',
'browser/aura/software_browser_compositor_output_surface.h',
'browser/aura/software_output_device_win.cc',