• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include <HwcTrace.h>
18 #include <IDisplayDevice.h>
19 #include <DisplayQuery.h>
20 #include <BufferManager.h>
21 #include <DisplayPlaneManager.h>
22 #include <Hwcomposer.h>
23 #include <VsyncManager.h>
24 
25 
26 namespace android {
27 namespace intel {
28 
VsyncManager(Hwcomposer & hwc)29 VsyncManager::VsyncManager(Hwcomposer &hwc)
30      :mHwc(hwc),
31       mInitialized(false),
32       mEnableDynamicVsync(true),
33       mEnabled(false),
34       mVsyncSource(IDisplayDevice::DEVICE_COUNT),
35       mLock()
36 {
37 }
38 
~VsyncManager()39 VsyncManager::~VsyncManager()
40 {
41     WARN_IF_NOT_DEINIT();
42 }
43 
initialize()44 bool VsyncManager::initialize()
45 {
46 
47     mEnabled = false;
48     mVsyncSource = IDisplayDevice::DEVICE_COUNT;
49     mEnableDynamicVsync = !scUsePrimaryVsyncOnly;
50     mInitialized = true;
51     return true;
52 }
53 
deinitialize()54 void VsyncManager::deinitialize()
55 {
56     if (mEnabled) {
57         WTRACE("vsync is still enabled");
58     }
59 
60     mVsyncSource = IDisplayDevice::DEVICE_COUNT;
61     mEnabled = false;
62     mEnableDynamicVsync = !scUsePrimaryVsyncOnly;
63     mInitialized = false;
64 }
65 
handleVsyncControl(int disp,bool enabled)66 bool VsyncManager::handleVsyncControl(int disp, bool enabled)
67 {
68     Mutex::Autolock l(mLock);
69 
70     if (disp != IDisplayDevice::DEVICE_PRIMARY) {
71         WTRACE("vsync control on non-primary device %d", disp);
72         return false;
73     }
74 
75     if (mEnabled == enabled) {
76         WTRACE("vsync state %d is not changed", enabled);
77         return true;
78     }
79 
80     if (!enabled) {
81         disableVsync();
82         mEnabled = false;
83         return true;
84     } else {
85         mEnabled = enableVsync(getCandidate());
86         return mEnabled;
87     }
88 
89     return false;
90 }
91 
resetVsyncSource()92 void VsyncManager::resetVsyncSource()
93 {
94     Mutex::Autolock l(mLock);
95 
96     if (!mEnableDynamicVsync) {
97         ITRACE("dynamic vsync source switch is not supported");
98         return;
99     }
100 
101     if (!mEnabled) {
102         return;
103     }
104 
105     int vsyncSource = getCandidate();
106     if (vsyncSource == mVsyncSource) {
107         return;
108     }
109 
110     disableVsync();
111     enableVsync(vsyncSource);
112 }
113 
getVsyncSource()114 int VsyncManager::getVsyncSource()
115 {
116     return mVsyncSource;
117 }
118 
enableDynamicVsync(bool enable)119 void VsyncManager::enableDynamicVsync(bool enable)
120 {
121     Mutex::Autolock l(mLock);
122     if (scUsePrimaryVsyncOnly) {
123         WTRACE("dynamic vsync is not supported");
124         return;
125     }
126 
127     mEnableDynamicVsync = enable;
128 
129     if (!mEnabled) {
130         return;
131     }
132 
133     int vsyncSource = getCandidate();
134     if (vsyncSource == mVsyncSource) {
135         return;
136     }
137 
138     disableVsync();
139     enableVsync(vsyncSource);
140 }
141 
getDisplayDevice(int dispType)142 IDisplayDevice* VsyncManager::getDisplayDevice(int dispType ) {
143     return mHwc.getDisplayDevice(dispType);
144 }
145 
getCandidate()146 int VsyncManager::getCandidate()
147 {
148     if (!mEnableDynamicVsync) {
149         return IDisplayDevice::DEVICE_PRIMARY;
150     }
151 
152     IDisplayDevice *device = NULL;
153     // use HDMI vsync when connected
154     device = getDisplayDevice(IDisplayDevice::DEVICE_EXTERNAL);
155     if (device && device->isConnected()) {
156         return IDisplayDevice::DEVICE_EXTERNAL;
157     }
158 
159 #ifdef INTEL_WIDI_MERRIFIELD
160     // use vsync from virtual display when video extended mode is entered
161     if (Hwcomposer::getInstance().getDisplayAnalyzer()->isVideoExtModeActive()) {
162         device = getDisplayDevice(IDisplayDevice::DEVICE_VIRTUAL);
163         if (device && device->isConnected()) {
164             return IDisplayDevice::DEVICE_VIRTUAL;
165         }
166         WTRACE("Could not use vsync from secondary device");
167     }
168 #endif
169     return IDisplayDevice::DEVICE_PRIMARY;
170 }
171 
enableVsync(int candidate)172 bool VsyncManager::enableVsync(int candidate)
173 {
174     if (mVsyncSource != IDisplayDevice::DEVICE_COUNT) {
175         WTRACE("vsync has been enabled on %d", mVsyncSource);
176         return true;
177     }
178 
179     IDisplayDevice *device = getDisplayDevice(candidate);
180     if (!device) {
181         ETRACE("invalid vsync source candidate %d", candidate);
182         return false;
183     }
184 
185     if (device->vsyncControl(true)) {
186         mVsyncSource = candidate;
187         return true;
188     }
189 
190     if (candidate != IDisplayDevice::DEVICE_PRIMARY) {
191         WTRACE("failed to enable vsync on display %d, fall back to primary", candidate);
192         device = getDisplayDevice(IDisplayDevice::DEVICE_PRIMARY);
193         if (device && device->vsyncControl(true)) {
194             mVsyncSource = IDisplayDevice::DEVICE_PRIMARY;
195             return true;
196         }
197     }
198     ETRACE("failed to enable vsync on the primary display");
199     return false;
200 }
201 
disableVsync()202 void VsyncManager::disableVsync()
203 {
204     if (mVsyncSource == IDisplayDevice::DEVICE_COUNT) {
205         WTRACE("vsync has been disabled");
206         return;
207     }
208 
209     IDisplayDevice *device = getDisplayDevice(mVsyncSource);
210     if (device && !device->vsyncControl(false)) {
211         WTRACE("failed to disable vsync on device %d", mVsyncSource);
212     }
213     mVsyncSource = IDisplayDevice::DEVICE_COUNT;
214 }
215 
216 } // namespace intel
217 } // namespace android
218 
219