| 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/compositing_iosurface_mac.h" | 5 #include "content/browser/renderer_host/compositing_iosurface_mac.h" |
| 6 | 6 |
| 7 #include <OpenGL/CGLRenderers.h> | 7 #include <OpenGL/CGLRenderers.h> |
| 8 #include <OpenGL/OpenGL.h> | 8 #include <OpenGL/OpenGL.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 texture_(0), | 273 texture_(0), |
| 274 finish_copy_timer_( | 274 finish_copy_timer_( |
| 275 FROM_HERE, | 275 FROM_HERE, |
| 276 base::TimeDelta::FromMilliseconds(kFinishCopyPollingPeriodMs), | 276 base::TimeDelta::FromMilliseconds(kFinishCopyPollingPeriodMs), |
| 277 base::Bind(&CompositingIOSurfaceMac::FinishAllCopies, | 277 base::Bind(&CompositingIOSurfaceMac::FinishAllCopies, |
| 278 base::Unretained(this)), | 278 base::Unretained(this)), |
| 279 true), | 279 true), |
| 280 display_link_(0), | 280 display_link_(0), |
| 281 display_link_stop_timer_(FROM_HERE, base::TimeDelta::FromSeconds(1), | 281 display_link_stop_timer_(FROM_HERE, base::TimeDelta::FromSeconds(1), |
| 282 this, &CompositingIOSurfaceMac::StopDisplayLink), | 282 this, &CompositingIOSurfaceMac::StopDisplayLink), |
| 283 vsync_count_(0), | |
| 284 swap_count_(0), | |
| 285 vsync_interval_numerator_(0), | 283 vsync_interval_numerator_(0), |
| 286 vsync_interval_denominator_(0), | 284 vsync_interval_denominator_(0), |
| 287 initialized_is_intel_(false), | 285 initialized_is_intel_(false), |
| 288 is_intel_(false), | 286 is_intel_(false), |
| 289 screen_(0) { | 287 screen_(0) { |
| 290 } | 288 } |
| 291 | 289 |
| 292 void CompositingIOSurfaceMac::SetupCVDisplayLink() { | 290 void CompositingIOSurfaceMac::SetupCVDisplayLink() { |
| 293 if (display_link_) { | 291 if (display_link_) { |
| 294 LOG(ERROR) << "DisplayLink already setup"; | 292 LOG(ERROR) << "DisplayLink already setup"; |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 | 556 |
| 559 if (!using_core_animation) | 557 if (!using_core_animation) |
| 560 CGLSetCurrentContext(0); | 558 CGLSetCurrentContext(0); |
| 561 | 559 |
| 562 if (!copy_done_callback.is_null()) | 560 if (!copy_done_callback.is_null()) |
| 563 copy_done_callbacks.push_back(copy_done_callback); | 561 copy_done_callbacks.push_back(copy_done_callback); |
| 564 for (size_t i = 0; i < copy_done_callbacks.size(); ++i) | 562 for (size_t i = 0; i < copy_done_callbacks.size(); ++i) |
| 565 copy_done_callbacks[i].Run(); | 563 copy_done_callbacks[i].Run(); |
| 566 | 564 |
| 567 StartOrContinueDisplayLink(); | 565 StartOrContinueDisplayLink(); |
| 568 | |
| 569 if (!is_vsync_disabled()) | |
| 570 RateLimitDraws(); | |
| 571 } | 566 } |
| 572 | 567 |
| 573 void CompositingIOSurfaceMac::CopyTo( | 568 void CompositingIOSurfaceMac::CopyTo( |
| 574 const gfx::Rect& src_pixel_subrect, | 569 const gfx::Rect& src_pixel_subrect, |
| 575 const gfx::Size& dst_pixel_size, | 570 const gfx::Size& dst_pixel_size, |
| 576 const base::Callback<void(bool, const SkBitmap&)>& callback) { | 571 const base::Callback<void(bool, const SkBitmap&)>& callback) { |
| 577 scoped_ptr<SkBitmap> output(new SkBitmap()); | 572 scoped_ptr<SkBitmap> output(new SkBitmap()); |
| 578 output->setConfig(SkBitmap::kARGB_8888_Config, | 573 output->setConfig(SkBitmap::kARGB_8888_Config, |
| 579 dst_pixel_size.width(), dst_pixel_size.height()); | 574 dst_pixel_size.width(), dst_pixel_size.height()); |
| 580 if (!output->allocPixels()) { | 575 if (!output->allocPixels()) { |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 | 728 |
| 734 void CompositingIOSurfaceMac::ClearDrawable() { | 729 void CompositingIOSurfaceMac::ClearDrawable() { |
| 735 [context_->nsgl_context() clearDrawable]; | 730 [context_->nsgl_context() clearDrawable]; |
| 736 UnrefIOSurface(); | 731 UnrefIOSurface(); |
| 737 } | 732 } |
| 738 | 733 |
| 739 void CompositingIOSurfaceMac::DisplayLinkTick(CVDisplayLinkRef display_link, | 734 void CompositingIOSurfaceMac::DisplayLinkTick(CVDisplayLinkRef display_link, |
| 740 const CVTimeStamp* time) { | 735 const CVTimeStamp* time) { |
| 741 TRACE_EVENT0("gpu", "CompositingIOSurfaceMac::DisplayLinkTick"); | 736 TRACE_EVENT0("gpu", "CompositingIOSurfaceMac::DisplayLinkTick"); |
| 742 base::AutoLock lock(lock_); | 737 base::AutoLock lock(lock_); |
| 743 // Increment vsync_count but don't let it get ahead of swap_count. | |
| 744 vsync_count_ = std::min(vsync_count_ + 1, swap_count_); | |
| 745 | |
| 746 CalculateVsyncParametersLockHeld(time); | 738 CalculateVsyncParametersLockHeld(time); |
| 747 } | 739 } |
| 748 | 740 |
| 749 void CompositingIOSurfaceMac::CalculateVsyncParametersLockHeld( | 741 void CompositingIOSurfaceMac::CalculateVsyncParametersLockHeld( |
| 750 const CVTimeStamp* time) { | 742 const CVTimeStamp* time) { |
| 751 lock_.AssertAcquired(); | 743 lock_.AssertAcquired(); |
| 752 vsync_interval_numerator_ = static_cast<uint32>(time->videoRefreshPeriod); | 744 vsync_interval_numerator_ = static_cast<uint32>(time->videoRefreshPeriod); |
| 753 vsync_interval_denominator_ = time->videoTimeScale; | 745 vsync_interval_denominator_ = time->videoTimeScale; |
| 754 // Verify that videoRefreshPeriod is 32 bits. | 746 // Verify that videoRefreshPeriod is 32 bits. |
| 755 DCHECK((time->videoRefreshPeriod & ~0xffffFFFFull) == 0ull); | 747 DCHECK((time->videoRefreshPeriod & ~0xffffFFFFull) == 0ull); |
| 756 | 748 |
| 757 vsync_timebase_ = | 749 vsync_timebase_ = |
| 758 base::TimeTicks::FromInternalValue(time->hostTime / 1000); | 750 base::TimeTicks::FromInternalValue(time->hostTime / 1000); |
| 759 } | 751 } |
| 760 | 752 |
| 761 void CompositingIOSurfaceMac::RateLimitDraws() { | |
| 762 int64 vsync_count; | |
| 763 int64 swap_count; | |
| 764 | |
| 765 { | |
| 766 base::AutoLock lock(lock_); | |
| 767 vsync_count = vsync_count_; | |
| 768 swap_count = ++swap_count_; | |
| 769 } | |
| 770 | |
| 771 // It's OK for swap_count to get 2 ahead of vsync_count, but any more | |
| 772 // indicates that it has become unthrottled. This happens when, for example, | |
| 773 // the window is obscured by another opaque window. | |
| 774 if (swap_count > vsync_count + 2) { | |
| 775 TRACE_EVENT0("gpu", "CompositingIOSurfaceMac::RateLimitDraws"); | |
| 776 // Sleep for one vsync interval. This will prevent spinning while the window | |
| 777 // is not visible, but will also allow quick recovery when the window | |
| 778 // becomes visible again. | |
| 779 int64 sleep_us = 16666; // default to 60hz if display link API fails. | |
| 780 if (vsync_interval_denominator_ > 0) { | |
| 781 sleep_us = (static_cast<int64>(vsync_interval_numerator_) * 1000000) / | |
| 782 vsync_interval_denominator_; | |
| 783 } | |
| 784 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(sleep_us)); | |
| 785 } | |
| 786 } | |
| 787 | |
| 788 void CompositingIOSurfaceMac::StartOrContinueDisplayLink() { | 753 void CompositingIOSurfaceMac::StartOrContinueDisplayLink() { |
| 789 if (display_link_ == NULL) | 754 if (display_link_ == NULL) |
| 790 return; | 755 return; |
| 791 | 756 |
| 792 if (!CVDisplayLinkIsRunning(display_link_)) { | 757 if (!CVDisplayLinkIsRunning(display_link_)) { |
| 793 vsync_count_ = swap_count_ = 0; | |
| 794 CVDisplayLinkStart(display_link_); | 758 CVDisplayLinkStart(display_link_); |
| 795 } | 759 } |
| 796 display_link_stop_timer_.Reset(); | 760 display_link_stop_timer_.Reset(); |
| 797 } | 761 } |
| 798 | 762 |
| 799 void CompositingIOSurfaceMac::StopDisplayLink() { | 763 void CompositingIOSurfaceMac::StopDisplayLink() { |
| 800 if (display_link_ == NULL) | 764 if (display_link_ == NULL) |
| 801 return; | 765 return; |
| 802 | 766 |
| 803 if (CVDisplayLinkIsRunning(display_link_)) | 767 if (CVDisplayLinkIsRunning(display_link_)) |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 } | 1070 } |
| 1107 } | 1071 } |
| 1108 | 1072 |
| 1109 gfx::Rect CompositingIOSurfaceMac::IntersectWithIOSurface( | 1073 gfx::Rect CompositingIOSurfaceMac::IntersectWithIOSurface( |
| 1110 const gfx::Rect& rect) const { | 1074 const gfx::Rect& rect) const { |
| 1111 return gfx::IntersectRects(rect, | 1075 return gfx::IntersectRects(rect, |
| 1112 gfx::ToEnclosingRect(gfx::Rect(pixel_io_surface_size_))); | 1076 gfx::ToEnclosingRect(gfx::Rect(pixel_io_surface_size_))); |
| 1113 } | 1077 } |
| 1114 | 1078 |
| 1115 } // namespace content | 1079 } // namespace content |
| OLD | NEW |