Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / display_link_mac.cc
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.
4
5 #include "content/browser/renderer_host/display_link_mac.h"
6
7 #include "base/debug/trace_event.h"
8 #include "base/logging.h"
9
10 namespace base {
11
12 template<>
13 struct ScopedTypeRefTraits<CVDisplayLinkRef> {
14   static void Retain(CVDisplayLinkRef object) {
15     CVDisplayLinkRetain(object);
16   }
17   static void Release(CVDisplayLinkRef object) {
18     CVDisplayLinkRelease(object);
19   }
20 };
21
22 }  // namespace base
23
24 namespace content {
25
26 // static
27 scoped_refptr<DisplayLinkMac> DisplayLinkMac::Create() {
28   CVReturn ret = kCVReturnSuccess;
29
30   base::ScopedTypeRef<CVDisplayLinkRef> display_link;
31   ret = CVDisplayLinkCreateWithActiveCGDisplays(display_link.InitializeInto());
32   if (ret != kCVReturnSuccess) {
33     LOG(ERROR) << "CVDisplayLinkCreateWithActiveCGDisplays failed: " << ret;
34     return NULL;
35   }
36
37   scoped_refptr<DisplayLinkMac> display_link_mac;
38   display_link_mac = new DisplayLinkMac(display_link);
39
40   ret = CVDisplayLinkSetOutputCallback(
41       display_link_mac->display_link_,
42       &DisplayLinkCallback,
43       display_link_mac.get());
44   if (ret != kCVReturnSuccess) {
45     LOG(ERROR) << "CVDisplayLinkSetOutputCallback failed: " << ret;
46     return NULL;
47   }
48
49   return display_link_mac;
50 }
51
52 DisplayLinkMac::DisplayLinkMac(
53     base::ScopedTypeRef<CVDisplayLinkRef> display_link)
54       : display_link_(display_link),
55         stop_timer_(
56             FROM_HERE, base::TimeDelta::FromSeconds(1),
57             this, &DisplayLinkMac::StopDisplayLink),
58         timebase_and_interval_valid_(false) {
59 }
60
61 DisplayLinkMac::~DisplayLinkMac() {
62   if (CVDisplayLinkIsRunning(display_link_))
63     CVDisplayLinkStop(display_link_);
64 }
65
66 bool DisplayLinkMac::GetVSyncParameters(
67     base::TimeTicks* timebase, base::TimeDelta* interval) {
68   StartOrContinueDisplayLink();
69
70   base::AutoLock lock(lock_);
71   if (!timebase_and_interval_valid_)
72     return false;
73
74   *timebase = timebase_;
75   *interval = interval_;
76   return true;
77 }
78
79 void DisplayLinkMac::Tick(const CVTimeStamp* cv_time) {
80   TRACE_EVENT0("browser", "DisplayLinkMac::GetVSyncParameters");
81   base::AutoLock lock(lock_);
82
83   // Verify that videoRefreshPeriod is 32 bits.
84   DCHECK((cv_time->videoRefreshPeriod & ~0xffffFFFFull) == 0ull);
85
86   // Verify that the numerator and denominator make some sense.
87   uint32 numerator = static_cast<uint32>(cv_time->videoRefreshPeriod);
88   uint32 denominator = cv_time->videoTimeScale;
89   if (numerator <= 0 || denominator <= 0) {
90     LOG(WARNING) << "Unexpected numerator or denominator, bailing.";
91     return;
92   }
93
94   timebase_ = base::TimeTicks::FromInternalValue(
95       cv_time->hostTime / 1000);
96   interval_ = base::TimeDelta::FromMicroseconds(
97       1000000 * static_cast<int64>(numerator) / denominator);
98   timebase_and_interval_valid_ = true;
99 }
100
101 void DisplayLinkMac::StartOrContinueDisplayLink() {
102   // Reset the timer, so that the display link won't be turned off for another
103   // second.
104   stop_timer_.Reset();
105
106   if (CVDisplayLinkIsRunning(display_link_))
107     return;
108
109   CVReturn ret = CVDisplayLinkStart(display_link_);
110   if (ret != kCVReturnSuccess) {
111     LOG(ERROR) << "CVDisplayLinkStart failed: " << ret;
112   }
113 }
114
115 void DisplayLinkMac::StopDisplayLink() {
116   if (!CVDisplayLinkIsRunning(display_link_))
117     return;
118
119   CVReturn ret = CVDisplayLinkStop(display_link_);
120   if (ret != kCVReturnSuccess) {
121     LOG(ERROR) << "CVDisplayLinkStop failed: " << ret;
122   }
123 }
124
125 CVReturn DisplayLinkMac::DisplayLinkCallback(
126     CVDisplayLinkRef display_link,
127     const CVTimeStamp* now,
128     const CVTimeStamp* output_time,
129     CVOptionFlags flags_in,
130     CVOptionFlags* flags_out,
131     void* context) {
132   DisplayLinkMac* display_link_mac = static_cast<DisplayLinkMac*>(context);
133   display_link_mac->Tick(output_time);
134   return kCVReturnSuccess;
135 }
136
137 }  // content
138