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

Unified Diff: content/browser/renderer_host/render_widget_host_view_aura.cc

Issue 10690168: Aura: Resize locks with --ui-enable-threaded-compositing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: OSX compile fix. Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/render_widget_host_view_aura.cc
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 f8565eee8930390b9190a23eae09d3e897e4b935..6987fcc95dab4f69a9d5887fe12e657529ad8d78 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();

Powered by Google App Engine
This is Rietveld 408576698