Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/render_widget_host_view_aura.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 } | 190 } |
| 191 | 191 |
| 192 private: | 192 private: |
| 193 RenderWidgetHostViewAura* view_; | 193 RenderWidgetHostViewAura* view_; |
| 194 | 194 |
| 195 DISALLOW_COPY_AND_ASSIGN(WindowObserver); | 195 DISALLOW_COPY_AND_ASSIGN(WindowObserver); |
| 196 }; | 196 }; |
| 197 | 197 |
| 198 class RenderWidgetHostViewAura::ResizeLock { | 198 class RenderWidgetHostViewAura::ResizeLock { |
| 199 public: | 199 public: |
| 200 ResizeLock(aura::RootWindow* root_window, const gfx::Size new_size) | 200 ResizeLock(aura::RootWindow* root_window, |
| 201 const gfx::Size new_size, | |
| 202 bool defer_compositor_lock) | |
| 201 : root_window_(root_window), | 203 : root_window_(root_window), |
| 202 new_size_(new_size), | 204 new_size_(new_size), |
| 203 compositor_lock_(root_window_->GetCompositorLock()), | 205 compositor_lock_(defer_compositor_lock ? |
| 204 weak_ptr_factory_(this) { | 206 NULL : |
| 207 root_window_->compositor()->GetCompositorLock()), | |
| 208 weak_ptr_factory_(this), | |
| 209 defer_compositor_lock_(defer_compositor_lock) { | |
| 205 root_window_->HoldMouseMoves(); | 210 root_window_->HoldMouseMoves(); |
| 206 | 211 |
| 207 BrowserThread::PostDelayedTask( | 212 BrowserThread::PostDelayedTask( |
| 208 BrowserThread::UI, FROM_HERE, | 213 BrowserThread::UI, FROM_HERE, |
| 209 base::Bind(&RenderWidgetHostViewAura::ResizeLock::CancelLock, | 214 base::Bind(&RenderWidgetHostViewAura::ResizeLock::CancelLock, |
| 210 weak_ptr_factory_.GetWeakPtr()), | 215 weak_ptr_factory_.GetWeakPtr()), |
| 211 base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)); | 216 base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)); |
| 212 } | 217 } |
| 213 | 218 |
| 214 ~ResizeLock() { | 219 ~ResizeLock() { |
| 215 CancelLock(); | 220 CancelLock(); |
| 216 } | 221 } |
| 217 | 222 |
| 218 void UnlockCompositor() { | 223 void UnlockCompositor() { |
| 224 defer_compositor_lock_ = false; | |
| 219 compositor_lock_ = NULL; | 225 compositor_lock_ = NULL; |
| 220 } | 226 } |
| 221 | 227 |
| 222 void CancelLock() { | 228 void CancelLock() { |
| 223 if (!root_window_) | 229 if (!root_window_) |
| 224 return; | 230 return; |
| 225 UnlockCompositor(); | 231 UnlockCompositor(); |
| 226 root_window_->ReleaseMouseMoves(); | 232 root_window_->ReleaseMouseMoves(); |
| 227 root_window_ = NULL; | 233 root_window_ = NULL; |
| 228 } | 234 } |
| 229 | 235 |
| 230 const gfx::Size& expected_size() const { | 236 const gfx::Size& expected_size() const { |
| 231 return new_size_; | 237 return new_size_; |
| 232 } | 238 } |
| 233 | 239 |
| 240 void GrabDeferredLock() { | |
| 241 if (defer_compositor_lock_) { | |
|
piman
2012/10/17 21:26:32
&& root_window_
jonathan.backer
2012/10/18 20:20:35
Can do. It's more robust. But if root_window_ = NU
| |
| 242 compositor_lock_ = root_window_->compositor()->GetCompositorLock(); | |
| 243 defer_compositor_lock_ = false; | |
| 244 } | |
| 245 } | |
| 246 | |
| 234 private: | 247 private: |
| 235 aura::RootWindow* root_window_; | 248 aura::RootWindow* root_window_; |
| 236 gfx::Size new_size_; | 249 gfx::Size new_size_; |
| 237 scoped_refptr<aura::CompositorLock> compositor_lock_; | 250 scoped_refptr<ui::CompositorLock> compositor_lock_; |
| 238 base::WeakPtrFactory<ResizeLock> weak_ptr_factory_; | 251 base::WeakPtrFactory<ResizeLock> weak_ptr_factory_; |
| 252 bool defer_compositor_lock_; | |
| 239 | 253 |
| 240 DISALLOW_COPY_AND_ASSIGN(ResizeLock); | 254 DISALLOW_COPY_AND_ASSIGN(ResizeLock); |
| 241 }; | 255 }; |
| 242 | 256 |
| 243 //////////////////////////////////////////////////////////////////////////////// | 257 //////////////////////////////////////////////////////////////////////////////// |
| 244 // RenderWidgetHostViewAura, public: | 258 // RenderWidgetHostViewAura, public: |
| 245 | 259 |
| 246 RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host) | 260 RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host) |
| 247 : host_(RenderWidgetHostImpl::From(host)), | 261 : host_(RenderWidgetHostImpl::From(host)), |
| 248 ALLOW_THIS_IN_INITIALIZER_LIST(window_(new aura::Window(this))), | 262 ALLOW_THIS_IN_INITIALIZER_LIST(window_(new aura::Window(this))), |
| 249 in_shutdown_(false), | 263 in_shutdown_(false), |
| 250 is_fullscreen_(false), | 264 is_fullscreen_(false), |
| 251 popup_parent_host_view_(NULL), | 265 popup_parent_host_view_(NULL), |
| 252 popup_child_host_view_(NULL), | 266 popup_child_host_view_(NULL), |
| 253 is_loading_(false), | 267 is_loading_(false), |
| 254 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 268 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
| 255 can_compose_inline_(true), | 269 can_compose_inline_(true), |
| 256 has_composition_text_(false), | 270 has_composition_text_(false), |
| 257 device_scale_factor_(1.0f), | 271 device_scale_factor_(1.0f), |
| 258 current_surface_(0), | 272 current_surface_(0), |
| 259 current_surface_is_protected_(true), | 273 current_surface_is_protected_(true), |
| 260 current_surface_in_use_by_compositor_(true), | 274 current_surface_in_use_by_compositor_(true), |
| 261 protection_state_id_(0), | 275 protection_state_id_(0), |
| 262 surface_route_id_(0), | 276 surface_route_id_(0), |
| 263 paint_canvas_(NULL), | 277 paint_canvas_(NULL), |
| 264 synthetic_move_sent_(false), | 278 synthetic_move_sent_(false), |
| 265 accelerated_compositing_state_changed_(false) { | 279 accelerated_compositing_state_changed_(false), |
| 280 can_lock_compositor_(YES) { | |
| 266 host_->SetView(this); | 281 host_->SetView(this); |
| 267 window_observer_.reset(new WindowObserver(this)); | 282 window_observer_.reset(new WindowObserver(this)); |
| 268 window_->AddObserver(window_observer_.get()); | 283 window_->AddObserver(window_observer_.get()); |
| 269 aura::client::SetTooltipText(window_, &tooltip_); | 284 aura::client::SetTooltipText(window_, &tooltip_); |
| 270 aura::client::SetActivationDelegate(window_, this); | 285 aura::client::SetActivationDelegate(window_, this); |
| 271 } | 286 } |
| 272 | 287 |
| 273 //////////////////////////////////////////////////////////////////////////////// | 288 //////////////////////////////////////////////////////////////////////////////// |
| 274 // RenderWidgetHostViewAura, RenderWidgetHostView implementation: | 289 // RenderWidgetHostViewAura, RenderWidgetHostView implementation: |
| 275 | 290 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 return host_; | 350 return host_; |
| 336 } | 351 } |
| 337 | 352 |
| 338 void RenderWidgetHostViewAura::WasShown() { | 353 void RenderWidgetHostViewAura::WasShown() { |
| 339 if (!host_->is_hidden()) | 354 if (!host_->is_hidden()) |
| 340 return; | 355 return; |
| 341 host_->WasShown(); | 356 host_->WasShown(); |
| 342 | 357 |
| 343 if (!current_surface_ && host_->is_accelerated_compositing_active() && | 358 if (!current_surface_ && host_->is_accelerated_compositing_active() && |
| 344 !released_front_lock_.get()) { | 359 !released_front_lock_.get()) { |
| 345 released_front_lock_ = window_->GetRootWindow()->GetCompositorLock(); | 360 released_front_lock_ = GetCompositor()->GetCompositorLock(); |
| 346 } | 361 } |
| 347 | 362 |
| 348 AdjustSurfaceProtection(); | 363 AdjustSurfaceProtection(); |
| 349 | 364 |
| 350 #if defined(OS_WIN) | 365 #if defined(OS_WIN) |
| 351 LPARAM lparam = reinterpret_cast<LPARAM>(this); | 366 LPARAM lparam = reinterpret_cast<LPARAM>(this); |
| 352 EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam); | 367 EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam); |
| 353 #endif | 368 #endif |
| 354 } | 369 } |
| 355 | 370 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 380 } | 395 } |
| 381 | 396 |
| 382 void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) { | 397 void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) { |
| 383 SetBounds(gfx::Rect(window_->bounds().origin(), size)); | 398 SetBounds(gfx::Rect(window_->bounds().origin(), size)); |
| 384 } | 399 } |
| 385 | 400 |
| 386 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) { | 401 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) { |
| 387 if (window_->bounds().size() != rect.size() && | 402 if (window_->bounds().size() != rect.size() && |
| 388 host_->is_accelerated_compositing_active()) { | 403 host_->is_accelerated_compositing_active()) { |
| 389 aura::RootWindow* root_window = window_->GetRootWindow(); | 404 aura::RootWindow* root_window = window_->GetRootWindow(); |
| 390 if (root_window) { | 405 ui::Compositor* compositor = GetCompositor(); |
|
piman
2012/10/17 21:26:32
nit: ui::Compositor* compositor = root_window ? ro
jonathan.backer
2012/10/18 20:20:35
Done.
| |
| 406 if (root_window && compositor) { | |
| 407 // Listen to changes in the compositor lock state. | |
| 408 if (!compositor->HasObserver(this)) | |
| 409 compositor->AddObserver(this); | |
| 410 | |
| 411 bool defer_compositor_lock = | |
| 412 can_lock_compositor_ == NO_PENDING_FRAME || | |
| 413 can_lock_compositor_ == NO_PENDING_COMMIT; | |
| 414 | |
| 415 if (can_lock_compositor_ == YES) | |
| 416 can_lock_compositor_ = YES_DID_LOCK; | |
| 417 | |
| 391 resize_locks_.push_back(make_linked_ptr( | 418 resize_locks_.push_back(make_linked_ptr( |
| 392 new ResizeLock(root_window, rect.size()))); | 419 new ResizeLock(root_window, rect.size(), defer_compositor_lock))); |
| 393 } | 420 } |
| 394 } | 421 } |
| 395 window_->SetBounds(rect); | 422 window_->SetBounds(rect); |
| 396 host_->WasResized(); | 423 host_->WasResized(); |
| 397 } | 424 } |
| 398 | 425 |
| 399 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const { | 426 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const { |
| 400 return window_; | 427 return window_; |
| 401 } | 428 } |
| 402 | 429 |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 686 // switching to software mode or receive a buffers swapped notification | 713 // switching to software mode or receive a buffers swapped notification |
| 687 // if switching to accelerated mode. | 714 // if switching to accelerated mode. |
| 688 // Sometimes (e.g. on a page load) the renderer will spuriously disable then | 715 // Sometimes (e.g. on a page load) the renderer will spuriously disable then |
| 689 // re-enable accelerated compositing, causing us to flash. | 716 // re-enable accelerated compositing, causing us to flash. |
| 690 // TODO(piman): factor the enable/disable accelerated compositing message into | 717 // TODO(piman): factor the enable/disable accelerated compositing message into |
| 691 // the UpdateRect/AcceleratedSurfaceBuffersSwapped messages so that we have | 718 // the UpdateRect/AcceleratedSurfaceBuffersSwapped messages so that we have |
| 692 // fewer inconsistent temporary states. | 719 // fewer inconsistent temporary states. |
| 693 accelerated_compositing_state_changed_ = true; | 720 accelerated_compositing_state_changed_ = true; |
| 694 } | 721 } |
| 695 | 722 |
| 723 bool RenderWidgetHostViewAura::ShouldFastACK(uint64 surface_id) { | |
| 724 ui::Texture* container = image_transport_clients_[surface_id]; | |
| 725 DCHECK(container); | |
| 726 | |
| 727 if (can_lock_compositor_ == NO_PENDING_FRAME || | |
| 728 can_lock_compositor_ == NO_PENDING_COMMIT || | |
| 729 resize_locks_.empty()) | |
| 730 return false; | |
| 731 | |
| 732 gfx::Size container_size = ConvertSizeToDIP(this, container->size()); | |
| 733 ResizeLockList::iterator it = resize_locks_.begin(); | |
| 734 while (it != resize_locks_.end()) { | |
| 735 if ((*it)->expected_size() == container_size) | |
| 736 break; | |
| 737 ++it; | |
| 738 } | |
| 739 | |
| 740 // We could be getting an unexpected frame due to an animation | |
| 741 // (i.e. we start resizing but we get an old size frame first). | |
| 742 return it == resize_locks_.end() || ++it != resize_locks_.end(); | |
| 743 } | |
| 744 | |
| 696 void RenderWidgetHostViewAura::UpdateExternalTexture() { | 745 void RenderWidgetHostViewAura::UpdateExternalTexture() { |
| 697 // Delay processing accelerated compositing state change till here where we | 746 // Delay processing accelerated compositing state change till here where we |
| 698 // act upon the state change. (Clear the external texture if switching to | 747 // act upon the state change. (Clear the external texture if switching to |
| 699 // software mode or set the external texture if going to accelerated mode). | 748 // software mode or set the external texture if going to accelerated mode). |
| 700 if (accelerated_compositing_state_changed_) { | 749 if (accelerated_compositing_state_changed_) { |
| 701 // Don't scale the contents in accelerated mode because the renderer takes | 750 // Don't scale the contents in accelerated mode because the renderer takes |
| 702 // care of it. | 751 // care of it. |
| 703 window_->layer()->set_scale_content( | 752 window_->layer()->set_scale_content( |
| 704 !host_->is_accelerated_compositing_active()); | 753 !host_->is_accelerated_compositing_active()); |
| 705 | 754 |
| 706 accelerated_compositing_state_changed_ = false; | 755 accelerated_compositing_state_changed_ = false; |
| 707 } | 756 } |
| 708 | 757 |
| 709 if (current_surface_ != 0 && host_->is_accelerated_compositing_active()) { | 758 if (current_surface_ != 0 && host_->is_accelerated_compositing_active()) { |
| 710 ui::Texture* container = image_transport_clients_[current_surface_]; | 759 ui::Texture* container = image_transport_clients_[current_surface_]; |
| 711 window_->SetExternalTexture(container); | 760 window_->SetExternalTexture(container); |
| 712 current_surface_in_use_by_compositor_ = true; | 761 current_surface_in_use_by_compositor_ = true; |
| 713 | 762 |
| 714 if (!container) { | 763 if (!container) { |
| 715 resize_locks_.clear(); | 764 resize_locks_.clear(); |
| 716 } else { | 765 } else { |
| 717 typedef std::vector<linked_ptr<ResizeLock> > ResizeLockList; | |
| 718 ResizeLockList::iterator it = resize_locks_.begin(); | 766 ResizeLockList::iterator it = resize_locks_.begin(); |
| 719 while (it != resize_locks_.end()) { | 767 while (it != resize_locks_.end()) { |
| 720 gfx::Size container_size = ConvertSizeToDIP(this, | 768 gfx::Size container_size = ConvertSizeToDIP(this, |
| 721 container->size()); | 769 container->size()); |
| 722 if ((*it)->expected_size() == container_size) | 770 if ((*it)->expected_size() == container_size) |
| 723 break; | 771 break; |
| 724 ++it; | 772 ++it; |
| 725 } | 773 } |
| 726 if (it != resize_locks_.end()) { | 774 if (it != resize_locks_.end()) { |
| 727 ++it; | 775 ++it; |
| 728 ui::Compositor* compositor = GetCompositor(); | 776 ui::Compositor* compositor = GetCompositor(); |
| 729 if (compositor) { | 777 if (compositor) { |
| 730 // Delay the release of the lock until we've kicked a frame with the | 778 // Delay the release of the lock until we've kicked a frame with the |
| 731 // new texture, to avoid resizing the UI before we have a chance to | 779 // new texture, to avoid resizing the UI before we have a chance to |
| 732 // draw a "good" frame. | 780 // draw a "good" frame. |
| 733 locks_pending_draw_.insert( | 781 locks_pending_commit_.insert( |
| 734 locks_pending_draw_.begin(), resize_locks_.begin(), it); | 782 locks_pending_commit_.begin(), resize_locks_.begin(), it); |
| 735 // However since we got the size we were looking for, unlock the | 783 // However since we got the size we were looking for, unlock the |
| 736 // compositor. | 784 // compositor. |
| 737 for (ResizeLockList::iterator it2 = resize_locks_.begin(); | 785 for (ResizeLockList::iterator it2 = resize_locks_.begin(); |
| 738 it2 !=it; ++it2) { | 786 it2 !=it; ++it2) { |
| 739 it2->get()->UnlockCompositor(); | 787 it2->get()->UnlockCompositor(); |
| 740 } | 788 } |
| 741 if (!compositor->HasObserver(this)) | 789 if (!compositor->HasObserver(this)) |
| 742 compositor->AddObserver(this); | 790 compositor->AddObserver(this); |
| 743 } | 791 } |
| 744 resize_locks_.erase(resize_locks_.begin(), it); | 792 resize_locks_.erase(resize_locks_.begin(), it); |
| 745 } | 793 } |
| 746 } | 794 } |
| 747 } else { | 795 } else { |
| 748 window_->SetExternalTexture(NULL); | 796 window_->SetExternalTexture(NULL); |
| 749 if (ShouldReleaseFrontSurface() && | 797 if (ShouldReleaseFrontSurface() && |
| 750 host_->is_accelerated_compositing_active()) { | 798 host_->is_accelerated_compositing_active()) { |
| 751 // The current surface may have pipelined gl commands, so always wait for | 799 // We need to wait for a commit to clear to guarantee that all we |
| 752 // the next composite to start. If the current surface is still null, | 800 // will not issue any more GL referencing the previous surface. |
| 753 // then we really know its no longer in use. | |
| 754 ui::Compositor* compositor = GetCompositor(); | 801 ui::Compositor* compositor = GetCompositor(); |
| 755 if (compositor) { | 802 if (compositor) { |
| 756 on_compositing_will_start_callbacks_.push_back( | 803 can_lock_compositor_ = NO_PENDING_COMMIT; |
| 804 on_compositing_did_commit_callbacks_.push_back( | |
| 757 base::Bind(&RenderWidgetHostViewAura:: | 805 base::Bind(&RenderWidgetHostViewAura:: |
| 758 SetSurfaceNotInUseByCompositor, | 806 SetSurfaceNotInUseByCompositor, |
| 759 AsWeakPtr())); | 807 AsWeakPtr())); |
| 760 if (!compositor->HasObserver(this)) | 808 if (!compositor->HasObserver(this)) |
| 761 compositor->AddObserver(this); | 809 compositor->AddObserver(this); |
| 762 } | 810 } |
| 763 } | 811 } |
| 764 resize_locks_.clear(); | 812 resize_locks_.clear(); |
| 765 } | 813 } |
| 766 } | 814 } |
| 767 | 815 |
| 768 void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped( | 816 void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped( |
| 769 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel, | 817 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel, |
| 770 int gpu_host_id) { | 818 int gpu_host_id) { |
| 771 surface_route_id_ = params_in_pixel.route_id; | 819 surface_route_id_ = params_in_pixel.route_id; |
| 772 // If protection state changed, then this swap is stale. We must still ACK but | 820 // If protection state changed, then this swap is stale. We must still ACK but |
| 773 // do not update current_surface_ since it may have been discarded. | 821 // do not update current_surface_ since it may have been discarded. |
| 774 if (params_in_pixel.protection_state_id && | 822 if (params_in_pixel.protection_state_id && |
| 775 params_in_pixel.protection_state_id != protection_state_id_) { | 823 params_in_pixel.protection_state_id != protection_state_id_) { |
| 776 DCHECK(!current_surface_); | 824 DCHECK(!current_surface_); |
| 777 if (!params_in_pixel.skip_ack) | 825 if (!params_in_pixel.skip_ack) |
| 778 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL); | 826 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL); |
| 779 return; | 827 return; |
| 780 } | 828 } |
| 781 current_surface_ = params_in_pixel.surface_handle; | |
| 782 // If we don't require an ACK that means the content is not a fresh updated | |
| 783 // new frame, rather we are just resetting our handle to some old content that | |
| 784 // we still hadn't discarded. Although we could display immediately, by not | |
| 785 // resetting the compositor lock here, we give us some time to get a fresh | |
| 786 // frame which means fewer content flashes. | |
| 787 if (!params_in_pixel.skip_ack) | |
| 788 released_front_lock_ = NULL; | |
| 789 | |
| 790 UpdateExternalTexture(); | |
| 791 | 829 |
| 792 ui::Compositor* compositor = GetCompositor(); | 830 ui::Compositor* compositor = GetCompositor(); |
| 793 if (!compositor) { | 831 if (!compositor || ShouldFastACK(params_in_pixel.surface_handle)) { |
|
piman
2012/10/17 21:26:32
I think we still want to update the layer tree (Up
jonathan.backer
2012/10/18 20:20:35
Done.
| |
| 794 // We have no compositor, so we have no way to display the surface. | |
| 795 // Must still send the ACK. | |
| 796 if (!params_in_pixel.skip_ack) | 832 if (!params_in_pixel.skip_ack) |
| 797 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL); | 833 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, |
| 834 compositor); | |
| 798 } else { | 835 } else { |
| 836 current_surface_ = params_in_pixel.surface_handle; | |
| 837 // If we don't require an ACK that means the content is not a fresh updated | |
| 838 // new frame, rather we are just resetting our handle to some old content | |
| 839 // that we still hadn't discarded. Although we could display immediately, | |
| 840 // by not resetting the compositor lock here, we give us some time to get | |
| 841 // a fresh frame which means fewer content flashes. | |
| 842 if (!params_in_pixel.skip_ack) | |
| 843 released_front_lock_ = NULL; | |
| 844 | |
| 845 UpdateExternalTexture(); | |
| 846 | |
| 799 DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) != | 847 DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) != |
| 800 image_transport_clients_.end()); | 848 image_transport_clients_.end()); |
| 801 gfx::Size surface_size_in_pixel = | 849 gfx::Size surface_size_in_pixel = |
| 802 image_transport_clients_[params_in_pixel.surface_handle]->size(); | 850 image_transport_clients_[params_in_pixel.surface_handle]->size(); |
| 803 gfx::Size surface_size = ConvertSizeToDIP(this, | 851 gfx::Size surface_size = ConvertSizeToDIP(this, surface_size_in_pixel); |
| 804 surface_size_in_pixel); | |
| 805 window_->SchedulePaintInRect(gfx::Rect(surface_size)); | 852 window_->SchedulePaintInRect(gfx::Rect(surface_size)); |
| 806 | 853 |
| 807 if (!params_in_pixel.skip_ack) { | 854 if (!params_in_pixel.skip_ack) { |
| 808 if (!resize_locks_.empty()) { | 855 // Add sending an ACK to the list of things to do OnCompositingDidCommit |
| 809 // If we are waiting for the resize, fast-track the ACK. | 856 can_lock_compositor_ = NO_PENDING_COMMIT; |
| 810 if (compositor->IsThreaded()) { | 857 on_compositing_did_commit_callbacks_.push_back( |
| 811 // We need the compositor thread to pick up the active buffer before | 858 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, |
| 812 // ACKing. | 859 params_in_pixel.route_id, |
| 813 on_compositing_did_commit_callbacks_.push_back( | 860 gpu_host_id, |
| 814 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, | 861 true)); |
| 815 params_in_pixel.route_id, | 862 if (!compositor->HasObserver(this)) |
| 816 gpu_host_id)); | 863 compositor->AddObserver(this); |
| 817 if (!compositor->HasObserver(this)) | |
| 818 compositor->AddObserver(this); | |
| 819 } else { | |
| 820 // The compositor will pickup the active buffer during a draw, so we | |
| 821 // can ACK immediately. | |
| 822 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, | |
| 823 compositor); | |
| 824 } | |
| 825 } else { | |
| 826 // Add sending an ACK to the list of things to do OnCompositingWillStart | |
| 827 on_compositing_will_start_callbacks_.push_back( | |
| 828 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, | |
| 829 params_in_pixel.route_id, | |
| 830 gpu_host_id)); | |
| 831 if (!compositor->HasObserver(this)) | |
| 832 compositor->AddObserver(this); | |
| 833 } | |
| 834 } | 864 } |
| 835 } | 865 } |
| 836 } | 866 } |
| 837 | 867 |
| 838 void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer( | 868 void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer( |
| 839 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel, | 869 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel, |
| 840 int gpu_host_id) { | 870 int gpu_host_id) { |
| 841 surface_route_id_ = params_in_pixel.route_id; | 871 surface_route_id_ = params_in_pixel.route_id; |
| 842 // If visible state changed, then this PSB is stale. We must still ACK but | 872 // If visible state changed, then this PSB is stale. We must still ACK but |
| 843 // do not update current_surface_. | 873 // do not update current_surface_. |
| 844 if (params_in_pixel.protection_state_id && | 874 if (params_in_pixel.protection_state_id && |
| 845 params_in_pixel.protection_state_id != protection_state_id_) { | 875 params_in_pixel.protection_state_id != protection_state_id_) { |
| 846 DCHECK(!current_surface_); | 876 DCHECK(!current_surface_); |
| 847 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL); | 877 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL); |
| 848 return; | 878 return; |
| 849 } | 879 } |
| 850 current_surface_ = params_in_pixel.surface_handle; | |
| 851 released_front_lock_ = NULL; | |
| 852 DCHECK(current_surface_); | |
| 853 UpdateExternalTexture(); | |
| 854 | 880 |
| 855 ui::Compositor* compositor = GetCompositor(); | 881 ui::Compositor* compositor = GetCompositor(); |
| 856 if (!compositor) { | 882 if (!compositor || ShouldFastACK(params_in_pixel.surface_handle)) { |
| 857 // We have no compositor, so we have no way to display the surface | 883 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, |
| 858 // Must still send the ACK | 884 compositor); |
| 859 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, NULL); | |
| 860 } else { | 885 } else { |
| 886 current_surface_ = params_in_pixel.surface_handle; | |
| 887 released_front_lock_ = NULL; | |
| 888 DCHECK(current_surface_); | |
| 889 UpdateExternalTexture(); | |
| 861 DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) != | 890 DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) != |
| 862 image_transport_clients_.end()); | 891 image_transport_clients_.end()); |
| 863 gfx::Size surface_size_in_pixel = | 892 gfx::Size surface_size_in_pixel = |
| 864 image_transport_clients_[params_in_pixel.surface_handle]->size(); | 893 image_transport_clients_[params_in_pixel.surface_handle]->size(); |
| 865 | 894 |
| 866 // Co-ordinates come in OpenGL co-ordinate space. | 895 // Co-ordinates come in OpenGL co-ordinate space. |
| 867 // We need to convert to layer space. | 896 // We need to convert to layer space. |
| 868 gfx::Rect rect_to_paint = ConvertRectToDIP(this, gfx::Rect( | 897 gfx::Rect rect_to_paint = ConvertRectToDIP(this, gfx::Rect( |
| 869 params_in_pixel.x, | 898 params_in_pixel.x, |
| 870 surface_size_in_pixel.height() - params_in_pixel.y - | 899 surface_size_in_pixel.height() - params_in_pixel.y - |
| 871 params_in_pixel.height, | 900 params_in_pixel.height, |
| 872 params_in_pixel.width, | 901 params_in_pixel.width, |
| 873 params_in_pixel.height)); | 902 params_in_pixel.height)); |
| 874 | 903 |
| 875 // Damage may not have been DIP aligned, so inflate damage to compensate | 904 // Damage may not have been DIP aligned, so inflate damage to compensate |
| 876 // for any round-off error. | 905 // for any round-off error. |
| 877 rect_to_paint.Inset(-1, -1); | 906 rect_to_paint.Inset(-1, -1); |
| 878 rect_to_paint = rect_to_paint.Intersect(window_->bounds()); | 907 rect_to_paint = rect_to_paint.Intersect(window_->bounds()); |
| 879 | 908 |
| 880 window_->SchedulePaintInRect(rect_to_paint); | 909 window_->SchedulePaintInRect(rect_to_paint); |
| 881 | 910 |
| 882 if (!resize_locks_.empty()) { | 911 // Add sending an ACK to the list of things to do OnCompositingDidCommit |
| 883 // If we are waiting for the resize, fast-track the ACK. | 912 can_lock_compositor_ = NO_PENDING_COMMIT; |
| 884 if (compositor->IsThreaded()) { | 913 on_compositing_did_commit_callbacks_.push_back( |
| 885 // We need the compositor thread to pick up the active buffer before | 914 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, |
| 886 // ACKing. | 915 params_in_pixel.route_id, |
| 887 on_compositing_did_commit_callbacks_.push_back( | 916 gpu_host_id, |
| 888 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, | 917 true)); |
| 889 params_in_pixel.route_id, | 918 if (!compositor->HasObserver(this)) |
| 890 gpu_host_id)); | 919 compositor->AddObserver(this); |
| 891 if (!compositor->HasObserver(this)) | |
| 892 compositor->AddObserver(this); | |
| 893 } else { | |
| 894 // The compositor will pickup the active buffer during a draw, so we | |
| 895 // can ACK immediately. | |
| 896 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, | |
| 897 compositor); | |
| 898 } | |
| 899 } else { | |
| 900 // Add sending an ACK to the list of things to do OnCompositingWillStart | |
| 901 on_compositing_will_start_callbacks_.push_back( | |
| 902 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, | |
| 903 params_in_pixel.route_id, | |
| 904 gpu_host_id)); | |
| 905 if (!compositor->HasObserver(this)) | |
| 906 compositor->AddObserver(this); | |
| 907 } | |
| 908 } | 920 } |
| 909 } | 921 } |
| 910 | 922 |
| 911 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() { | 923 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() { |
| 912 } | 924 } |
| 913 | 925 |
| 914 bool RenderWidgetHostViewAura::HasAcceleratedSurface( | 926 bool RenderWidgetHostViewAura::HasAcceleratedSurface( |
| 915 const gfx::Size& desired_size) { | 927 const gfx::Size& desired_size) { |
| 916 // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't | 928 // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't |
| 917 // matter what is returned here as GetBackingStore is the only caller of this | 929 // matter what is returned here as GetBackingStore is the only caller of this |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1630 } | 1642 } |
| 1631 | 1643 |
| 1632 void RenderWidgetHostViewAura::OnLostActive() { | 1644 void RenderWidgetHostViewAura::OnLostActive() { |
| 1633 } | 1645 } |
| 1634 | 1646 |
| 1635 //////////////////////////////////////////////////////////////////////////////// | 1647 //////////////////////////////////////////////////////////////////////////////// |
| 1636 // RenderWidgetHostViewAura, ui::CompositorObserver implementation: | 1648 // RenderWidgetHostViewAura, ui::CompositorObserver implementation: |
| 1637 | 1649 |
| 1638 void RenderWidgetHostViewAura::OnCompositingDidCommit( | 1650 void RenderWidgetHostViewAura::OnCompositingDidCommit( |
| 1639 ui::Compositor* compositor) { | 1651 ui::Compositor* compositor) { |
| 1652 if (can_lock_compositor_ == NO_PENDING_COMMIT) { | |
| 1653 can_lock_compositor_ = YES; | |
| 1654 for (ResizeLockList::iterator it = resize_locks_.begin(); | |
| 1655 it != resize_locks_.end(); ++it) | |
| 1656 (*it)->GrabDeferredLock(); | |
|
piman
2012/10/17 21:26:32
should we set can_lock_compositor_ to YES_DID_LOCK
jonathan.backer
2012/10/18 20:20:35
Done.
| |
| 1657 } | |
| 1640 RunCompositingDidCommitCallbacks(compositor); | 1658 RunCompositingDidCommitCallbacks(compositor); |
| 1641 } | 1659 locks_pending_commit_.clear(); |
| 1642 | |
| 1643 void RenderWidgetHostViewAura::OnCompositingWillStart( | |
| 1644 ui::Compositor* compositor) { | |
| 1645 RunCompositingWillStartCallbacks(compositor); | |
| 1646 } | 1660 } |
| 1647 | 1661 |
| 1648 void RenderWidgetHostViewAura::OnCompositingStarted( | 1662 void RenderWidgetHostViewAura::OnCompositingStarted( |
| 1649 ui::Compositor* compositor) { | 1663 ui::Compositor* compositor) { |
| 1650 locks_pending_draw_.clear(); | |
| 1651 } | 1664 } |
| 1652 | 1665 |
| 1653 void RenderWidgetHostViewAura::OnCompositingEnded( | 1666 void RenderWidgetHostViewAura::OnCompositingEnded( |
| 1654 ui::Compositor* compositor) { | 1667 ui::Compositor* compositor) { |
| 1655 } | 1668 } |
| 1656 | 1669 |
| 1657 void RenderWidgetHostViewAura::OnCompositingAborted( | 1670 void RenderWidgetHostViewAura::OnCompositingAborted( |
| 1658 ui::Compositor* compositor) { | 1671 ui::Compositor* compositor) { |
| 1659 } | 1672 } |
| 1660 | 1673 |
| 1674 void RenderWidgetHostViewAura::OnCompositingLockStateChanged( | |
| 1675 ui::Compositor* compositor) { | |
| 1676 if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) { | |
|
piman
2012/10/17 21:26:32
It's worth a comment to point out that this happen
jonathan.backer
2012/10/18 20:20:35
Done.
| |
| 1677 can_lock_compositor_ = NO_PENDING_FRAME; | |
| 1678 } | |
| 1679 } | |
| 1680 | |
| 1661 //////////////////////////////////////////////////////////////////////////////// | 1681 //////////////////////////////////////////////////////////////////////////////// |
| 1662 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: | 1682 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: |
| 1663 | 1683 |
| 1664 void RenderWidgetHostViewAura::OnLostResources() { | 1684 void RenderWidgetHostViewAura::OnLostResources() { |
| 1665 image_transport_clients_.clear(); | 1685 image_transport_clients_.clear(); |
| 1666 current_surface_ = 0; | 1686 current_surface_ = 0; |
| 1667 protection_state_id_ = 0; | 1687 protection_state_id_ = 0; |
| 1668 current_surface_is_protected_ = true; | 1688 current_surface_is_protected_ = true; |
| 1669 current_surface_in_use_by_compositor_ = true; | 1689 current_surface_in_use_by_compositor_ = true; |
| 1670 surface_route_id_ = 0; | 1690 surface_route_id_ = 0; |
| 1671 UpdateExternalTexture(); | 1691 UpdateExternalTexture(); |
| 1672 locks_pending_draw_.clear(); | 1692 locks_pending_commit_.clear(); |
| 1673 | 1693 |
| 1674 DCHECK(!shared_surface_handle_.is_null()); | 1694 DCHECK(!shared_surface_handle_.is_null()); |
| 1675 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 1695 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
| 1676 factory->DestroySharedSurfaceHandle(shared_surface_handle_); | 1696 factory->DestroySharedSurfaceHandle(shared_surface_handle_); |
| 1677 shared_surface_handle_ = factory->CreateSharedSurfaceHandle(); | 1697 shared_surface_handle_ = factory->CreateSharedSurfaceHandle(); |
| 1678 host_->CompositingSurfaceUpdated(); | 1698 host_->CompositingSurfaceUpdated(); |
| 1679 host_->ScheduleComposite(); | 1699 host_->ScheduleComposite(); |
| 1680 } | 1700 } |
| 1681 | 1701 |
| 1682 //////////////////////////////////////////////////////////////////////////////// | 1702 //////////////////////////////////////////////////////////////////////////////// |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1808 void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks( | 1828 void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks( |
| 1809 ui::Compositor* compositor) { | 1829 ui::Compositor* compositor) { |
| 1810 for (std::vector< base::Callback<void(ui::Compositor*)> >::const_iterator | 1830 for (std::vector< base::Callback<void(ui::Compositor*)> >::const_iterator |
| 1811 it = on_compositing_did_commit_callbacks_.begin(); | 1831 it = on_compositing_did_commit_callbacks_.begin(); |
| 1812 it != on_compositing_did_commit_callbacks_.end(); ++it) { | 1832 it != on_compositing_did_commit_callbacks_.end(); ++it) { |
| 1813 it->Run(compositor); | 1833 it->Run(compositor); |
| 1814 } | 1834 } |
| 1815 on_compositing_did_commit_callbacks_.clear(); | 1835 on_compositing_did_commit_callbacks_.clear(); |
| 1816 } | 1836 } |
| 1817 | 1837 |
| 1818 void RenderWidgetHostViewAura::RunCompositingWillStartCallbacks( | |
| 1819 ui::Compositor* compositor) { | |
| 1820 for (std::vector< base::Callback<void(ui::Compositor*)> >::const_iterator | |
| 1821 it = on_compositing_will_start_callbacks_.begin(); | |
| 1822 it != on_compositing_will_start_callbacks_.end(); ++it) { | |
| 1823 it->Run(compositor); | |
| 1824 } | |
| 1825 on_compositing_will_start_callbacks_.clear(); | |
| 1826 } | |
| 1827 | |
| 1828 // static | 1838 // static |
| 1829 void RenderWidgetHostViewAura::InsertSyncPointAndACK( | 1839 void RenderWidgetHostViewAura::InsertSyncPointAndACK( |
| 1830 int32 route_id, int gpu_host_id, ui::Compositor* compositor) { | 1840 int32 route_id, int gpu_host_id, bool presented, |
| 1841 ui::Compositor* compositor) { | |
| 1831 uint32 sync_point = 0; | 1842 uint32 sync_point = 0; |
| 1832 // If we have no compositor, so we must still send the ACK. A zero | 1843 // If we have no compositor, so we must still send the ACK. A zero |
| 1833 // sync point will not be waited for in the GPU process. | 1844 // sync point will not be waited for in the GPU process. |
| 1834 if (compositor) { | 1845 if (compositor) { |
| 1835 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | 1846 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); |
| 1836 sync_point = factory->InsertSyncPoint(); | 1847 sync_point = factory->InsertSyncPoint(); |
| 1837 } | 1848 } |
| 1838 | 1849 |
| 1839 RenderWidgetHostImpl::AcknowledgeBufferPresent( | 1850 RenderWidgetHostImpl::AcknowledgeBufferPresent( |
| 1840 route_id, gpu_host_id, sync_point); | 1851 route_id, gpu_host_id, presented, sync_point); |
| 1841 } | 1852 } |
| 1842 | 1853 |
| 1843 void RenderWidgetHostViewAura::RemovingFromRootWindow() { | 1854 void RenderWidgetHostViewAura::RemovingFromRootWindow() { |
| 1844 // We are about to disconnect ourselves from the compositor, we need to issue | 1855 // We are about to disconnect ourselves from the compositor, we need to issue |
| 1845 // the callbacks now, because we won't get notified when the frame is done. | 1856 // the callbacks now, because we won't get notified when the frame is done. |
| 1846 // TODO(piman): this might in theory cause a race where the GPU process starts | 1857 // TODO(piman): this might in theory cause a race where the GPU process starts |
| 1847 // drawing to the buffer we haven't yet displayed. This will only show for 1 | 1858 // drawing to the buffer we haven't yet displayed. This will only show for 1 |
| 1848 // frame though, because we will reissue a new frame right away without that | 1859 // frame though, because we will reissue a new frame right away without that |
| 1849 // composited data. | 1860 // composited data. |
| 1850 ui::Compositor* compositor = GetCompositor(); | 1861 ui::Compositor* compositor = GetCompositor(); |
| 1851 RunCompositingDidCommitCallbacks(compositor); | 1862 RunCompositingDidCommitCallbacks(compositor); |
| 1852 RunCompositingWillStartCallbacks(compositor); | 1863 locks_pending_commit_.clear(); |
| 1853 locks_pending_draw_.clear(); | |
| 1854 if (compositor && compositor->HasObserver(this)) | 1864 if (compositor && compositor->HasObserver(this)) |
| 1855 compositor->RemoveObserver(this); | 1865 compositor->RemoveObserver(this); |
| 1856 DetachFromInputMethod(); | 1866 DetachFromInputMethod(); |
| 1857 } | 1867 } |
| 1858 | 1868 |
| 1859 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() { | 1869 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() { |
| 1860 aura::RootWindow* root_window = window_->GetRootWindow(); | 1870 aura::RootWindow* root_window = window_->GetRootWindow(); |
| 1861 return root_window ? root_window->compositor() : NULL; | 1871 return root_window ? root_window->compositor() : NULL; |
| 1862 } | 1872 } |
| 1863 | 1873 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1875 RenderWidgetHost* widget) { | 1885 RenderWidgetHost* widget) { |
| 1876 return new RenderWidgetHostViewAura(widget); | 1886 return new RenderWidgetHostViewAura(widget); |
| 1877 } | 1887 } |
| 1878 | 1888 |
| 1879 // static | 1889 // static |
| 1880 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) { | 1890 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) { |
| 1881 GetScreenInfoForWindow(results, NULL); | 1891 GetScreenInfoForWindow(results, NULL); |
| 1882 } | 1892 } |
| 1883 | 1893 |
| 1884 } // namespace content | 1894 } // namespace content |
| OLD | NEW |