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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_aura.cc

Issue 11194042: Implement TextureImageTransportSurface using texture mailbox (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased, fixed post sub buffer, use multiple mailbox names Created 8 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 in_shutdown_(false), 270 in_shutdown_(false),
271 is_fullscreen_(false), 271 is_fullscreen_(false),
272 popup_parent_host_view_(NULL), 272 popup_parent_host_view_(NULL),
273 popup_child_host_view_(NULL), 273 popup_child_host_view_(NULL),
274 is_loading_(false), 274 is_loading_(false),
275 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), 275 text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
276 can_compose_inline_(true), 276 can_compose_inline_(true),
277 has_composition_text_(false), 277 has_composition_text_(false),
278 device_scale_factor_(1.0f), 278 device_scale_factor_(1.0f),
279 current_surface_(0), 279 current_surface_(0),
280 current_surface_is_protected_(true),
281 current_surface_in_use_by_compositor_(true),
282 protection_state_id_(0),
283 surface_route_id_(0),
284 paint_canvas_(NULL), 280 paint_canvas_(NULL),
285 synthetic_move_sent_(false), 281 synthetic_move_sent_(false),
286 accelerated_compositing_state_changed_(false), 282 accelerated_compositing_state_changed_(false),
287 can_lock_compositor_(YES) { 283 can_lock_compositor_(YES) {
288 host_->SetView(this); 284 host_->SetView(this);
289 window_observer_.reset(new WindowObserver(this)); 285 window_observer_.reset(new WindowObserver(this));
290 window_->AddObserver(window_observer_.get()); 286 window_->AddObserver(window_observer_.get());
291 aura::client::SetTooltipText(window_, &tooltip_); 287 aura::client::SetTooltipText(window_, &tooltip_);
292 aura::client::SetActivationDelegate(window_, this); 288 aura::client::SetActivationDelegate(window_, this);
293 } 289 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 void RenderWidgetHostViewAura::WasShown() { 356 void RenderWidgetHostViewAura::WasShown() {
361 if (!host_->is_hidden()) 357 if (!host_->is_hidden())
362 return; 358 return;
363 host_->WasShown(); 359 host_->WasShown();
364 360
365 if (!current_surface_ && host_->is_accelerated_compositing_active() && 361 if (!current_surface_ && host_->is_accelerated_compositing_active() &&
366 !released_front_lock_.get()) { 362 !released_front_lock_.get()) {
367 released_front_lock_ = GetCompositor()->GetCompositorLock(); 363 released_front_lock_ = GetCompositor()->GetCompositorLock();
368 } 364 }
369 365
370 AdjustSurfaceProtection();
371
372 #if defined(OS_WIN) 366 #if defined(OS_WIN)
373 LPARAM lparam = reinterpret_cast<LPARAM>(this); 367 LPARAM lparam = reinterpret_cast<LPARAM>(this);
374 EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam); 368 EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam);
375 #endif 369 #endif
376 } 370 }
377 371
378 void RenderWidgetHostViewAura::WasHidden() { 372 void RenderWidgetHostViewAura::WasHidden() {
379 if (host_->is_hidden()) 373 if (host_->is_hidden())
380 return; 374 return;
381 host_->WasHidden(); 375 host_->WasHidden();
382 376
383 released_front_lock_ = NULL; 377 released_front_lock_ = NULL;
384 378
385 if (ShouldReleaseFrontSurface() &&
386 host_->is_accelerated_compositing_active()) {
387 current_surface_ = 0;
388 UpdateExternalTexture();
389 }
390
391 AdjustSurfaceProtection();
392
393 #if defined(OS_WIN) 379 #if defined(OS_WIN)
394 aura::RootWindow* root_window = window_->GetRootWindow(); 380 aura::RootWindow* root_window = window_->GetRootWindow();
395 if (root_window) { 381 if (root_window) {
396 HWND parent = root_window->GetAcceleratedWidget(); 382 HWND parent = root_window->GetAcceleratedWidget();
397 LPARAM lparam = reinterpret_cast<LPARAM>(this); 383 LPARAM lparam = reinterpret_cast<LPARAM>(this);
398 384
399 EnumChildWindows(parent, HideWindowsCallback, lparam); 385 EnumChildWindows(parent, HideWindowsCallback, lparam);
400 } 386 }
401 #endif 387 #endif
402 } 388 }
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 const gfx::Size& dst_size, 657 const gfx::Size& dst_size,
672 const base::Callback<void(bool)>& callback, 658 const base::Callback<void(bool)>& callback,
673 skia::PlatformBitmap* output) { 659 skia::PlatformBitmap* output) {
674 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); 660 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
675 661
676 std::map<uint64, scoped_refptr<ui::Texture> >::iterator it = 662 std::map<uint64, scoped_refptr<ui::Texture> >::iterator it =
677 image_transport_clients_.find(current_surface_); 663 image_transport_clients_.find(current_surface_);
678 if (it == image_transport_clients_.end()) 664 if (it == image_transport_clients_.end())
679 return; 665 return;
680 666
681 ui::Texture* container = it->second; 667 scoped_refptr<ui::Texture> container = it->second;
682 DCHECK(container); 668 DCHECK(container);
683 669
684 gfx::Size dst_size_in_pixel = ConvertSizeToPixel(this, dst_size); 670 gfx::Size dst_size_in_pixel = ConvertSizeToPixel(this, dst_size);
685 if (!output->Allocate( 671 if (!output->Allocate(
686 dst_size_in_pixel.width(), dst_size_in_pixel.height(), true)) 672 dst_size_in_pixel.width(), dst_size_in_pixel.height(), true))
687 return; 673 return;
688 674
689 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 675 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
690 GLHelper* gl_helper = factory->GetGLHelper(); 676 GLHelper* gl_helper = factory->GetGLHelper();
691 if (!gl_helper) 677 if (!gl_helper)
692 return; 678 return;
693 679
694 unsigned char* addr = static_cast<unsigned char*>( 680 unsigned char* addr = static_cast<unsigned char*>(
695 output->GetBitmap().getPixels()); 681 output->GetBitmap().getPixels());
696 scoped_callback_runner.Release(); 682 scoped_callback_runner.Release();
697 // Wrap the callback with an internal handler so that we can inject our 683 // Wrap the callback with an internal handler so that we can inject our
698 // own completion handlers (where we can call AdjustSurfaceProtection). 684 // own completion handlers (where we can try to free the frontbuffer).
699 base::Callback<void(bool)> wrapper_callback = base::Bind( 685 base::Callback<void(bool)> wrapper_callback = base::Bind(
700 &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished, 686 &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished,
701 AsWeakPtr(), 687 AsWeakPtr(),
702 callback); 688 callback,
689 container); // Hold a reference to the texture
piman 2012/11/09 22:02:01 I think we don't need this. By the time CropScaleR
no sievers 2012/11/19 20:30:44 Right it does the copy first on the UI thread. Rem
703 ++pending_thumbnail_tasks_; 690 ++pending_thumbnail_tasks_;
704 691
705 // Convert |src_subrect| from the views coordinate (upper-left origin) into 692 // Convert |src_subrect| from the views coordinate (upper-left origin) into
706 // the OpenGL coordinate (lower-left origin). 693 // the OpenGL coordinate (lower-left origin).
707 gfx::Rect src_subrect_in_gl = src_subrect; 694 gfx::Rect src_subrect_in_gl = src_subrect;
708 src_subrect_in_gl.set_y(GetViewBounds().height() - src_subrect.bottom()); 695 src_subrect_in_gl.set_y(GetViewBounds().height() - src_subrect.bottom());
709 696
710 gfx::Rect src_subrect_in_pixel = ConvertRectToPixel(this, src_subrect_in_gl); 697 gfx::Rect src_subrect_in_pixel = ConvertRectToPixel(this, src_subrect_in_gl);
711 gl_helper->CropScaleReadbackAndCleanTexture(container->PrepareTexture(), 698 gl_helper->CropScaleReadbackAndCleanTexture(container->PrepareTexture(),
712 container->size(), 699 container->size(),
713 src_subrect_in_pixel, 700 src_subrect_in_pixel,
714 dst_size_in_pixel, 701 dst_size_in_pixel,
715 addr, 702 addr,
716 wrapper_callback); 703 wrapper_callback);
717 } 704 }
718 705
719 void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() { 706 void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
720 // Delay processing the state change until we either get a software frame if 707 // Delay processing the state change until we either get a software frame if
721 // switching to software mode or receive a buffers swapped notification 708 // switching to software mode or receive a buffers swapped notification
722 // if switching to accelerated mode. 709 // if switching to accelerated mode.
723 // Sometimes (e.g. on a page load) the renderer will spuriously disable then 710 // Sometimes (e.g. on a page load) the renderer will spuriously disable then
724 // re-enable accelerated compositing, causing us to flash. 711 // re-enable accelerated compositing, causing us to flash.
725 // TODO(piman): factor the enable/disable accelerated compositing message into 712 // TODO(piman): factor the enable/disable accelerated compositing message into
726 // the UpdateRect/AcceleratedSurfaceBuffersSwapped messages so that we have 713 // the UpdateRect/AcceleratedSurfaceBuffersSwapped messages so that we have
727 // fewer inconsistent temporary states. 714 // fewer inconsistent temporary states.
728 accelerated_compositing_state_changed_ = true; 715 accelerated_compositing_state_changed_ = true;
729 } 716 }
730 717
731 bool RenderWidgetHostViewAura::ShouldFastACK(uint64 surface_id) { 718 bool RenderWidgetHostViewAura::ShouldFastACK(const gfx::Size& size) {
732 ui::Texture* container = image_transport_clients_[surface_id];
733 DCHECK(container);
734
735 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME || 719 if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
736 can_lock_compositor_ == NO_PENDING_COMMIT || 720 can_lock_compositor_ == NO_PENDING_COMMIT ||
737 resize_locks_.empty()) 721 resize_locks_.empty())
738 return false; 722 return false;
739 723
740 gfx::Size container_size = ConvertSizeToDIP(this, container->size()); 724 gfx::Size container_size = ConvertSizeToDIP(this, size);
741 ResizeLockList::iterator it = resize_locks_.begin(); 725 ResizeLockList::iterator it = resize_locks_.begin();
742 while (it != resize_locks_.end()) { 726 while (it != resize_locks_.end()) {
743 if ((*it)->expected_size() == container_size) 727 if ((*it)->expected_size() == container_size)
744 break; 728 break;
745 ++it; 729 ++it;
746 } 730 }
747 731
748 // We could be getting an unexpected frame due to an animation 732 // We could be getting an unexpected frame due to an animation
749 // (i.e. we start resizing but we get an old size frame first). 733 // (i.e. we start resizing but we get an old size frame first).
750 return it == resize_locks_.end() || ++it != resize_locks_.end(); 734 return it == resize_locks_.end() || ++it != resize_locks_.end();
751 } 735 }
752 736
753 void RenderWidgetHostViewAura::UpdateExternalTexture() { 737 void RenderWidgetHostViewAura::UpdateExternalTexture() {
754 // Delay processing accelerated compositing state change till here where we 738 // Delay processing accelerated compositing state change till here where we
755 // act upon the state change. (Clear the external texture if switching to 739 // act upon the state change. (Clear the external texture if switching to
756 // software mode or set the external texture if going to accelerated mode). 740 // software mode or set the external texture if going to accelerated mode).
757 if (accelerated_compositing_state_changed_) 741 if (accelerated_compositing_state_changed_)
758 accelerated_compositing_state_changed_ = false; 742 accelerated_compositing_state_changed_ = false;
759 743
760 if (current_surface_ != 0 && host_->is_accelerated_compositing_active()) { 744 if (current_surface_ != 0 && host_->is_accelerated_compositing_active()) {
761 ui::Texture* container = image_transport_clients_[current_surface_]; 745 ui::Texture* container = image_transport_clients_[current_surface_];
762 window_->SetExternalTexture(container); 746 window_->SetExternalTexture(container);
763 current_surface_in_use_by_compositor_ = true;
764 747
765 if (!container) { 748 if (!container) {
766 resize_locks_.clear(); 749 resize_locks_.clear();
767 } else { 750 } else {
768 ResizeLockList::iterator it = resize_locks_.begin(); 751 ResizeLockList::iterator it = resize_locks_.begin();
769 while (it != resize_locks_.end()) { 752 while (it != resize_locks_.end()) {
770 gfx::Size container_size = ConvertSizeToDIP(this, 753 gfx::Size container_size = ConvertSizeToDIP(this,
771 container->size()); 754 container->size());
772 if ((*it)->expected_size() == container_size) 755 if ((*it)->expected_size() == container_size)
773 break; 756 break;
(...skipping 15 matching lines...) Expand all
789 it2->get()->UnlockCompositor(); 772 it2->get()->UnlockCompositor();
790 } 773 }
791 if (!compositor->HasObserver(this)) 774 if (!compositor->HasObserver(this))
792 compositor->AddObserver(this); 775 compositor->AddObserver(this);
793 } 776 }
794 resize_locks_.erase(resize_locks_.begin(), it); 777 resize_locks_.erase(resize_locks_.begin(), it);
795 } 778 }
796 } 779 }
797 } else { 780 } else {
798 window_->SetExternalTexture(NULL); 781 window_->SetExternalTexture(NULL);
799 if (ShouldReleaseFrontSurface() &&
800 host_->is_accelerated_compositing_active()) {
801 // We need to wait for a commit to clear to guarantee that all we
802 // will not issue any more GL referencing the previous surface.
803 ui::Compositor* compositor = GetCompositor();
804 if (compositor) {
805 can_lock_compositor_ = NO_PENDING_COMMIT;
806 on_compositing_did_commit_callbacks_.push_back(
807 base::Bind(&RenderWidgetHostViewAura::
808 SetSurfaceNotInUseByCompositor,
809 AsWeakPtr()));
810 if (!compositor->HasObserver(this))
811 compositor->AddObserver(this);
812 }
813 }
814 resize_locks_.clear(); 782 resize_locks_.clear();
815 } 783 }
816 } 784 }
817 785
786 void RenderWidgetHostViewAura::SwapBuffersCompleted(
787 int gpu_host_id,
788 int route_id,
789 uint64 surface_handle,
790 scoped_refptr<ui::Texture> texture) {
791 ui::Compositor* compositor = GetCompositor();
792 if (!compositor) {
793 InsertSyncPointAndACK(route_id, gpu_host_id, surface_handle, texture);
794 } else {
795 // Add sending an ACK to the list of things to do OnCompositingDidCommit
796 can_lock_compositor_ = NO_PENDING_COMMIT;
797 on_compositing_did_commit_callbacks_.push_back(
798 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
799 route_id,
800 gpu_host_id,
801 surface_handle,
802 texture));
803 if (!compositor->HasObserver(this))
804 compositor->AddObserver(this);
805 }
806 }
807
818 void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped( 808 void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
819 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel, 809 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
820 int gpu_host_id) { 810 int gpu_host_id) {
821 surface_route_id_ = params_in_pixel.route_id; 811 const gfx::Rect surface_rect = gfx::Rect(gfx::Point(), params_in_pixel.size);
822 // If protection state changed, then this swap is stale. We must still ACK but 812 if (ShouldFastACK(params_in_pixel.size)) {
jonathan.backer 2012/11/12 16:52:15 I'm torn as to handle the detached (no compositor
no sievers 2012/11/19 20:30:44 When exactly would this happen? It sounds though l
piman 2012/11/19 22:09:52 When detached, there'll be no commit either since
piman 2012/11/19 22:31:54 GetCompositor() walks the window tree to find the
823 // do not update current_surface_ since it may have been discarded. 813 skipped_damage_ = UnionRects(skipped_damage_, surface_rect);
824 if (params_in_pixel.protection_state_id && 814 InsertSyncPointAndACK(params_in_pixel.route_id,
825 params_in_pixel.protection_state_id != protection_state_id_) { 815 gpu_host_id,
826 DCHECK(!current_surface_); 816 params_in_pixel.surface_handle,
827 if (!params_in_pixel.skip_ack) 817 NULL);
828 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL);
829 return; 818 return;
830 } 819 }
831 820
832 if (ShouldFastACK(params_in_pixel.surface_handle)) { 821 const uint64 previous_surface = current_surface_;
833 if (!params_in_pixel.skip_ack) 822 scoped_refptr<ui::Texture> texture_to_return;
834 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL); 823 if (previous_surface)
835 return; 824 texture_to_return = image_transport_clients_[previous_surface];
825
826 current_surface_ = params_in_pixel.surface_handle;
827 DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) !=
828 image_transport_clients_.end());
829
830 image_transport_clients_[current_surface_]->Consume(params_in_pixel.size);
831 released_front_lock_ = NULL;
832 UpdateExternalTexture();
833
834 previous_damage_rect_ = surface_rect;
835 if (!skipped_damage_.IsEmpty())
piman 2012/11/09 22:02:01 The test isn't useful, since you always end up wit
no sievers 2012/11/19 20:30:44 Done.
836 skipped_damage_ = gfx::Rect();
837
838 ui::Compositor* compositor = GetCompositor();
839 if (compositor) {
840 gfx::Size surface_size = ConvertSizeToDIP(this, params_in_pixel.size);
841 window_->SchedulePaintInRect(gfx::Rect(surface_size));
836 } 842 }
837 843
838 current_surface_ = params_in_pixel.surface_handle; 844 SwapBuffersCompleted(gpu_host_id,
839 // If we don't require an ACK that means the content is not a fresh updated 845 params_in_pixel.route_id,
840 // new frame, rather we are just resetting our handle to some old content 846 previous_surface,
841 // that we still hadn't discarded. Although we could display immediately, 847 texture_to_return);
842 // by not resetting the compositor lock here, we give us some time to get
843 // a fresh frame which means fewer content flashes.
844 if (!params_in_pixel.skip_ack)
845 released_front_lock_ = NULL;
846
847 UpdateExternalTexture();
848
849 ui::Compositor* compositor = GetCompositor();
850 if (!compositor) {
851 if (!params_in_pixel.skip_ack)
852 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, true, NULL);
853 } else {
854 DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) !=
855 image_transport_clients_.end());
856 gfx::Size surface_size_in_pixel =
857 image_transport_clients_[params_in_pixel.surface_handle]->size();
858 gfx::Size surface_size = ConvertSizeToDIP(this, surface_size_in_pixel);
859 window_->SchedulePaintInRect(gfx::Rect(surface_size));
860
861 if (!params_in_pixel.skip_ack) {
862 // Add sending an ACK to the list of things to do OnCompositingDidCommit
863 can_lock_compositor_ = NO_PENDING_COMMIT;
864 on_compositing_did_commit_callbacks_.push_back(
865 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK,
866 params_in_pixel.route_id,
867 gpu_host_id,
868 true));
869 if (!compositor->HasObserver(this))
870 compositor->AddObserver(this);
871 }
872 }
873 } 848 }
874 849
875 void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer( 850 void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
876 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel, 851 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
877 int gpu_host_id) { 852 int gpu_host_id) {
878 surface_route_id_ = params_in_pixel.route_id; 853 const gfx::Rect surface_rect =
879 // If visible state changed, then this PSB is stale. We must still ACK but 854 gfx::Rect(gfx::Point(), params_in_pixel.surface_size);
880 // do not update current_surface_. 855 gfx::Rect damage_rect(params_in_pixel.x,
881 if (params_in_pixel.protection_state_id && 856 params_in_pixel.y,
882 params_in_pixel.protection_state_id != protection_state_id_) { 857 params_in_pixel.width,
883 DCHECK(!current_surface_); 858 params_in_pixel.height);
884 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL); 859 if (ShouldFastACK(params_in_pixel.surface_size)) {
860 skipped_damage_ = UnionRects(skipped_damage_, damage_rect);
861 InsertSyncPointAndACK(params_in_pixel.route_id,
862 gpu_host_id,
863 params_in_pixel.surface_handle,
864 NULL);
885 return; 865 return;
886 } 866 }
887 867
888 if (ShouldFastACK(params_in_pixel.surface_handle)) { 868 const uint64 previous_surface = current_surface_;
889 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, false, NULL); 869 scoped_refptr<ui::Texture> texture_to_return;
890 return; 870 if (previous_surface)
871 texture_to_return = image_transport_clients_[previous_surface];
872
873 current_surface_ = params_in_pixel.surface_handle;
874 DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) !=
875 image_transport_clients_.end());
876
877 scoped_refptr<ui::Texture>& current_texture =
piman 2012/11/09 22:02:01 scoped_refptr<ui::Texture>& -> ui::Texture*? You'r
no sievers 2012/11/19 20:30:44 Done.
878 image_transport_clients_[current_surface_];
879 current_texture->Consume(params_in_pixel.surface_size);
880 released_front_lock_ = NULL;
881 UpdateExternalTexture();
882
883 if (!surface_rect.Contains(skipped_damage_)) {
884 // The surface could have shrunk since we skipped an update, in which
885 // case we can expect a full update.
886 DCHECK(damage_rect == surface_rect);
piman 2012/11/09 22:02:01 mmh, you're really asserting something that's comi
no sievers 2012/11/19 20:30:44 Done.
887 skipped_damage_ = gfx::Rect();
891 } 888 }
892 889
893 current_surface_ = params_in_pixel.surface_handle; 890 if (!skipped_damage_.IsEmpty()) {
894 released_front_lock_ = NULL; 891 damage_rect = UnionRects(skipped_damage_, damage_rect);
piman 2012/11/09 22:02:01 So the problem here (and when we union the skipped
jonathan.backer 2012/11/12 16:52:15 Good catch.
no sievers 2012/11/19 20:30:44 Done.
895 DCHECK(current_surface_); 892 skipped_damage_ = gfx::Rect();
896 UpdateExternalTexture(); 893 }
897 894
895 DCHECK(surface_rect.Contains(damage_rect));
898 ui::Compositor* compositor = GetCompositor(); 896 ui::Compositor* compositor = GetCompositor();
899 if (!compositor) { 897 if (compositor) {
piman 2012/11/09 22:02:01 I think you should do this always. At least the co
jonathan.backer 2012/11/12 16:52:15 As I've mentioned above, I have a slight preferenc
no sievers 2012/11/19 20:30:44 Done, I let it skip the frame if !GetCompositor().
900 InsertSyncPointAndACK(params_in_pixel.route_id, gpu_host_id, true, NULL); 898 const gfx::Size surface_size_in_pixel = params_in_pixel.surface_size;
901 } else { 899 DCHECK(!texture_to_return ||
902 DCHECK(image_transport_clients_.find(params_in_pixel.surface_handle) != 900 texture_to_return->size() == current_texture->size() ||
903 image_transport_clients_.end()); 901 damage_rect == surface_rect);
904 gfx::Size surface_size_in_pixel = 902 if (texture_to_return && !previous_damage_rect_.IsEmpty() &&
905 image_transport_clients_[params_in_pixel.surface_handle]->size(); 903 texture_to_return->size() == current_texture->size()) {
904 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
905 GLHelper* gl_helper = factory->GetGLHelper();
906 gl_helper->CopySubBufferDamage(current_texture->PrepareTexture(),
907 texture_to_return->PrepareTexture(),
908 damage_rect,
909 previous_damage_rect_);
jonathan.backer 2012/11/12 16:52:15 Which context is current here? Maybe it doesn't ma
no sievers 2012/11/19 20:30:44 Yes, the thumbnailer also uses the GLHelper and re
piman 2012/11/19 22:09:52 On the client side, makeContextCurrent is essentia
910 }
911 previous_damage_rect_ = damage_rect;
906 912
907 // Co-ordinates come in OpenGL co-ordinate space. 913 // Co-ordinates come in OpenGL co-ordinate space.
908 // We need to convert to layer space. 914 // We need to convert to layer space.
909 gfx::Rect rect_to_paint = ConvertRectToDIP(this, gfx::Rect( 915 gfx::Rect rect_to_paint = ConvertRectToDIP(this, gfx::Rect(
910 params_in_pixel.x, 916 params_in_pixel.x,
911 surface_size_in_pixel.height() - params_in_pixel.y - 917 surface_size_in_pixel.height() - params_in_pixel.y -
912 params_in_pixel.height, 918 params_in_pixel.height,
913 params_in_pixel.width, 919 params_in_pixel.width,
914 params_in_pixel.height)); 920 params_in_pixel.height));
915 921
916 // Damage may not have been DIP aligned, so inflate damage to compensate 922 // Damage may not have been DIP aligned, so inflate damage to compensate
917 // for any round-off error. 923 // for any round-off error.
918 rect_to_paint.Inset(-1, -1); 924 rect_to_paint.Inset(-1, -1);
919 rect_to_paint.Intersect(window_->bounds()); 925 rect_to_paint.Intersect(window_->bounds());
920 926
921 window_->SchedulePaintInRect(rect_to_paint); 927 window_->SchedulePaintInRect(rect_to_paint);
928 }
922 929
923 // Add sending an ACK to the list of things to do OnCompositingDidCommit 930 SwapBuffersCompleted(gpu_host_id,
924 can_lock_compositor_ = NO_PENDING_COMMIT; 931 params_in_pixel.route_id,
925 on_compositing_did_commit_callbacks_.push_back( 932 previous_surface,
926 base::Bind(&RenderWidgetHostViewAura::InsertSyncPointAndACK, 933 texture_to_return);
927 params_in_pixel.route_id,
928 gpu_host_id,
929 true));
930 if (!compositor->HasObserver(this))
931 compositor->AddObserver(this);
932 }
933 } 934 }
934 935
935 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() { 936 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
936 } 937 }
937 938
938 bool RenderWidgetHostViewAura::HasAcceleratedSurface( 939 bool RenderWidgetHostViewAura::HasAcceleratedSurface(
939 const gfx::Size& desired_size) { 940 const gfx::Size& desired_size) {
940 // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't 941 // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't
941 // matter what is returned here as GetBackingStore is the only caller of this 942 // matter what is returned here as GetBackingStore is the only caller of this
942 // method. TODO(jbates) implement this if other Aura code needs it. 943 // method. TODO(jbates) implement this if other Aura code needs it.
943 return false; 944 return false;
944 } 945 }
945 946
946 // TODO(backer): Drop the |shm_handle| once I remove some unused service side 947 // TODO(backer): Drop the |shm_handle| once I remove some unused service side
947 // code. 948 // code.
948 void RenderWidgetHostViewAura::AcceleratedSurfaceNew( 949 void RenderWidgetHostViewAura::AcceleratedSurfaceNew(
949 int32 width_in_pixel, 950 int32 width_in_pixel,
950 int32 height_in_pixel, 951 int32 height_in_pixel,
951 uint64 surface_handle) { 952 uint64 surface_handle,
953 const std::vector<signed char>& mailbox_name) {
952 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 954 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
953 scoped_refptr<ui::Texture> surface(factory->CreateTransportClient( 955 scoped_refptr<ui::Texture> surface(factory->CreateTransportClient(
954 gfx::Size(width_in_pixel, height_in_pixel), device_scale_factor_, 956 gfx::Size(width_in_pixel, height_in_pixel), device_scale_factor_,
955 surface_handle)); 957 mailbox_name));
956 if (!surface) { 958 if (!surface) {
957 LOG(ERROR) << "Failed to create ImageTransport texture"; 959 LOG(ERROR) << "Failed to create ImageTransport texture";
958 return; 960 return;
959 } 961 }
960
961 image_transport_clients_[surface_handle] = surface; 962 image_transport_clients_[surface_handle] = surface;
962 } 963 }
963 964
964 void RenderWidgetHostViewAura::AcceleratedSurfaceRelease( 965 void RenderWidgetHostViewAura::AcceleratedSurfaceRelease(
965 uint64 surface_handle) { 966 uint64 surface_handle) {
966 DCHECK(image_transport_clients_.find(surface_handle) != 967 // This really tells us to release the frontbuffer.
967 image_transport_clients_.end()); 968 if (current_surface_ && ShouldReleaseFrontSurface() &&
piman 2012/11/09 22:02:01 We should only do this if current_surface_==surfac
no sievers 2012/11/19 20:30:44 Well, I guess I changed the semantics of the messa
968 if (current_surface_ == surface_handle) { 969 host_->is_accelerated_compositing_active()) {
piman 2012/11/09 22:02:01 Why is this test needed? Note, it's almost positiv
no sievers 2012/11/19 20:30:44 Done.
970 ui::Compositor* compositor = GetCompositor();
971 if (compositor) {
972 // We need to wait for a commit to clear to guarantee that all we
973 // will not issue any more GL referencing the previous surface.
974 can_lock_compositor_ = NO_PENDING_COMMIT;
975 scoped_refptr<ui::Texture> surface_ref =
976 image_transport_clients_[surface_handle];
977 on_compositing_did_commit_callbacks_.push_back(
978 base::Bind(&RenderWidgetHostViewAura::
979 SetSurfaceNotInUseByCompositor,
980 AsWeakPtr(),
981 surface_ref));
982 if (!compositor->HasObserver(this))
983 compositor->AddObserver(this);
984 }
985 image_transport_clients_.erase(current_surface_);
piman 2012/11/09 22:02:01 This should still happen always
969 current_surface_ = 0; 986 current_surface_ = 0;
970 UpdateExternalTexture(); 987 UpdateExternalTexture();
971 } 988 }
972 image_transport_clients_.erase(surface_handle);
973 } 989 }
974 990
975 void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor(ui::Compositor*) { 991 void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor(
976 if (current_surface_ || !host_->is_hidden()) 992 scoped_refptr<ui::Texture>) {
977 return;
978 current_surface_in_use_by_compositor_ = false;
979 AdjustSurfaceProtection();
980 }
981
982 void RenderWidgetHostViewAura::AdjustSurfaceProtection() {
983 // If the current surface is non null, it is protected.
984 // If we are visible, it is protected.
985 // Otherwise, change to not proctected once done thumbnailing and compositing.
986 bool surface_is_protected =
987 current_surface_ ||
988 !host_->is_hidden() ||
989 (current_surface_is_protected_ &&
990 (pending_thumbnail_tasks_ > 0 ||
991 current_surface_in_use_by_compositor_));
992 if (current_surface_is_protected_ == surface_is_protected)
993 return;
994 current_surface_is_protected_ = surface_is_protected;
995 ++protection_state_id_;
996
997 if (!surface_route_id_ || !shared_surface_handle_.parent_gpu_process_id)
998 return;
999
1000 RenderWidgetHostImpl::SendFrontSurfaceIsProtected(
1001 surface_is_protected,
1002 protection_state_id_,
1003 surface_route_id_,
1004 shared_surface_handle_.parent_gpu_process_id);
1005 } 993 }
1006 994
1007 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished( 995 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished(
1008 base::WeakPtr<RenderWidgetHostViewAura> render_widget_host_view, 996 base::WeakPtr<RenderWidgetHostViewAura> render_widget_host_view,
1009 const base::Callback<void(bool)>& callback, 997 const base::Callback<void(bool)>& callback,
998 scoped_refptr<ui::Texture>,
1010 bool result) { 999 bool result) {
1011 callback.Run(result); 1000 callback.Run(result);
1012 1001
1013 if (!render_widget_host_view.get()) 1002 if (!render_widget_host_view.get())
1014 return; 1003 return;
1015 --render_widget_host_view->pending_thumbnail_tasks_; 1004 --render_widget_host_view->pending_thumbnail_tasks_;
1016 render_widget_host_view->AdjustSurfaceProtection();
1017 } 1005 }
1018 1006
1019 void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) { 1007 void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
1020 RenderWidgetHostViewBase::SetBackground(background); 1008 RenderWidgetHostViewBase::SetBackground(background);
1021 host_->SetBackground(background); 1009 host_->SetBackground(background);
1022 window_->layer()->SetFillsBoundsOpaquely(background.isOpaque()); 1010 window_->layer()->SetFillsBoundsOpaquely(background.isOpaque());
1023 } 1011 }
1024 1012
1025 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) { 1013 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) {
1026 GetScreenInfoForWindow(results, window_); 1014 GetScreenInfoForWindow(results, window_);
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 1675
1688 void RenderWidgetHostViewAura::OnCompositingDidCommit( 1676 void RenderWidgetHostViewAura::OnCompositingDidCommit(
1689 ui::Compositor* compositor) { 1677 ui::Compositor* compositor) {
1690 if (can_lock_compositor_ == NO_PENDING_COMMIT) { 1678 if (can_lock_compositor_ == NO_PENDING_COMMIT) {
1691 can_lock_compositor_ = YES; 1679 can_lock_compositor_ = YES;
1692 for (ResizeLockList::iterator it = resize_locks_.begin(); 1680 for (ResizeLockList::iterator it = resize_locks_.begin();
1693 it != resize_locks_.end(); ++it) 1681 it != resize_locks_.end(); ++it)
1694 if ((*it)->GrabDeferredLock()) 1682 if ((*it)->GrabDeferredLock())
1695 can_lock_compositor_ = YES_DID_LOCK; 1683 can_lock_compositor_ = YES_DID_LOCK;
1696 } 1684 }
1697 RunCompositingDidCommitCallbacks(compositor); 1685 RunCompositingDidCommitCallbacks();
1698 locks_pending_commit_.clear(); 1686 locks_pending_commit_.clear();
1699 } 1687 }
1700 1688
1701 void RenderWidgetHostViewAura::OnCompositingStarted( 1689 void RenderWidgetHostViewAura::OnCompositingStarted(
1702 ui::Compositor* compositor) { 1690 ui::Compositor* compositor) {
1703 } 1691 }
1704 1692
1705 void RenderWidgetHostViewAura::OnCompositingEnded( 1693 void RenderWidgetHostViewAura::OnCompositingEnded(
1706 ui::Compositor* compositor) { 1694 ui::Compositor* compositor) {
1707 } 1695 }
(...skipping 10 matching lines...) Expand all
1718 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME; 1706 can_lock_compositor_ = NO_PENDING_RENDERER_FRAME;
1719 } 1707 }
1720 } 1708 }
1721 1709
1722 //////////////////////////////////////////////////////////////////////////////// 1710 ////////////////////////////////////////////////////////////////////////////////
1723 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: 1711 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation:
1724 1712
1725 void RenderWidgetHostViewAura::OnLostResources() { 1713 void RenderWidgetHostViewAura::OnLostResources() {
1726 image_transport_clients_.clear(); 1714 image_transport_clients_.clear();
1727 current_surface_ = 0; 1715 current_surface_ = 0;
1728 protection_state_id_ = 0;
1729 current_surface_is_protected_ = true;
1730 current_surface_in_use_by_compositor_ = true;
1731 surface_route_id_ = 0;
1732 UpdateExternalTexture(); 1716 UpdateExternalTexture();
1733 locks_pending_commit_.clear(); 1717 locks_pending_commit_.clear();
1734 1718
1735 DCHECK(!shared_surface_handle_.is_null()); 1719 DCHECK(!shared_surface_handle_.is_null());
1736 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 1720 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1737 factory->DestroySharedSurfaceHandle(shared_surface_handle_); 1721 factory->DestroySharedSurfaceHandle(shared_surface_handle_);
1738 shared_surface_handle_ = factory->CreateSharedSurfaceHandle(); 1722 shared_surface_handle_ = factory->CreateSharedSurfaceHandle();
1739 host_->CompositingSurfaceUpdated(); 1723 host_->CompositingSurfaceUpdated();
1740 host_->ScheduleComposite(); 1724 host_->ScheduleComposite();
1741 } 1725 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 gfx::Rect rect = window_->bounds(); 1840 gfx::Rect rect = window_->bounds();
1857 int border_x = rect.width() * kMouseLockBorderPercentage / 100; 1841 int border_x = rect.width() * kMouseLockBorderPercentage / 100;
1858 int border_y = rect.height() * kMouseLockBorderPercentage / 100; 1842 int border_y = rect.height() * kMouseLockBorderPercentage / 100;
1859 1843
1860 return global_mouse_position_.x() < rect.x() + border_x || 1844 return global_mouse_position_.x() < rect.x() + border_x ||
1861 global_mouse_position_.x() > rect.right() - border_x || 1845 global_mouse_position_.x() > rect.right() - border_x ||
1862 global_mouse_position_.y() < rect.y() + border_y || 1846 global_mouse_position_.y() < rect.y() + border_y ||
1863 global_mouse_position_.y() > rect.bottom() - border_y; 1847 global_mouse_position_.y() > rect.bottom() - border_y;
1864 } 1848 }
1865 1849
1866 void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks( 1850 void RenderWidgetHostViewAura::RunCompositingDidCommitCallbacks() {
1867 ui::Compositor* compositor) { 1851 for (std::vector<base::Closure>::const_iterator
1868 for (std::vector< base::Callback<void(ui::Compositor*)> >::const_iterator
1869 it = on_compositing_did_commit_callbacks_.begin(); 1852 it = on_compositing_did_commit_callbacks_.begin();
1870 it != on_compositing_did_commit_callbacks_.end(); ++it) { 1853 it != on_compositing_did_commit_callbacks_.end(); ++it) {
1871 it->Run(compositor); 1854 it->Run();
1872 } 1855 }
1873 on_compositing_did_commit_callbacks_.clear(); 1856 on_compositing_did_commit_callbacks_.clear();
1874 } 1857 }
1875 1858
1876 // static 1859 // static
1877 void RenderWidgetHostViewAura::InsertSyncPointAndACK( 1860 void RenderWidgetHostViewAura::InsertSyncPointAndACK(
1878 int32 route_id, int gpu_host_id, bool presented, 1861 int32 route_id,
1879 ui::Compositor* compositor) { 1862 int gpu_host_id,
1863 uint64 surface_handle,
1864 scoped_refptr<ui::Texture> texture_to_produce) {
1865 if (texture_to_produce)
1866 texture_to_produce->Produce();
1867
1868 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1869
1880 uint32 sync_point = 0; 1870 uint32 sync_point = 0;
1881 // If we have no compositor, so we must still send the ACK. A zero 1871 // If we did at least consume a texture (not skipped a frame), we have
1882 // sync point will not be waited for in the GPU process. 1872 // to insert a sync point.
1883 if (compositor) { 1873 if (texture_to_produce || !surface_handle)
1884 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 1874 sync_point = factory->InsertSyncPoint();
1885 sync_point = factory->InsertSyncPoint();
1886 }
1887 1875
1888 RenderWidgetHostImpl::AcknowledgeBufferPresent( 1876 RenderWidgetHostImpl::AcknowledgeBufferPresent(
1889 route_id, gpu_host_id, presented, sync_point); 1877 route_id, gpu_host_id, surface_handle, sync_point);
1890 } 1878 }
1891 1879
1892 void RenderWidgetHostViewAura::AddingToRootWindow() { 1880 void RenderWidgetHostViewAura::AddingToRootWindow() {
1893 host_->ParentChanged(GetNativeViewId()); 1881 host_->ParentChanged(GetNativeViewId());
1894 } 1882 }
1895 1883
1896 void RenderWidgetHostViewAura::RemovingFromRootWindow() { 1884 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
1897 host_->ParentChanged(0); 1885 host_->ParentChanged(0);
1898 // We are about to disconnect ourselves from the compositor, we need to issue 1886 // We are about to disconnect ourselves from the compositor, we need to issue
1899 // the callbacks now, because we won't get notified when the frame is done. 1887 // the callbacks now, because we won't get notified when the frame is done.
1900 // TODO(piman): this might in theory cause a race where the GPU process starts 1888 // TODO(piman): this might in theory cause a race where the GPU process starts
1901 // drawing to the buffer we haven't yet displayed. This will only show for 1 1889 // drawing to the buffer we haven't yet displayed. This will only show for 1
1902 // frame though, because we will reissue a new frame right away without that 1890 // frame though, because we will reissue a new frame right away without that
1903 // composited data. 1891 // composited data.
1904 ui::Compositor* compositor = GetCompositor(); 1892 ui::Compositor* compositor = GetCompositor();
1905 RunCompositingDidCommitCallbacks(compositor); 1893 RunCompositingDidCommitCallbacks();
1906 locks_pending_commit_.clear(); 1894 locks_pending_commit_.clear();
1907 if (compositor && compositor->HasObserver(this)) 1895 if (compositor && compositor->HasObserver(this))
1908 compositor->RemoveObserver(this); 1896 compositor->RemoveObserver(this);
1909 DetachFromInputMethod(); 1897 DetachFromInputMethod();
1910 } 1898 }
1911 1899
1912 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() { 1900 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() {
1913 aura::RootWindow* root_window = window_->GetRootWindow(); 1901 aura::RootWindow* root_window = window_->GetRootWindow();
1914 return root_window ? root_window->compositor() : NULL; 1902 return root_window ? root_window->compositor() : NULL;
1915 } 1903 }
(...skipping 12 matching lines...) Expand all
1928 RenderWidgetHost* widget) { 1916 RenderWidgetHost* widget) {
1929 return new RenderWidgetHostViewAura(widget); 1917 return new RenderWidgetHostViewAura(widget);
1930 } 1918 }
1931 1919
1932 // static 1920 // static
1933 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) { 1921 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
1934 GetScreenInfoForWindow(results, NULL); 1922 GetScreenInfoForWindow(results, NULL);
1935 } 1923 }
1936 1924
1937 } // namespace content 1925 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698