Index: ui/compositor/compositor.cc |
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc |
index dbaac60941cbb24bc7e3e4833b2573b7cc6e5317..50585c661aec7c1a38594dada900a1db64d29083 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 { |
@@ -133,6 +137,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_->Unlock(); |
+ compositor_ = NULL; |
+} |
+ |
Compositor::Compositor(CompositorDelegate* delegate, |
gfx::AcceleratedWidget widget) |
: delegate_(delegate), |
@@ -142,7 +165,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()); |
@@ -162,6 +186,11 @@ Compositor::Compositor(CompositorDelegate* delegate, |
} |
Compositor::~Compositor() { |
+ if (compositor_lock_) { |
+ compositor_lock_->CancelLock(); |
+ DCHECK(!compositor_lock_); |
+ } |
+ |
// Don't call |CompositorDelegate::ScheduleDraw| from this point. |
delegate_ = NULL; |
if (root_layer_) |
@@ -231,15 +260,19 @@ void Compositor::Draw(bool force_clear) { |
return; |
last_started_frame_++; |
- if (!g_compositor_thread) |
+ |
+ // Fast track draw because visible state could not have changed. |
piman
2012/10/17 21:26:32
There is a case where we may want to paint anyway,
jonathan.backer
2012/10/18 20:20:35
LayerAnimator::step on the window resize triggers
|
+ if (!g_compositor_thread && IsLocked()) { |
FOR_EACH_OBSERVER(CompositorObserver, |
observer_list_, |
- OnCompositingWillStart(this)); |
+ OnCompositingStarted(this)); |
+ } else { |
+ // TODO(nduca): Temporary while compositor calls |
+ // compositeImmediately() directly. |
+ layout(); |
+ host_->composite(); |
+ } |
- // TODO(nduca): Temporary while compositor calls |
- // compositeImmediately() directly. |
- layout(); |
- host_->composite(); |
if (!g_compositor_thread && !swap_posted_) |
NotifyEnd(); |
} |
@@ -288,10 +321,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; |
} |
@@ -385,21 +414,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() { |
- 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) |
+ if (!IsLocked()) |
piman
2012/10/17 21:26:32
nit: style requires braces because the statement s
jonathan.backer
2012/10/18 20:20:35
Done.
|
FOR_EACH_OBSERVER(CompositorObserver, |
observer_list_, |
- OnCompositingWillStart(this)); |
+ OnCompositingDidCommit(this)); |
+} |
+void Compositor::didCommitAndDrawFrame() { |
FOR_EACH_OBSERVER(CompositorObserver, |
observer_list_, |
OnCompositingStarted(this)); |
@@ -414,6 +436,26 @@ void Compositor::scheduleComposite() { |
ScheduleDraw(); |
} |
+scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { |
+ if (!compositor_lock_) { |
+ compositor_lock_ = new CompositorLock(this); |
+ root_web_layer_->setDeferUpdates(true); |
+ FOR_EACH_OBSERVER(CompositorObserver, |
+ observer_list_, |
+ OnCompositingLockStateChanged(this)); |
+ } |
+ return compositor_lock_; |
+} |
+ |
+void Compositor::Unlock() { |
+ DCHECK(compositor_lock_); |
+ compositor_lock_ = NULL; |
+ root_web_layer_->setDeferUpdates(false); |
+ FOR_EACH_OBSERVER(CompositorObserver, |
+ observer_list_, |
+ OnCompositingLockStateChanged(this)); |
+} |
+ |
void Compositor::NotifyEnd() { |
last_ended_frame_++; |
FOR_EACH_OBSERVER(CompositorObserver, |