summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/wm/window_animations.cc5
-rw-r--r--cc/layer_tree_host.cc9
-rw-r--r--cc/layer_tree_host.h5
-rw-r--r--cc/layer_tree_host_unittest.cc53
-rw-r--r--cc/proxy.h4
-rw-r--r--cc/single_thread_proxy.cc6
-rw-r--r--cc/single_thread_proxy.h1
-rw-r--r--cc/test/layer_tree_test_common.cc5
-rw-r--r--cc/test/layer_tree_test_common.h1
-rw-r--r--cc/thread_proxy.cc28
-rw-r--r--cc/thread_proxy.h4
-rw-r--r--content/browser/gpu/gpu_process_host.cc15
-rw-r--r--content/browser/gpu/gpu_process_host_ui_shim.cc4
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc1
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc4
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.h1
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc2
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc230
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h32
-rw-r--r--content/browser/renderer_host/render_widget_host_view_gtk.cc4
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm1
-rw-r--r--content/common/gpu/gpu_messages.h3
-rw-r--r--content/common/gpu/image_transport_surface.cc9
-rw-r--r--content/common/gpu/image_transport_surface.h7
-rw-r--r--content/common/gpu/image_transport_surface_mac.cc6
-rw-r--r--content/common/gpu/image_transport_surface_win.cc5
-rw-r--r--content/common/gpu/texture_image_transport_surface.cc27
-rw-r--r--content/common/gpu/texture_image_transport_surface.h7
-rw-r--r--ui/aura/bench/bench_main.cc5
-rw-r--r--ui/aura/root_window.cc62
-rw-r--r--ui/aura/root_window.h37
-rw-r--r--ui/compositor/compositor.cc85
-rw-r--r--ui/compositor/compositor.h43
-rw-r--r--ui/compositor/compositor_observer.h9
-rw-r--r--ui/compositor/layer_unittest.cc13
-rw-r--r--webkit/compositor_bindings/web_layer_tree_view_impl.cc5
-rw-r--r--webkit/compositor_bindings/web_layer_tree_view_impl.h1
37 files changed, 466 insertions, 273 deletions
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc
index 282567c..48ee701 100644
--- a/ash/wm/window_animations.cc
+++ b/ash/wm/window_animations.cc
@@ -573,8 +573,6 @@ class CrossFadeObserver : public ui::CompositorObserver,
// ui::CompositorObserver overrides:
virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {
}
- virtual void OnCompositingWillStart(ui::Compositor* compositor) OVERRIDE {
- }
virtual void OnCompositingStarted(ui::Compositor* compositor) OVERRIDE {
}
virtual void OnCompositingEnded(ui::Compositor* compositor) OVERRIDE {
@@ -583,6 +581,9 @@ class CrossFadeObserver : public ui::CompositorObserver,
// Triggers OnImplicitAnimationsCompleted() to be called and deletes us.
layer_->GetAnimator()->StopAnimating();
}
+ virtual void OnCompositingLockStateChanged(
+ ui::Compositor* compositor) OVERRIDE {
+ }
// aura::WindowObserver overrides:
virtual void OnWindowDestroying(Window* window) OVERRIDE {
diff --git a/cc/layer_tree_host.cc b/cc/layer_tree_host.cc
index aead25f..7c70ef9 100644
--- a/cc/layer_tree_host.cc
+++ b/cc/layer_tree_host.cc
@@ -345,6 +345,15 @@ void LayerTreeHost::finishAllRendering()
m_proxy->finishAllRendering();
}
+void LayerTreeHost::setDeferCommits(bool deferCommits)
+{
+ m_proxy->setDeferCommits(deferCommits);
+}
+
+void LayerTreeHost::didDeferCommit()
+{
+}
+
void LayerTreeHost::renderingStats(RenderingStats* stats) const
{
*stats = m_renderingStats;
diff --git a/cc/layer_tree_host.h b/cc/layer_tree_host.h
index f64862e..12e7750 100644
--- a/cc/layer_tree_host.h
+++ b/cc/layer_tree_host.h
@@ -143,6 +143,11 @@ public:
void finishAllRendering();
+ void setDeferCommits(bool deferCommits);
+
+ // Test only hook
+ virtual void didDeferCommit();
+
int commitNumber() const { return m_commitNumber; }
void renderingStats(RenderingStats*) const;
diff --git a/cc/layer_tree_host_unittest.cc b/cc/layer_tree_host_unittest.cc
index 72b094a..f85111e 100644
--- a/cc/layer_tree_host_unittest.cc
+++ b/cc/layer_tree_host_unittest.cc
@@ -3183,4 +3183,57 @@ TEST_F(LayerTreeHostTestContinuousAnimate, runMultiThread)
runTest(true);
}
+class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
+public:
+ LayerTreeHostTestDeferCommits()
+ : m_numCommitsDeferred(0)
+ , m_numCompleteCommits(0)
+ {
+ }
+
+ virtual void beginTest() OVERRIDE
+ {
+ postSetNeedsCommitToMainThread();
+ }
+
+ virtual void didDeferCommit() OVERRIDE
+ {
+ m_numCommitsDeferred++;
+ m_layerTreeHost->setDeferCommits(false);
+ }
+
+ virtual void didCommit() OVERRIDE
+ {
+ m_numCompleteCommits++;
+ switch (m_numCompleteCommits) {
+ case 1:
+ EXPECT_EQ(0, m_numCommitsDeferred);
+ m_layerTreeHost->setDeferCommits(true);
+ postSetNeedsCommitToMainThread();
+ break;
+ case 2:
+ endTest();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ virtual void afterTest() OVERRIDE
+ {
+ EXPECT_EQ(1, m_numCommitsDeferred);
+ EXPECT_EQ(2, m_numCompleteCommits);
+ }
+
+private:
+ int m_numCommitsDeferred;
+ int m_numCompleteCommits;
+};
+
+TEST_F(LayerTreeHostTestDeferCommits, runMultiThread)
+{
+ runTest(true);
+}
+
} // namespace
diff --git a/cc/proxy.h b/cc/proxy.h
index daddade..f3edbaa 100644
--- a/cc/proxy.h
+++ b/cc/proxy.h
@@ -65,6 +65,10 @@ public:
virtual void setNeedsCommit() = 0;
virtual void setNeedsRedraw() = 0;
+ // Defers commits until it is reset. It is only supported when in threaded mode. It's an error to make a sync call
+ // like compositeAndReadback while commits are deferred.
+ virtual void setDeferCommits(bool) = 0;
+
virtual void didAddAnimation() = 0;
virtual bool commitRequested() const = 0;
diff --git a/cc/single_thread_proxy.cc b/cc/single_thread_proxy.cc
index 5cbe3d2..9433e1a 100644
--- a/cc/single_thread_proxy.cc
+++ b/cc/single_thread_proxy.cc
@@ -231,6 +231,12 @@ void SingleThreadProxy::setNeedsRedraw()
setNeedsCommit();
}
+void SingleThreadProxy::setDeferCommits(bool deferCommits)
+{
+ // Thread-only feature.
+ NOTREACHED();
+}
+
bool SingleThreadProxy::commitRequested() const
{
return false;
diff --git a/cc/single_thread_proxy.h b/cc/single_thread_proxy.h
index 2a27e32..ca6769f 100644
--- a/cc/single_thread_proxy.h
+++ b/cc/single_thread_proxy.h
@@ -37,6 +37,7 @@ public:
virtual void setNeedsAnimate() OVERRIDE;
virtual void setNeedsCommit() OVERRIDE;
virtual void setNeedsRedraw() OVERRIDE;
+ virtual void setDeferCommits(bool) OVERRIDE;
virtual bool commitRequested() const OVERRIDE;
virtual void didAddAnimation() OVERRIDE;
virtual void start() OVERRIDE;
diff --git a/cc/test/layer_tree_test_common.cc b/cc/test/layer_tree_test_common.cc
index 686cd27..846e807 100644
--- a/cc/test/layer_tree_test_common.cc
+++ b/cc/test/layer_tree_test_common.cc
@@ -181,6 +181,11 @@ public:
void setTestStarted(bool started) { m_testStarted = started; }
+ virtual void didDeferCommit() OVERRIDE
+ {
+ m_testHooks->didDeferCommit();
+ }
+
private:
MockLayerTreeHost(TestHooks* testHooks, cc::LayerTreeHostClient* client, const cc::LayerTreeSettings& settings)
: LayerTreeHost(client, settings)
diff --git a/cc/test/layer_tree_test_common.h b/cc/test/layer_tree_test_common.h
index 91f9525..d1378c8 100644
--- a/cc/test/layer_tree_test_common.h
+++ b/cc/test/layer_tree_test_common.h
@@ -40,6 +40,7 @@ public:
virtual void didCommit() { }
virtual void didCommitAndDrawFrame() { }
virtual void scheduleComposite() { }
+ virtual void didDeferCommit() { }
// Implementation of WebAnimationDelegate
virtual void notifyAnimationStarted(double time) OVERRIDE { }
diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc
index 666c03f..e8229ca 100644
--- a/cc/thread_proxy.cc
+++ b/cc/thread_proxy.cc
@@ -53,6 +53,8 @@ ThreadProxy::ThreadProxy(LayerTreeHost* layerTreeHost)
, m_nextFrameIsNewlyCommittedFrameOnImplThread(false)
, m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled)
, m_totalCommitCount(0)
+ , m_deferCommits(false)
+ , m_deferredCommitPending(false)
{
TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
DCHECK(isMainThread());
@@ -70,6 +72,7 @@ bool ThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
TRACE_EVENT0("cc", "ThreadPRoxy::compositeAndReadback");
DCHECK(isMainThread());
DCHECK(m_layerTreeHost);
+ DCHECK(!m_deferCommits);
if (!m_layerTreeHost->initializeRendererIfNeeded()) {
TRACE_EVENT0("cc", "compositeAndReadback_EarlyOut_LR_Uninitialized");
@@ -131,6 +134,7 @@ void ThreadProxy::requestStartPageScaleAnimationOnImplThread(IntSize targetPosit
void ThreadProxy::finishAllRendering()
{
DCHECK(Proxy::isMainThread());
+ DCHECK(!m_deferCommits);
// Make sure all GL drawing is finished on the impl thread.
DebugScopedSetMainThreadBlocked mainThreadBlocked;
@@ -386,6 +390,23 @@ void ThreadProxy::setNeedsRedraw()
Proxy::implThread()->postTask(createThreadTask(this, &ThreadProxy::setNeedsRedrawOnImplThread));
}
+void ThreadProxy::setDeferCommits(bool deferCommits)
+{
+ DCHECK(isMainThread());
+ DCHECK_NE(m_deferCommits, deferCommits);
+ m_deferCommits = deferCommits;
+
+ if (m_deferCommits)
+ TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::setDeferCommits", this);
+ else
+ TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::setDeferCommits", this);
+
+ if (!m_deferCommits && m_deferredCommitPending) {
+ m_deferredCommitPending = false;
+ m_mainThreadProxy->postTask(createThreadTask(this, &ThreadProxy::beginFrame));
+ }
+}
+
bool ThreadProxy::commitRequested() const
{
DCHECK(isMainThread());
@@ -500,6 +521,13 @@ void ThreadProxy::beginFrame()
if (!m_layerTreeHost)
return;
+ if (m_deferCommits) {
+ m_deferredCommitPending = true;
+ m_layerTreeHost->didDeferCommit();
+ TRACE_EVENT0("cc", "EarlyOut_DeferCommits");
+ return;
+ }
+
if (!m_pendingBeginFrameRequest) {
TRACE_EVENT0("cc", "EarlyOut_StaleBeginFrameMessage");
return;
diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h
index 58e327c..695ac80 100644
--- a/cc/thread_proxy.h
+++ b/cc/thread_proxy.h
@@ -45,6 +45,7 @@ public:
virtual void setNeedsAnimate() OVERRIDE;
virtual void setNeedsCommit() OVERRIDE;
virtual void setNeedsRedraw() OVERRIDE;
+ virtual void setDeferCommits(bool) OVERRIDE;
virtual bool commitRequested() const OVERRIDE;
virtual void didAddAnimation() OVERRIDE { }
virtual void start() OVERRIDE;
@@ -174,6 +175,9 @@ private:
base::TimeDelta m_totalCommitTime;
size_t m_totalCommitCount;
+
+ bool m_deferCommits;
+ bool m_deferredCommitPending;
};
}
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 5f964c0..2e99d2e 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -108,7 +108,8 @@ void SendGpuProcessMessage(GpuProcessHost::GpuProcessKind kind,
void AcceleratedSurfaceBuffersSwappedCompletedForGPU(int host_id,
int route_id,
- bool alive) {
+ bool alive,
+ bool did_swap) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO,
@@ -116,14 +117,16 @@ void AcceleratedSurfaceBuffersSwappedCompletedForGPU(int host_id,
base::Bind(&AcceleratedSurfaceBuffersSwappedCompletedForGPU,
host_id,
route_id,
- alive));
+ alive,
+ did_swap));
return;
}
GpuProcessHost* host = GpuProcessHost::FromID(host_id);
if (host) {
if (alive)
- host->Send(new AcceleratedSurfaceMsg_BufferPresented(route_id, 0));
+ host->Send(new AcceleratedSurfaceMsg_BufferPresented(
+ route_id, did_swap, 0));
else
host->ForceShutdown();
}
@@ -168,7 +171,8 @@ void AcceleratedSurfaceBuffersSwappedCompleted(int host_id,
bool alive,
base::TimeTicks timebase,
base::TimeDelta interval) {
- AcceleratedSurfaceBuffersSwappedCompletedForGPU(host_id, route_id, alive);
+ AcceleratedSurfaceBuffersSwappedCompletedForGPU(host_id, route_id,
+ alive, true /* presented */);
AcceleratedSurfaceBuffersSwappedCompletedForRenderer(surface_id, timebase,
interval);
}
@@ -680,7 +684,8 @@ void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped(
base::ScopedClosureRunner scoped_completion_runner(
base::Bind(&AcceleratedSurfaceBuffersSwappedCompletedForGPU,
- host_id_, params.route_id, true));
+ host_id_, params.route_id,
+ true /* alive */, false /* presented */));
int render_process_id = 0;
int render_widget_id = 0;
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc
index 766157b..13a0cd1 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.cc
+++ b/content/browser/gpu/gpu_process_host_ui_shim.cc
@@ -307,7 +307,7 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
ScopedSendOnIOThread delayed_send(
host_id_,
- new AcceleratedSurfaceMsg_BufferPresented(params.route_id, 0));
+ new AcceleratedSurfaceMsg_BufferPresented(params.route_id, false, 0));
RenderWidgetHostViewPort* view = GetRenderWidgetHostViewFromSurfaceID(
params.surface_id);
@@ -331,7 +331,7 @@ void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer(
ScopedSendOnIOThread delayed_send(
host_id_,
- new AcceleratedSurfaceMsg_BufferPresented(params.route_id, 0));
+ new AcceleratedSurfaceMsg_BufferPresented(params.route_id, false, 0));
RenderWidgetHostViewPort* view =
GetRenderWidgetHostViewFromSurfaceID(params.surface_id);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index d43f338..6666079 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1595,6 +1595,7 @@ void RenderProcessHostImpl::OnCompositorSurfaceBuffersSwappedNoHost(
"RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost");
RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id,
gpu_process_host_id,
+ false,
0);
}
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index d6131a5..404ec650 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1391,6 +1391,7 @@ void RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped(
if (!view_) {
RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id,
gpu_process_host_id,
+ false,
0);
return;
}
@@ -2130,10 +2131,11 @@ bool RenderWidgetHostImpl::GotResponseToLockMouseRequest(bool allowed) {
// static
void RenderWidgetHostImpl::AcknowledgeBufferPresent(
- int32 route_id, int gpu_host_id, uint32 sync_point) {
+ int32 route_id, int gpu_host_id, bool presented, uint32 sync_point) {
GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id);
if (ui_shim)
ui_shim->Send(new AcceleratedSurfaceMsg_BufferPresented(route_id,
+ presented,
sync_point));
}
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index b2e8591..db354a4 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -393,6 +393,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
static void AcknowledgeBufferPresent(
int32 route_id,
int gpu_host_id,
+ bool presented,
uint32 sync_point);
// Called by the view in response to AcceleratedSurfaceBuffersSwapped for
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 825c241..a4e90b6 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -379,7 +379,7 @@ void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
uint32 sync_point =
ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- params.route_id, gpu_host_id, sync_point);
+ params.route_id, gpu_host_id, true, sync_point);
}
void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
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 f8565ee..6987fcc 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -198,11 +198,16 @@ class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
class RenderWidgetHostViewAura::ResizeLock {
public:
- ResizeLock(aura::RootWindow* root_window, const gfx::Size new_size)
+ ResizeLock(aura::RootWindow* root_window,
+ const gfx::Size new_size,
+ bool defer_compositor_lock)
: root_window_(root_window),
new_size_(new_size),
- compositor_lock_(root_window_->GetCompositorLock()),
- weak_ptr_factory_(this) {
+ compositor_lock_(defer_compositor_lock ?
+ NULL :
+ root_window_->compositor()->GetCompositorLock()),
+ weak_ptr_factory_(this),
+ defer_compositor_lock_(defer_compositor_lock) {
root_window_->HoldMouseMoves();
BrowserThread::PostDelayedTask(
@@ -217,6 +222,7 @@ class RenderWidgetHostViewAura::ResizeLock {
}
void UnlockCompositor() {
+ defer_compositor_lock_ = false;
compositor_lock_ = NULL;
}
@@ -232,11 +238,21 @@ class RenderWidgetHostViewAura::ResizeLock {
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<aura::CompositorLock> compositor_lock_;
+ scoped_refptr<ui::CompositorLock> compositor_lock_;
base::WeakPtrFactory<ResizeLock> weak_ptr_factory_;
+ bool defer_compositor_lock_;
DISALLOW_COPY_AND_ASSIGN(ResizeLock);
};
@@ -263,7 +279,8 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
surface_route_id_(0),
paint_canvas_(NULL),
synthetic_move_sent_(false),
- accelerated_compositing_state_changed_(false) {
+ accelerated_compositing_state_changed_(false),
+ can_lock_compositor_(YES) {
host_->SetView(this);
window_observer_.reset(new WindowObserver(this));
window_->AddObserver(window_observer_.get());
@@ -343,7 +360,7 @@ void RenderWidgetHostViewAura::WasShown() {
if (!current_surface_ && host_->is_accelerated_compositing_active() &&
!released_front_lock_.get()) {
- released_front_lock_ = window_->GetRootWindow()->GetCompositorLock();
+ released_front_lock_ = GetCompositor()->GetCompositorLock();
}
AdjustSurfaceProtection();
@@ -388,9 +405,22 @@ void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
if (window_->bounds().size() != rect.size() &&
host_->is_accelerated_compositing_active()) {
aura::RootWindow* root_window = window_->GetRootWindow();
- if (root_window) {
+ 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);
+
+ 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_locks_.push_back(make_linked_ptr(
- new ResizeLock(root_window, rect.size())));
+ new ResizeLock(root_window, rect.size(), defer_compositor_lock)));
}
}
window_->SetBounds(rect);
@@ -695,6 +725,28 @@ void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
accelerated_compositing_state_changed_ = true;
}
+bool RenderWidgetHostViewAura::ShouldFastACK(uint64 surface_id) {
+ ui::Texture* container = image_transport_clients_[surface_id];
+ DCHECK(container);
+
+ if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
+ can_lock_compositor_ == NO_PENDING_COMMIT ||
+ resize_locks_.empty())
+ return false;
+
+ gfx::Size container_size = ConvertSizeToDIP(this, container->size());
+ ResizeLockList::iterator it = resize_locks_.begin();
+ while (it != resize_locks_.end()) {
+ if ((*it)->expected_size() == container_size)
+ break;
+ ++it;
+ }
+
+ // We could be getting an unexpected frame due to an animation
+ // (i.e. we start resizing but we get an old size frame first).
+ return it == resize_locks_.end() || ++it != resize_locks_.end();
+}
+
void RenderWidgetHostViewAura::UpdateExternalTexture() {
// Delay processing accelerated compositing state change till here where we
// act upon the state change. (Clear the external texture if switching to
@@ -710,7 +762,6 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
if (!container) {
resize_locks_.clear();
} else {
- typedef std::vector<linked_ptr<ResizeLock> > ResizeLockList;
ResizeLockList::iterator it = resize_locks_.begin();
while (it != resize_locks_.end()) {
gfx::Size container_size = ConvertSizeToDIP(this,
@@ -726,8 +777,8 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
// Delay the release of the lock until we've kicked a frame with the
// new texture, to avoid resizing the UI before we have a chance to
// draw a "good" frame.
- locks_pending_draw_.insert(
- locks_pending_draw_.begin(), resize_locks_.begin(), it);
+ locks_pending_commit_.insert(
+ locks_pending_commit_.begin(), resize_locks_.begin(), it);
// However since we got the size we were looking for, unlock the
// compositor.
for (ResizeLockList::iterator it2 = resize_locks_.begin();
@@ -744,12 +795,12 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() {
window_->SetExternalTexture(NULL);
if (ShouldReleaseFrontSurface() &&
host_->is_accelerated_compositing_active()) {
- // The current surface may have pipelined gl commands, so always wait for
- // the next composite to start. If the current surface is still null,
- // then we really know its no longer in use.
+ // We need to wait for a commit to clear to guarantee that all we
+ // will not issue any more GL referencing the previous surface.
ui::Compositor* compositor = GetCompositor();
if (compositor) {
- on_compositing_will_start_callbacks_.push_back(
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ on_compositing_did_commit_callbacks_.push_back(
base::Bind(&RenderWidgetHostViewAura::
SetSurfaceNotInUseByCompositor,
AsWeakPtr()));
@@ -771,15 +822,22 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
params_in_pixel.protection_state_id != protection_state_id_) {
DCHECK(!current_surface_);
if (!params_in_pixel.skip_ack)
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL);
+ InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
+ return;
+ }
+
+ if (ShouldFastACK(params_in_pixel.surface_handle)) {
+ if (!params_in_pixel.skip_ack)
+ InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
return;
}
+
current_surface_ = params_in_pixel.surface_handle;
// If we don't require an ACK that means the content is not a fresh updated
- // new frame, rather we are just resetting our handle to some old content that
- // we still hadn't discarded. Although we could display immediately, by not
- // resetting the compositor lock here, we give us some time to get a fresh
- // frame which means fewer content flashes.
+ // new frame, rather we are just resetting our handle to some old content
+ // that we still hadn't discarded. Although we could display immediately,
+ // by not resetting the compositor lock here, we give us some time to get
+ // a fresh frame which means fewer content flashes.
if (!params_in_pixel.skip_ack)
released_front_lock_ = NULL;
@@ -787,46 +845,26 @@ void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
ui::Compositor* compositor = GetCompositor();
if (!compositor) {
- // We have no compositor, so we have no way to display the surface.
- // Must still send the ACK.
if (!params_in_pixel.skip_ack)
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL);
+ InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
} else {
DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) !=
image_transport_clients_.end());
gfx::Size surface_size_in_pixel =
image_transport_clients_[params_in_pixel.surface_handle]->size();
- gfx::Size surface_size = ConvertSizeToDIP(this,
- surface_size_in_pixel);
+ gfx::Size surface_size = ConvertSizeToDIP(this, surface_size_in_pixel);
window_->SchedulePaintInRect(gfx::Rect(surface_size));
if (!params_in_pixel.skip_ack) {
- if (!resize_locks_.empty()) {
- // If we are waiting for the resize, fast-track the ACK.
- if (compositor->IsThreaded()) {
- // We need the compositor thread to pick up the active buffer before
- // ACKing.
- on_compositing_did_commit_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
- params_in_pixel.route_id,
- gpu_host_id));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
- } else {
- // The compositor will pickup the active buffer during a draw, so we
- // can ACK immediately.
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id,
- compositor);
- }
- } else {
- // Add sending an ACK to the list of things to do OnCompositingWillStart
- on_compositing_will_start_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
- params_in_pixel.route_id,
- gpu_host_id));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
- }
+ // Add sending an ACK to the list of things to do OnCompositingDidCommit
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ on_compositing_did_commit_callbacks_.push_back(
+ base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
+ params_in_pixel.route_id,
+ gpu_host_id,
+ true));
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
}
}
}
@@ -840,9 +878,15 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
if (params_in_pixel.protection_state_id &&
params_in_pixel.protection_state_id != protection_state_id_) {
DCHECK(!current_surface_);
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL);
+ InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
+ return;
+ }
+
+ if (ShouldFastACK(params_in_pixel.surface_handle)) {
+ InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
return;
}
+
current_surface_ = params_in_pixel.surface_handle;
released_front_lock_ = NULL;
DCHECK(current_surface_);
@@ -850,9 +894,7 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
ui::Compositor* compositor = GetCompositor();
if (!compositor) {
- // We have no compositor, so we have no way to display the surface
- // Must still send the ACK
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL);
+ InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
} else {
DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) !=
image_transport_clients_.end());
@@ -875,32 +917,15 @@ void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
window_->SchedulePaintInRect(rect_to_paint);
- if (!resize_locks_.empty()) {
- // If we are waiting for the resize, fast-track the ACK.
- if (compositor->IsThreaded()) {
- // We need the compositor thread to pick up the active buffer before
- // ACKing.
- on_compositing_did_commit_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
- params_in_pixel.route_id,
- gpu_host_id));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
- } else {
- // The compositor will pickup the active buffer during a draw, so we
- // can ACK immediately.
- InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id,
- compositor);
- }
- } else {
- // Add sending an ACK to the list of things to do OnCompositingWillStart
- on_compositing_will_start_callbacks_.push_back(
- base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
- params_in_pixel.route_id,
- gpu_host_id));
- if (!compositor->HasObserver(this))
- compositor->AddObserver(this);
- }
+ // Add sending an ACK to the list of things to do OnCompositingDidCommit
+ can_lock_compositor_ = NO_PENDING_COMMIT;
+ on_compositing_did_commit_callbacks_.push_back(
+ base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
+ params_in_pixel.route_id,
+ gpu_host_id,
+ true));
+ if (!compositor->HasObserver(this))
+ compositor->AddObserver(this);
}
}
@@ -1653,17 +1678,19 @@ void RenderWidgetHostViewAura::OnLostActive() {
void RenderWidgetHostViewAura::OnCompositingDidCommit(
ui::Compositor* compositor) {
+ if (can_lock_compositor_ == NO_PENDING_COMMIT) {
+ can_lock_compositor_ = YES;
+ for (ResizeLockList::iterator it = resize_locks_.begin();
+ it != resize_locks_.end(); ++it)
+ if ((*it)->GrabDeferredLock())
+ can_lock_compositor_ = YES_DID_LOCK;
+ }
RunCompositingDidCommitCallbacks(compositor);
-}
-
-void RenderWidgetHostViewAura::OnCompositingWillStart(
- ui::Compositor* compositor) {
- RunCompositingWillStartCallbacks(compositor);
+ locks_pending_commit_.clear();
}
void RenderWidgetHostViewAura::OnCompositingStarted(
ui::Compositor* compositor) {
- locks_pending_draw_.clear();
}
void RenderWidgetHostViewAura::OnCompositingEnded(
@@ -1674,6 +1701,15 @@ void RenderWidgetHostViewAura::OnCompositingAborted(
ui::Compositor* compositor) {
}
+void RenderWidgetHostViewAura::OnCompositingLockStateChanged(
+ ui::Compositor* compositor) {
+ // A compositor lock that is part of a resize lock timed out. We
+ // should display a renderer frame.
+ if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) {
+ can_lock_compositor_ = NO_PENDING_RENDERER_FRAME;
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation:
@@ -1685,7 +1721,7 @@ void RenderWidgetHostViewAura::OnLostResources() {
current_surface_in_use_by_compositor_ = true;
surface_route_id_ = 0;
UpdateExternalTexture();
- locks_pending_draw_.clear();
+ locks_pending_commit_.clear();
DCHECK(!shared_surface_handle_.is_null());
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
@@ -1832,19 +1868,10 @@ void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks(
on_compositing_did_commit_callbacks_.clear();
}
-void RenderWidgetHostViewAura::RunCompositingWillStartCallbacks(
- ui::Compositor* compositor) {
- for (std::vector< base::Callback<void(ui::Compositor*)> >::const_iterator
- it = on_compositing_will_start_callbacks_.begin();
- it != on_compositing_will_start_callbacks_.end(); ++it) {
- it->Run(compositor);
- }
- on_compositing_will_start_callbacks_.clear();
-}
-
// static
void RenderWidgetHostViewAura::InsertSyncPointAndACK(
- int32 route_id, int gpu_host_id, ui::Compositor* compositor) {
+ int32 route_id, int gpu_host_id, bool presented,
+ ui::Compositor* compositor) {
uint32 sync_point = 0;
// If we have no compositor, so we must still send the ACK. A zero
// sync point will not be waited for in the GPU process.
@@ -1854,7 +1881,7 @@ void RenderWidgetHostViewAura::InsertSyncPointAndACK(
}
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- route_id, gpu_host_id, sync_point);
+ route_id, gpu_host_id, presented, sync_point);
}
void RenderWidgetHostViewAura::RemovingFromRootWindow() {
@@ -1866,8 +1893,7 @@ void RenderWidgetHostViewAura::RemovingFromRootWindow() {
// composited data.
ui::Compositor* compositor = GetCompositor();
RunCompositingDidCommitCallbacks(compositor);
- RunCompositingWillStartCallbacks(compositor);
- locks_pending_draw_.clear();
+ locks_pending_commit_.clear();
if (compositor && compositor->HasObserver(this))
compositor->RemoveObserver(this);
DetachFromInputMethod();
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 70d244f..c6076f3 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -24,7 +24,6 @@
#include "webkit/glue/webcursor.h"
namespace aura {
-class CompositorLock;
class WindowTracker;
}
@@ -33,6 +32,7 @@ class Canvas;
}
namespace ui {
+class CompositorLock;
class InputMethod;
class Texture;
}
@@ -206,10 +206,11 @@ class RenderWidgetHostViewAura
// Overridden from ui::CompositorObserver:
virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE;
- virtual void OnCompositingWillStart(ui::Compositor* compositor) OVERRIDE;
virtual void OnCompositingStarted(ui::Compositor* compositor) OVERRIDE;
virtual void OnCompositingEnded(ui::Compositor* compositor) OVERRIDE;
virtual void OnCompositingAborted(ui::Compositor* compositor) OVERRIDE;
+ virtual void OnCompositingLockStateChanged(
+ ui::Compositor* compositor) OVERRIDE;
// Overridden from ImageTransportFactoryObserver:
virtual void OnLostResources() OVERRIDE;
@@ -217,6 +218,7 @@ class RenderWidgetHostViewAura
virtual ~RenderWidgetHostViewAura();
void UpdateCursorIfOverSelf();
+ bool ShouldFastACK(uint64 surface_id);
void UpdateExternalTexture();
ui::InputMethod* GetInputMethod() const;
@@ -241,12 +243,12 @@ class RenderWidgetHostViewAura
// Run the compositing callbacks.
void RunCompositingDidCommitCallbacks(ui::Compositor* compositor);
- void RunCompositingWillStartCallbacks(ui::Compositor* compositor);
// Insert a sync point into the compositor's command stream and acknowledge
// that we have presented the accelerated surface buffer.
static void InsertSyncPointAndACK(int32 route_id,
int gpu_host_id,
+ bool presented,
ui::Compositor* compositor);
// Called when window_ is removed from the window tree.
@@ -330,9 +332,6 @@ class RenderWidgetHostViewAura
std::vector< base::Callback<void(ui::Compositor*)> >
on_compositing_did_commit_callbacks_;
- std::vector< base::Callback<void(ui::Compositor*)> >
- on_compositing_will_start_callbacks_;
-
std::map<uint64, scoped_refptr<ui::Texture> >
image_transport_clients_;
@@ -379,19 +378,32 @@ class RenderWidgetHostViewAura
// Used to prevent further resizes while a resize is pending.
class ResizeLock;
+ typedef std::vector<linked_ptr<ResizeLock> > ResizeLockList;
+
// These locks are the ones waiting for a texture of the right size to come
// back from the renderer/GPU process.
- std::vector<linked_ptr<ResizeLock> > resize_locks_;
- // These locks are the ones waiting for a frame to be drawn.
- std::vector<linked_ptr<ResizeLock> > locks_pending_draw_;
+ ResizeLockList resize_locks_;
+ // These locks are the ones waiting for a frame to be committed.
+ ResizeLockList locks_pending_commit_;
// This lock is for waiting for a front surface to become available to draw.
- scoped_refptr<aura::CompositorLock> released_front_lock_;
+ scoped_refptr<ui::CompositorLock> released_front_lock_;
// Used to track the state of the window we're created from. Only used when
// created fullscreen.
scoped_ptr<aura::WindowTracker> host_tracker_;
+ enum CanLockCompositorState {
+ YES,
+ // We locked, so at some point we'll need to kick a frame.
+ YES_DID_LOCK,
+ // No. A lock timed out, we need to kick a new frame before locking again.
+ NO_PENDING_RENDERER_FRAME,
+ // No. We've got a frame, but it hasn't been committed.
+ NO_PENDING_COMMIT,
+ };
+ CanLockCompositorState can_lock_compositor_;
+
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAura);
};
diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.cc b/content/browser/renderer_host/render_widget_host_view_gtk.cc
index dbe534d4..b429496 100644
--- a/content/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/content/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -1072,14 +1072,14 @@ void RenderWidgetHostViewGtk::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- params.route_id, gpu_host_id, 0);
+ params.route_id, gpu_host_id, true, 0);
}
void RenderWidgetHostViewGtk::AcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
int gpu_host_id) {
RenderWidgetHostImpl::AcknowledgeBufferPresent(
- params.route_id, gpu_host_id, 0);
+ params.route_id, gpu_host_id, true, 0);
}
void RenderWidgetHostViewGtk::AcceleratedSurfaceSuspend() {
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index f6cdfd4..8b75f45 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1037,6 +1037,7 @@ void RenderWidgetHostViewMac::AckPendingSwapBuffers() {
RenderWidgetHostImpl::AcknowledgeBufferPresent(
pending_swap_buffers_acks_.front().first,
pending_swap_buffers_acks_.front().second,
+ true,
0);
if (render_widget_host_) {
render_widget_host_->AcknowledgeSwapBuffersToRenderer();
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index 4549e30..498f1ba 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -275,7 +275,8 @@ IPC_MESSAGE_ROUTED2(AcceleratedSurfaceMsg_SetFrontSurfaceIsProtected,
// Tells the GPU process that the browser process has handled the swap
// buffers or post sub-buffer request. A non-zero sync point means
// that we should wait for the sync point.
-IPC_MESSAGE_ROUTED1(AcceleratedSurfaceMsg_BufferPresented,
+IPC_MESSAGE_ROUTED2(AcceleratedSurfaceMsg_BufferPresented,
+ bool /* presented */,
uint32 /* sync_point */)
// Tells the GPU process to remove all contexts.
diff --git a/content/common/gpu/image_transport_surface.cc b/content/common/gpu/image_transport_surface.cc
index dce01a2..47bb204 100644
--- a/content/common/gpu/image_transport_surface.cc
+++ b/content/common/gpu/image_transport_surface.cc
@@ -212,8 +212,9 @@ void ImageTransportHelper::OnSetFrontSurfaceIsProtected(
surface_->OnSetFrontSurfaceIsProtected(is_protected, protection_state_id);
}
-void ImageTransportHelper::OnBufferPresented(uint32 sync_point) {
- surface_->OnBufferPresented(sync_point);
+void ImageTransportHelper::OnBufferPresented(bool presented,
+ uint32 sync_point) {
+ surface_->OnBufferPresented(presented, sync_point);
}
void ImageTransportHelper::OnResizeViewACK() {
@@ -311,7 +312,9 @@ bool PassThroughImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
return true;
}
-void PassThroughImageTransportSurface::OnBufferPresented(uint32 sync_point) {
+void PassThroughImageTransportSurface::OnBufferPresented(
+ bool /* presented */,
+ uint32 /* sync_point */) {
DCHECK(transport_);
helper_->SetScheduled(true);
}
diff --git a/content/common/gpu/image_transport_surface.h b/content/common/gpu/image_transport_surface.h
index 3a9849e..391f72a 100644
--- a/content/common/gpu/image_transport_surface.h
+++ b/content/common/gpu/image_transport_surface.h
@@ -60,7 +60,7 @@ class ImageTransportSurface {
public:
ImageTransportSurface();
- virtual void OnBufferPresented(uint32 sync_point) = 0;
+ virtual void OnBufferPresented(bool presented, uint32 sync_point) = 0;
virtual void OnResizeViewACK() = 0;
virtual void OnResize(gfx::Size size) = 0;
virtual void OnSetFrontSurfaceIsProtected(bool is_protected,
@@ -139,7 +139,7 @@ class ImageTransportHelper : public IPC::Listener {
gpu::gles2::GLES2Decoder* Decoder();
// IPC::Message handlers.
- void OnBufferPresented(uint32 sync_point);
+ void OnBufferPresented(bool presented, uint32 sync_point);
void OnResizeViewACK();
void OnSetFrontSurfaceIsProtected(bool is_protected,
uint32 protection_state_id);
@@ -177,7 +177,8 @@ class PassThroughImageTransportSurface
virtual bool OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
// ImageTransportSurface implementation.
- virtual void OnBufferPresented(uint32 sync_point) OVERRIDE;
+ virtual void OnBufferPresented(bool presented,
+ uint32 sync_point) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
virtual gfx::Size GetSize() OVERRIDE;
diff --git a/content/common/gpu/image_transport_surface_mac.cc b/content/common/gpu/image_transport_surface_mac.cc
index bb9defe..0070c0e 100644
--- a/content/common/gpu/image_transport_surface_mac.cc
+++ b/content/common/gpu/image_transport_surface_mac.cc
@@ -57,7 +57,8 @@ class IOSurfaceImageTransportSurface : public gfx::NoOpGLSurfaceCGL,
protected:
// ImageTransportSurface implementation
- virtual void OnBufferPresented(uint32 sync_point) OVERRIDE;
+ virtual void OnBufferPresented(bool presented,
+ uint32 sync_point) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
@@ -273,7 +274,8 @@ gfx::Size IOSurfaceImageTransportSurface::GetSize() {
return size_;
}
-void IOSurfaceImageTransportSurface::OnBufferPresented(uint32 sync_point) {
+void IOSurfaceImageTransportSurface::OnBufferPresented(bool presented,
+ uint32 sync_point) {
DCHECK(is_swap_buffers_pending_);
is_swap_buffers_pending_ = false;
if (did_unschedule_) {
diff --git a/content/common/gpu/image_transport_surface_win.cc b/content/common/gpu/image_transport_surface_win.cc
index bc4953a..930c888 100644
--- a/content/common/gpu/image_transport_surface_win.cc
+++ b/content/common/gpu/image_transport_surface_win.cc
@@ -50,7 +50,7 @@ class PbufferImageTransportSurface
protected:
// ImageTransportSurface implementation
- virtual void OnBufferPresented(uint32 sync_point) OVERRIDE;
+ virtual void OnBufferPresented(bool presented, uint32 sync_point) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
virtual gfx::Size GetSize() OVERRIDE;
@@ -205,7 +205,8 @@ void PbufferImageTransportSurface::SendBuffersSwapped() {
is_swap_buffers_pending_ = true;
}
-void PbufferImageTransportSurface::OnBufferPresented(uint32 sync_point) {
+void PbufferImageTransportSurface::OnBufferPresented(bool presented,
+ uint32 sync_point) {
is_swap_buffers_pending_ = false;
if (did_unschedule_) {
did_unschedule_ = false;
diff --git a/content/common/gpu/texture_image_transport_surface.cc b/content/common/gpu/texture_image_transport_surface.cc
index ab0a276..ec9aeb4 100644
--- a/content/common/gpu/texture_image_transport_surface.cc
+++ b/content/common/gpu/texture_image_transport_surface.cc
@@ -46,7 +46,8 @@ TextureImageTransportSurface::TextureImageTransportSurface(
handle_(handle),
parent_stub_(NULL),
is_swap_buffers_pending_(false),
- did_unschedule_(false) {
+ did_unschedule_(false),
+ did_flip_(false) {
helper_.reset(new ImageTransportHelper(this,
manager,
stub,
@@ -323,7 +324,7 @@ bool TextureImageTransportSurface::PostSubBuffer(
region_to_copy.width(), region_to_copy.height());
}
}
- } else {
+ } else if (!surfaces_same_size && did_flip_) {
DCHECK(new_damage_rect == gfx::Rect(expected_size));
}
@@ -391,21 +392,35 @@ void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected(
}
}
-void TextureImageTransportSurface::OnBufferPresented(uint32 sync_point) {
+void TextureImageTransportSurface::OnBufferPresented(bool presented,
+ uint32 sync_point) {
if (sync_point == 0) {
- BufferPresentedImpl();
+ BufferPresentedImpl(presented);
} else {
helper_->manager()->sync_point_manager()->AddSyncPointCallback(
sync_point,
base::Bind(&TextureImageTransportSurface::BufferPresentedImpl,
- this->AsWeakPtr()));
+ this->AsWeakPtr(),
+ presented));
}
}
-void TextureImageTransportSurface::BufferPresentedImpl() {
+void TextureImageTransportSurface::BufferPresentedImpl(bool presented) {
DCHECK(is_swap_buffers_pending_);
is_swap_buffers_pending_ = false;
+ if (presented) {
+ // If we had not flipped, the two frame damage tracking is inconsistent.
+ // So conservatively take the whole frame.
+ if (!did_flip_)
+ previous_damage_rect_ = gfx::Rect(textures_[front()].size);
+ } else {
+ front_ = back();
+ previous_damage_rect_ = gfx::Rect(0, 0, 0, 0);
+ }
+
+ did_flip_ = presented;
+
// We're relying on the fact that the parent context is
// finished with it's context when it inserts the sync point that
// triggers this callback.
diff --git a/content/common/gpu/texture_image_transport_surface.h b/content/common/gpu/texture_image_transport_surface.h
index 0d19d0f..150b585 100644
--- a/content/common/gpu/texture_image_transport_surface.h
+++ b/content/common/gpu/texture_image_transport_surface.h
@@ -48,6 +48,7 @@ class TextureImageTransportSurface :
protected:
// ImageTransportSurface implementation.
virtual void OnBufferPresented(
+ bool presented,
uint32 sync_point) OVERRIDE;
virtual void OnResizeViewACK() OVERRIDE;
virtual void OnSetFrontSurfaceIsProtected(
@@ -83,7 +84,7 @@ class TextureImageTransportSurface :
void ReleaseTexture(int id);
void ReleaseParentStub();
void AdjustFrontBufferAllocation();
- void BufferPresentedImpl();
+ void BufferPresentedImpl(bool presented);
int front() const { return front_; }
int back() const { return 1 - front_; }
@@ -122,6 +123,10 @@ class TextureImageTransportSurface :
// Whether we unscheduled command buffer because of pending SwapBuffers.
bool did_unschedule_;
+ // Whether or not the buffer flip went through browser side on the last
+ // swap or post sub buffer.
+ bool did_flip_;
+
DISALLOW_COPY_AND_ASSIGN(TextureImageTransportSurface);
};
diff --git a/ui/aura/bench/bench_main.cc b/ui/aura/bench/bench_main.cc
index b75a5d4..f105854 100644
--- a/ui/aura/bench/bench_main.cc
+++ b/ui/aura/bench/bench_main.cc
@@ -95,8 +95,6 @@ class BenchCompositorObserver : public ui::CompositorObserver {
virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {}
- virtual void OnCompositingWillStart(Compositor* compositor) OVERRIDE {}
-
virtual void OnCompositingStarted(Compositor* compositor) OVERRIDE {}
virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE {
@@ -120,6 +118,9 @@ class BenchCompositorObserver : public ui::CompositorObserver {
virtual void OnCompositingAborted(Compositor* compositor) OVERRIDE {}
+ virtual void OnCompositingLockStateChanged(
+ Compositor* compositor) OVERRIDE {}
+
virtual void Draw() {}
int frames() const { return frames_; }
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 39b07b7..5634566 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -50,8 +50,6 @@ namespace {
const char kRootWindowForAcceleratedWidget[] =
"__AURA_ROOT_WINDOW_ACCELERATED_WIDGET__";
-const int kCompositorLockTimeoutMs = 67;
-
// Returns true if |target| has a non-client (frame) component at |location|,
// in window coordinates.
bool IsNonClientLocation(Window* target, const gfx::Point& location) {
@@ -96,25 +94,6 @@ RootWindowHost* CreateHost(RootWindow* root_window,
} // namespace
-CompositorLock::CompositorLock(RootWindow* root_window)
- : root_window_(root_window) {
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&CompositorLock::CancelLock, AsWeakPtr()),
- base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs));
-}
-
-CompositorLock::~CompositorLock() {
- CancelLock();
-}
-
-void CompositorLock::CancelLock() {
- if (!root_window_)
- return;
- root_window_->UnlockCompositor();
- root_window_ = NULL;
-}
-
RootWindow::CreateParams::CreateParams(const gfx::Rect& a_initial_bounds)
: initial_bounds(a_initial_bounds),
host(NULL) {
@@ -143,9 +122,7 @@ RootWindow::RootWindow(const CreateParams& params)
draw_on_compositing_end_(false),
defer_draw_scheduling_(false),
mouse_move_hold_count_(0),
- ALLOW_THIS_IN_INITIALIZER_LIST(held_mouse_event_factory_(this)),
- compositor_lock_(NULL),
- draw_on_compositor_unlock_(false) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(held_mouse_event_factory_(this)) {
SetName("RootWindow");
compositor_.reset(new ui::Compositor(this, host_->GetAcceleratedWidget()));
@@ -158,12 +135,6 @@ RootWindow::RootWindow(const CreateParams& params)
}
RootWindow::~RootWindow() {
- if (compositor_lock_) {
- // No need to schedule a draw, we're going away.
- draw_on_compositor_unlock_ = false;
- compositor_lock_->CancelLock();
- DCHECK(!compositor_lock_);
- }
compositor_->RemoveObserver(this);
// Make sure to destroy the compositor before terminating so that state is
// cleared and we don't hit asserts.
@@ -279,10 +250,6 @@ void RootWindow::Draw() {
draw_on_compositing_end_ = true;
return;
}
- if (compositor_lock_) {
- draw_on_compositor_unlock_ = true;
- return;
- }
waiting_on_compositing_end_ = true;
TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::Draw",
@@ -412,6 +379,7 @@ void RootWindow::HoldMouseMoves() {
if (!mouse_move_hold_count_)
held_mouse_event_factory_.InvalidateWeakPtrs();
++mouse_move_hold_count_;
+ TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::HoldMouseMoves", this);
}
void RootWindow::ReleaseMouseMoves() {
@@ -428,12 +396,7 @@ void RootWindow::ReleaseMouseMoves() {
base::Bind(&RootWindow::DispatchHeldMouseMove,
held_mouse_event_factory_.GetWeakPtr()));
}
-}
-
-scoped_refptr<CompositorLock> RootWindow::GetCompositorLock() {
- if (!compositor_lock_)
- compositor_lock_ = new CompositorLock(this);
- return compositor_lock_;
+ TRACE_EVENT_ASYNC_END0("ui", "RootWindow::HoldMouseMoves", this);
}
void RootWindow::SetFocusWhenShown(bool focused) {
@@ -486,9 +449,7 @@ ui::EventTarget* RootWindow::GetParentTarget() {
// RootWindow, ui::CompositorDelegate implementation:
void RootWindow::ScheduleDraw() {
- if (compositor_lock_) {
- draw_on_compositor_unlock_ = true;
- } else if (!defer_draw_scheduling_) {
+ if (!defer_draw_scheduling_) {
defer_draw_scheduling_ = true;
MessageLoop::current()->PostTask(
FROM_HERE,
@@ -502,9 +463,6 @@ void RootWindow::ScheduleDraw() {
void RootWindow::OnCompositingDidCommit(ui::Compositor*) {
}
-void RootWindow::OnCompositingWillStart(ui::Compositor*) {
-}
-
void RootWindow::OnCompositingStarted(ui::Compositor*) {
}
@@ -525,6 +483,9 @@ void RootWindow::OnCompositingEnded(ui::Compositor*) {
void RootWindow::OnCompositingAborted(ui::Compositor*) {
}
+void RootWindow::OnCompositingLockStateChanged(ui::Compositor*) {
+}
+
////////////////////////////////////////////////////////////////////////////////
// RootWindow, ui::LayerDelegate implementation:
@@ -1062,13 +1023,4 @@ void RootWindow::SynthesizeMouseMoveEvent() {
#endif
}
-void RootWindow::UnlockCompositor() {
- DCHECK(compositor_lock_);
- compositor_lock_ = NULL;
- if (draw_on_compositor_unlock_) {
- draw_on_compositor_unlock_ = false;
- ScheduleDraw();
- }
-}
-
} // namespace aura
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 7631d96..2d07627 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -50,31 +50,6 @@ class RootWindow;
class RootWindowHost;
class RootWindowObserver;
-// This class represents a lock on the compositor, that can be used to prevent a
-// compositing pass from happening while we're waiting for an asynchronous
-// event. The typical use case is when waiting for a renderer to produce a frame
-// at the right size. The caller keeps a reference on this object, and drops the
-// reference once it desires to release the lock.
-// Note however that the lock is canceled after a short timeout to ensure
-// responsiveness of the UI, so the compositor tree should be kept in a
-// "reasonable" state while the lock is held.
-// Don't instantiate this class directly, use RootWindow::GetCompositorLock.
-class AURA_EXPORT CompositorLock
- : public base::RefCounted<CompositorLock>,
- public base::SupportsWeakPtr<CompositorLock> {
- private:
- friend class base::RefCounted<CompositorLock>;
- friend class RootWindow;
-
- explicit CompositorLock(RootWindow* root_window);
- ~CompositorLock();
-
- void CancelLock();
-
- RootWindow* root_window_;
- DISALLOW_COPY_AND_ASSIGN(CompositorLock);
-};
-
// RootWindow is responsible for hosting a set of windows.
class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
public ui::CompositorObserver,
@@ -235,9 +210,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
void HoldMouseMoves();
void ReleaseMouseMoves();
- // Creates a compositor lock.
- scoped_refptr<CompositorLock> GetCompositorLock();
-
// Sets if the window should be focused when shown.
void SetFocusWhenShown(bool focus_when_shown);
@@ -262,10 +234,10 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// Overridden from ui::CompositorObserver:
virtual void OnCompositingDidCommit(ui::Compositor*) OVERRIDE;
- virtual void OnCompositingWillStart(ui::Compositor*) OVERRIDE;
virtual void OnCompositingStarted(ui::Compositor*) OVERRIDE;
virtual void OnCompositingEnded(ui::Compositor*) OVERRIDE;
virtual void OnCompositingAborted(ui::Compositor*) OVERRIDE;
+ virtual void OnCompositingLockStateChanged(ui::Compositor*) OVERRIDE;
// Overridden from ui::LayerDelegate:
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;
@@ -285,7 +257,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
private:
friend class Window;
- friend class CompositorLock;
// Called whenever the mouse moves, tracks the current |mouse_moved_handler_|,
// sending exited and entered events as its value changes.
@@ -361,9 +332,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// current mouse location.
void SynthesizeMouseMoveEvent();
- // Called by CompositorLock.
- void UnlockCompositor();
-
scoped_ptr<ui::Compositor> compositor_;
scoped_ptr<RootWindowHost> host_;
@@ -410,9 +378,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
scoped_ptr<ui::ViewProp> prop_;
- CompositorLock* compositor_lock_;
- bool draw_on_compositor_unlock_;
-
DISALLOW_COPY_AND_ASSIGN(RootWindow);
};
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 31f47c7..f1c1b25 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -6,7 +6,9 @@
#include <algorithm>
+#include "base/bind.h"
#include "base/command_line.h"
+#include "base/message_loop.h"
#include "base/threading/thread_restrictions.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/Source/Platform/chromium/public/Platform.h"
@@ -40,6 +42,8 @@ bool test_compositor_enabled = false;
ui::ContextFactory* g_context_factory = NULL;
+const int kCompositorLockTimeoutMs = 67;
+
} // namespace
namespace ui {
@@ -132,6 +136,25 @@ Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor)
Texture::~Texture() {
}
+CompositorLock::CompositorLock(Compositor* compositor)
+ : compositor_(compositor) {
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&CompositorLock::CancelLock, AsWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs));
+}
+
+CompositorLock::~CompositorLock() {
+ CancelLock();
+}
+
+void CompositorLock::CancelLock() {
+ if (!compositor_)
+ return;
+ compositor_->UnlockCompositor();
+ compositor_ = NULL;
+}
+
Compositor::Compositor(CompositorDelegate* delegate,
gfx::AcceleratedWidget widget)
: delegate_(delegate),
@@ -141,7 +164,8 @@ Compositor::Compositor(CompositorDelegate* delegate,
device_scale_factor_(0.0f),
last_started_frame_(0),
last_ended_frame_(0),
- disable_schedule_composite_(false) {
+ disable_schedule_composite_(false),
+ compositor_lock_(NULL) {
WebKit::WebCompositorSupport* compositor_support =
WebKit::Platform::current()->compositorSupport();
root_web_layer_.reset(compositor_support->createLayer());
@@ -161,6 +185,9 @@ Compositor::Compositor(CompositorDelegate* delegate,
}
Compositor::~Compositor() {
+ CancelCompositorLock();
+ DCHECK(!compositor_lock_);
+
// Don't call |CompositorDelegate::ScheduleDraw| from this point.
delegate_ = NULL;
if (root_layer_)
@@ -230,15 +257,12 @@ void Compositor::Draw(bool force_clear) {
return;
last_started_frame_++;
- if (!g_compositor_thread)
- FOR_EACH_OBSERVER(CompositorObserver,
- observer_list_,
- OnCompositingWillStart(this));
-
- // TODO(nduca): Temporary while compositor calls
- // compositeImmediately() directly.
- layout();
- host_->composite();
+ if (!g_compositor_thread && !IsLocked()) {
+ // TODO(nduca): Temporary while compositor calls
+ // compositeImmediately() directly.
+ layout();
+ host_->composite();
+ }
if (!g_compositor_thread && !swap_posted_)
NotifyEnd();
}
@@ -257,6 +281,7 @@ bool Compositor::ReadPixels(SkBitmap* bitmap,
bitmap->allocPixels();
SkAutoLockPixels lock_image(*bitmap);
unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
+ CancelCompositorLock();
return host_->compositeAndReadback(pixels, bounds_in_pixel);
}
@@ -287,10 +312,6 @@ bool Compositor::HasObserver(CompositorObserver* observer) {
return observer_list_.HasObserver(observer);
}
-bool Compositor::IsThreaded() const {
- return g_compositor_thread != NULL;
-}
-
void Compositor::OnSwapBuffersPosted() {
swap_posted_ = true;
}
@@ -384,21 +405,14 @@ WebKit::WebCompositorOutputSurface* Compositor::createOutputSurface() {
void Compositor::didRecreateOutputSurface(bool success) {
}
-// Called once per draw in single-threaded compositor mode and potentially
-// many times between draws in the multi-threaded compositor mode.
void Compositor::didCommit() {
+ DCHECK(!IsLocked());
FOR_EACH_OBSERVER(CompositorObserver,
observer_list_,
OnCompositingDidCommit(this));
}
void Compositor::didCommitAndDrawFrame() {
- // TODO(backer): Plumb through an earlier impl side will start.
- if (g_compositor_thread)
- FOR_EACH_OBSERVER(CompositorObserver,
- observer_list_,
- OnCompositingWillStart(this));
-
FOR_EACH_OBSERVER(CompositorObserver,
observer_list_,
OnCompositingStarted(this));
@@ -413,6 +427,33 @@ void Compositor::scheduleComposite() {
ScheduleDraw();
}
+scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
+ if (!compositor_lock_) {
+ compositor_lock_ = new CompositorLock(this);
+ if (g_compositor_thread)
+ host_->setDeferCommits(true);
+ FOR_EACH_OBSERVER(CompositorObserver,
+ observer_list_,
+ OnCompositingLockStateChanged(this));
+ }
+ return compositor_lock_;
+}
+
+void Compositor::UnlockCompositor() {
+ DCHECK(compositor_lock_);
+ compositor_lock_ = NULL;
+ if (g_compositor_thread)
+ host_->setDeferCommits(false);
+ FOR_EACH_OBSERVER(CompositorObserver,
+ observer_list_,
+ OnCompositingLockStateChanged(this));
+}
+
+void Compositor::CancelCompositorLock() {
+ if (compositor_lock_)
+ compositor_lock_->CancelLock();
+}
+
void Compositor::NotifyEnd() {
last_ended_frame_++;
FOR_EACH_OBSERVER(CompositorObserver,
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index c5dc3ba..f3720bc 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -126,6 +126,32 @@ class COMPOSITOR_EXPORT CompositorDelegate {
virtual ~CompositorDelegate() {}
};
+// This class represents a lock on the compositor, that can be used to prevent
+// commits to the compositor tree while we're waiting for an asynchronous
+// event. The typical use case is when waiting for a renderer to produce a frame
+// at the right size. The caller keeps a reference on this object, and drops the
+// reference once it desires to release the lock.
+// Note however that the lock is cancelled after a short timeout to ensure
+// responsiveness of the UI, so the compositor tree should be kept in a
+// "reasonable" state while the lock is held.
+// Don't instantiate this class directly, use Compositor::GetCompositorLock.
+class COMPOSITOR_EXPORT CompositorLock
+ : public base::RefCounted<CompositorLock>,
+ public base::SupportsWeakPtr<CompositorLock> {
+ private:
+ friend class base::RefCounted<CompositorLock>;
+ friend class Compositor;
+
+ explicit CompositorLock(Compositor* compositor);
+ ~CompositorLock();
+
+ void CancelLock();
+
+ Compositor* compositor_;
+ DISALLOW_COPY_AND_ASSIGN(CompositorLock);
+};
+
+
// Compositor object to take care of GPU painting.
// A Browser compositor object is responsible for generating the final
// displayable form of pixels comprising a single widget's contents. It draws an
@@ -196,9 +222,9 @@ class COMPOSITOR_EXPORT Compositor
// and the OnCompositingEnded.
bool DrawPending() const { return swap_posted_; }
- // Returns whether the drawing is issued from a separate thread
- // (i.e. |Compositor::Initialize(true)| was called).
- bool IsThreaded() const;
+ // Creates a compositor lock. Returns NULL if it is not possible to lock at
+ // this time (i.e. we're waiting to complete a previous unlock).
+ scoped_refptr<CompositorLock> GetCompositorLock();
// Internal functions, called back by command-buffer contexts on swap buffer
// events.
@@ -227,8 +253,17 @@ class COMPOSITOR_EXPORT Compositor
int last_started_frame() { return last_started_frame_; }
int last_ended_frame() { return last_ended_frame_; }
+ bool IsLocked() { return compositor_lock_ != NULL; }
+
private:
friend class base::RefCounted<Compositor>;
+ friend class CompositorLock;
+
+ // Called by CompositorLock.
+ void UnlockCompositor();
+
+ // Called to release any pending CompositorLock
+ void CancelCompositorLock();
// Notifies the compositor that compositing is complete.
void NotifyEnd();
@@ -258,6 +293,8 @@ class COMPOSITOR_EXPORT Compositor
bool disable_schedule_composite_;
+ CompositorLock* compositor_lock_;
+
DISALLOW_COPY_AND_ASSIGN(Compositor);
};
diff --git a/ui/compositor/compositor_observer.h b/ui/compositor/compositor_observer.h
index 830f170..4157453 100644
--- a/ui/compositor/compositor_observer.h
+++ b/ui/compositor/compositor_observer.h
@@ -19,12 +19,10 @@ class COMPOSITOR_EXPORT CompositorObserver {
// composite. In the multi-threaded case, many commits may happen between
// two successive composites. In the single-threaded, a single commit
// between two composites (just before the composite as part of the
- // composite cycle).
+ // composite cycle). If the compositor is locked, it will not send this
+ // this signal.
virtual void OnCompositingDidCommit(Compositor* compositor) = 0;
- // Called when compositing will start.
- virtual void OnCompositingWillStart(Compositor* compositor) = 0;
-
// Called when compositing started: it has taken all the layer changes into
// account and has issued the graphics commands.
virtual void OnCompositingStarted(Compositor* compositor) = 0;
@@ -35,6 +33,9 @@ class COMPOSITOR_EXPORT CompositorObserver {
// Called when compositing is aborted (e.g. lost graphics context).
virtual void OnCompositingAborted(Compositor* compositor) = 0;
+ // Called when the compositor lock state changes.
+ virtual void OnCompositingLockStateChanged(Compositor* compositor) = 0;
+
protected:
virtual ~CompositorObserver() {}
};
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index f246997..7d2a1f6 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -323,13 +323,12 @@ class NullLayerDelegate : public LayerDelegate {
class TestCompositorObserver : public CompositorObserver {
public:
TestCompositorObserver()
- : will_start_(false), started_(false), ended_(false), aborted_(false) {}
+ : started_(false), ended_(false), aborted_(false) {}
- bool notified() const { return will_start_ && started_ && ended_; }
+ bool notified() const { return started_ && ended_; }
bool aborted() const { return aborted_; }
void Reset() {
- will_start_ = false;
started_ = false;
ended_ = false;
aborted_ = false;
@@ -339,10 +338,6 @@ class TestCompositorObserver : public CompositorObserver {
virtual void OnCompositingDidCommit(Compositor* compositor) OVERRIDE {
}
- virtual void OnCompositingWillStart(Compositor* compositor) OVERRIDE {
- will_start_ = true;
- }
-
virtual void OnCompositingStarted(Compositor* compositor) OVERRIDE {
started_ = true;
}
@@ -355,7 +350,9 @@ class TestCompositorObserver : public CompositorObserver {
aborted_ = true;
}
- bool will_start_;
+ virtual void OnCompositingLockStateChanged(Compositor* compositor) OVERRIDE {
+ }
+
bool started_;
bool ended_;
bool aborted_;
diff --git a/webkit/compositor_bindings/web_layer_tree_view_impl.cc b/webkit/compositor_bindings/web_layer_tree_view_impl.cc
index e61a166..d1a453e 100644
--- a/webkit/compositor_bindings/web_layer_tree_view_impl.cc
+++ b/webkit/compositor_bindings/web_layer_tree_view_impl.cc
@@ -165,6 +165,11 @@ void WebLayerTreeViewImpl::finishAllRendering()
m_layerTreeHost->finishAllRendering();
}
+void WebLayerTreeViewImpl::setDeferCommits(bool deferCommits)
+{
+ m_layerTreeHost->setDeferCommits(deferCommits);
+}
+
void WebLayerTreeViewImpl::renderingStats(WebRenderingStats& stats) const
{
RenderingStats ccStats;
diff --git a/webkit/compositor_bindings/web_layer_tree_view_impl.h b/webkit/compositor_bindings/web_layer_tree_view_impl.h
index 9b0ecbf..dace36c 100644
--- a/webkit/compositor_bindings/web_layer_tree_view_impl.h
+++ b/webkit/compositor_bindings/web_layer_tree_view_impl.h
@@ -46,6 +46,7 @@ public:
virtual void updateAnimations(double frameBeginTime) OVERRIDE;
virtual bool compositeAndReadback(void *pixels, const WebRect&) OVERRIDE;
virtual void finishAllRendering() OVERRIDE;
+ virtual void setDeferCommits(bool deferCommits) OVERRIDE;
virtual void renderingStats(WebRenderingStats&) const OVERRIDE;
virtual void setFontAtlas(SkBitmap, WebRect asciiToRectTable[128], int fontHeight) OVERRIDE;
virtual void loseCompositorContext(int numTimes) OVERRIDE;