summaryrefslogtreecommitdiff
path: root/hwc2/common/observers/SoftVsyncObserver.cpp (plain)
blob: 6347b8dcdfd7c4e93fe78ec2dbb9e793d514700e
1/*
2// Copyright (c) 2014 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16// This file is modified by Amlogic, Inc. 2017.01.17.
17*/
18
19#include <HwcTrace.h>
20#include <SoftVsyncObserver.h>
21#include <IDisplayDevice.h>
22
23extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
24 const struct timespec *request,
25 struct timespec *remain);
26
27
28namespace android {
29namespace amlogic {
30
31SoftVsyncObserver::SoftVsyncObserver(IDisplayDevice& disp)
32 : mDisplayDevice(disp),
33 mEnabled(false),
34 mRefreshRate(60), // default 60 frames per second
35 mRefreshPeriod(0),
36 mLock(),
37 mCondition(),
38 mNextFakeVSync(0),
39 mExitThread(false),
40 mInitialized(false)
41{
42}
43
44SoftVsyncObserver::~SoftVsyncObserver()
45{
46 WARN_IF_NOT_DEINIT();
47}
48
49bool SoftVsyncObserver::initialize()
50{
51 if (mInitialized) {
52 WTRACE("object has been initialized");
53 return true;
54 }
55
56 mExitThread = false;
57 mEnabled = false;
58 mRefreshRate = 60;
59 mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
60 mThread = new VsyncEventPollThread(this);
61 if (!mThread.get()) {
62 DEINIT_AND_RETURN_FALSE("failed to create vsync event poll thread.");
63 }
64 mThread->run("SoftVsyncObserver", PRIORITY_URGENT_DISPLAY);
65 mInitialized = true;
66 return true;
67}
68
69void SoftVsyncObserver::deinitialize()
70{
71 if (mEnabled) {
72 WTRACE("soft vsync is still enabled");
73 control(false);
74 }
75
76 mExitThread = true;
77 mCondition.signal();
78
79 if (mThread.get()) {
80 mThread->requestExitAndWait();
81 mThread = NULL;
82 }
83 mInitialized = false;
84}
85
86void SoftVsyncObserver::setRefreshRate(int rate)
87{
88 Mutex::Autolock _l(mLock);
89
90 if (rate < 1 || rate > 120) {
91 WTRACE("invalid refresh rate %d", rate);
92 } else if (mRefreshRate != rate) {
93 mRefreshRate = rate;
94 if (mEnabled) {
95 mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
96 mNextFakeVSync = systemTime(CLOCK_MONOTONIC) + mRefreshPeriod;
97 }
98 }
99}
100
101bool SoftVsyncObserver::control(bool enabled)
102{
103 Mutex::Autolock _l(mLock);
104
105 if (enabled == mEnabled) {
106 WTRACE("vsync state %d is not changed", enabled);
107 return true;
108 }
109
110 if (enabled) {
111 mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
112 mNextFakeVSync = systemTime(CLOCK_MONOTONIC) + mRefreshPeriod;
113 }
114 mEnabled = enabled;
115 mCondition.signal();
116 return true;
117}
118
119bool SoftVsyncObserver::threadLoop()
120{
121 { // scope for lock
122 Mutex::Autolock _l(mLock);
123 while (!mEnabled) {
124 mCondition.wait(mLock);
125 if (mExitThread) {
126 ITRACE("exiting thread loop");
127 return false;
128 }
129 }
130 }
131
132
133 const nsecs_t period = mRefreshPeriod;
134 const nsecs_t now = systemTime(CLOCK_MONOTONIC);
135 nsecs_t next_vsync = mNextFakeVSync;
136 nsecs_t sleep = next_vsync - now;
137 if (sleep < 0) {
138 // we missed, find where the next vsync should be
139 sleep = (period - ((now - next_vsync) % period));
140 next_vsync = now + sleep;
141 }
142 mNextFakeVSync = next_vsync + period;
143
144 struct timespec spec;
145 spec.tv_sec = next_vsync / 1000000000;
146 spec.tv_nsec = next_vsync % 1000000000;
147
148 int err;
149 do {
150 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
151 } while (err < 0 && errno == EINTR);
152
153
154 if (err == 0) {
155 mDisplayDevice.onVsync(next_vsync);
156 }
157
158 return true;
159}
160
161} // namespace amlogic
162} // namesapce android
163
164