Service Worker: Release controllees upon activation failure.
[chromium-blink-merge.git] / content / browser / renderer_host / display_link_mac.cc
blobfbbcf3756480ea47cc2301ab3b6be540438c151d
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/display_link_mac.h"
7 #include "base/logging.h"
8 #include "base/trace_event/trace_event.h"
10 namespace base {
12 template<>
13 struct ScopedTypeRefTraits<CVDisplayLinkRef> {
14 static void Retain(CVDisplayLinkRef object) {
15 CVDisplayLinkRetain(object);
17 static void Release(CVDisplayLinkRef object) {
18 CVDisplayLinkRelease(object);
22 } // namespace base
24 namespace content {
26 // static
27 scoped_refptr<DisplayLinkMac> DisplayLinkMac::GetForDisplay(
28 CGDirectDisplayID display_id) {
29 // Return the existing display link for this display, if it exists.
30 DisplayMap::iterator found = display_map_.Get().find(display_id);
31 if (found != display_map_.Get().end()) {
32 return found->second;
35 CVReturn ret = kCVReturnSuccess;
37 base::ScopedTypeRef<CVDisplayLinkRef> display_link;
38 ret = CVDisplayLinkCreateWithCGDisplay(
39 display_id,
40 display_link.InitializeInto());
41 if (ret != kCVReturnSuccess) {
42 LOG(ERROR) << "CVDisplayLinkCreateWithActiveCGDisplays failed: " << ret;
43 return NULL;
46 scoped_refptr<DisplayLinkMac> display_link_mac;
47 display_link_mac = new DisplayLinkMac(display_id, display_link);
49 ret = CVDisplayLinkSetOutputCallback(
50 display_link_mac->display_link_,
51 &DisplayLinkCallback,
52 display_link_mac.get());
53 if (ret != kCVReturnSuccess) {
54 LOG(ERROR) << "CVDisplayLinkSetOutputCallback failed: " << ret;
55 return NULL;
58 return display_link_mac;
61 DisplayLinkMac::DisplayLinkMac(
62 CGDirectDisplayID display_id,
63 base::ScopedTypeRef<CVDisplayLinkRef> display_link)
64 : display_id_(display_id),
65 display_link_(display_link),
66 stop_timer_(
67 FROM_HERE, base::TimeDelta::FromSeconds(1),
68 this, &DisplayLinkMac::StopDisplayLink),
69 timebase_and_interval_valid_(false) {
70 DCHECK(display_map_.Get().find(display_id) == display_map_.Get().end());
71 display_map_.Get().insert(std::make_pair(display_id_, this));
74 DisplayLinkMac::~DisplayLinkMac() {
75 if (CVDisplayLinkIsRunning(display_link_))
76 CVDisplayLinkStop(display_link_);
78 DisplayMap::iterator found = display_map_.Get().find(display_id_);
79 DCHECK(found != display_map_.Get().end());
80 DCHECK(found->second == this);
81 display_map_.Get().erase(found);
84 bool DisplayLinkMac::GetVSyncParameters(
85 base::TimeTicks* timebase, base::TimeDelta* interval) {
86 StartOrContinueDisplayLink();
88 base::AutoLock lock(lock_);
89 if (!timebase_and_interval_valid_)
90 return false;
92 *timebase = timebase_;
93 *interval = interval_;
94 return true;
97 void DisplayLinkMac::Tick(const CVTimeStamp* cv_time) {
98 TRACE_EVENT0("browser", "DisplayLinkMac::GetVSyncParameters");
99 base::AutoLock lock(lock_);
101 // Verify that videoRefreshPeriod is 32 bits.
102 DCHECK((cv_time->videoRefreshPeriod & ~0xffffFFFFull) == 0ull);
104 // Verify that the numerator and denominator make some sense.
105 uint32 numerator = static_cast<uint32>(cv_time->videoRefreshPeriod);
106 uint32 denominator = cv_time->videoTimeScale;
107 if (numerator <= 0 || denominator <= 0) {
108 LOG(WARNING) << "Unexpected numerator or denominator, bailing.";
109 return;
112 timebase_ = base::TimeTicks::FromInternalValue(
113 cv_time->hostTime / 1000);
114 interval_ = base::TimeDelta::FromMicroseconds(
115 1000000 * static_cast<int64>(numerator) / denominator);
116 timebase_and_interval_valid_ = true;
119 void DisplayLinkMac::StartOrContinueDisplayLink() {
120 // Reset the timer, so that the display link won't be turned off for another
121 // second.
122 stop_timer_.Reset();
124 if (CVDisplayLinkIsRunning(display_link_))
125 return;
127 CVReturn ret = CVDisplayLinkStart(display_link_);
128 if (ret != kCVReturnSuccess) {
129 LOG(ERROR) << "CVDisplayLinkStart failed: " << ret;
133 void DisplayLinkMac::StopDisplayLink() {
134 if (!CVDisplayLinkIsRunning(display_link_))
135 return;
137 CVReturn ret = CVDisplayLinkStop(display_link_);
138 if (ret != kCVReturnSuccess) {
139 LOG(ERROR) << "CVDisplayLinkStop failed: " << ret;
143 CVReturn DisplayLinkMac::DisplayLinkCallback(
144 CVDisplayLinkRef display_link,
145 const CVTimeStamp* now,
146 const CVTimeStamp* output_time,
147 CVOptionFlags flags_in,
148 CVOptionFlags* flags_out,
149 void* context) {
150 DisplayLinkMac* display_link_mac = static_cast<DisplayLinkMac*>(context);
151 display_link_mac->Tick(output_time);
152 return kCVReturnSuccess;
155 // static
156 base::LazyInstance<DisplayLinkMac::DisplayMap>
157 DisplayLinkMac::display_map_ = LAZY_INSTANCE_INITIALIZER;
159 } // content