• 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 #include <HwcTrace.h>
17 #include <VsyncEventObserver.h>
18 #include <PhysicalDevice.h>
19 
20 namespace android {
21 namespace intel {
22 
VsyncEventObserver(PhysicalDevice & disp)23 VsyncEventObserver::VsyncEventObserver(PhysicalDevice& disp)
24     : mLock(),
25       mCondition(),
26       mDisplayDevice(disp),
27       mVsyncControl(NULL),
28       mDevice(IDisplayDevice::DEVICE_COUNT),
29       mEnabled(false),
30       mExitThread(false),
31       mInitialized(false),
32       mFpsCounter(0)
33 {
34     CTRACE();
35 }
36 
~VsyncEventObserver()37 VsyncEventObserver::~VsyncEventObserver()
38 {
39     WARN_IF_NOT_DEINIT();
40 }
41 
initialize()42 bool VsyncEventObserver::initialize()
43 {
44     if (mInitialized) {
45         WTRACE("object has been initialized");
46         return true;
47     }
48 
49     mExitThread = false;
50     mEnabled = false;
51     mDevice = mDisplayDevice.getType();
52     mVsyncControl = mDisplayDevice.createVsyncControl();
53     if (!mVsyncControl || !mVsyncControl->initialize()) {
54         DEINIT_AND_RETURN_FALSE("failed to initialize vsync control");
55     }
56 
57     mThread = new VsyncEventPollThread(this);
58     if (!mThread.get()) {
59         DEINIT_AND_RETURN_FALSE("failed to create vsync event poll thread.");
60     }
61 
62     mThread->run("VsyncEventObserver", PRIORITY_URGENT_DISPLAY);
63 
64     mInitialized = true;
65     return true;
66 }
67 
deinitialize()68 void VsyncEventObserver::deinitialize()
69 {
70     if (mEnabled) {
71         WTRACE("vsync is still enabled");
72         control(false);
73     }
74     mInitialized = false;
75     mExitThread = true;
76     mEnabled = false;
77     mCondition.signal();
78 
79     if (mThread.get()) {
80         mThread->requestExitAndWait();
81         mThread = NULL;
82     }
83 
84     DEINIT_AND_DELETE_OBJ(mVsyncControl);
85 }
86 
control(bool enabled)87 bool VsyncEventObserver::control(bool enabled)
88 {
89     ATRACE("enabled = %d on device %d", enabled, mDevice);
90     if (enabled == mEnabled) {
91         WTRACE("vsync state %d is not changed", enabled);
92         return true;
93     }
94 
95     Mutex::Autolock _l(mLock);
96     bool ret = mVsyncControl->control(mDevice, enabled);
97     if (!ret) {
98         ETRACE("failed to control (%d) vsync on display %d", enabled, mDevice);
99         return false;
100     }
101 
102     mEnabled = enabled;
103     mCondition.signal();
104     return true;
105 }
106 
threadLoop()107 bool VsyncEventObserver::threadLoop()
108 {
109     do {
110         // scope for lock
111         Mutex::Autolock _l(mLock);
112         while (!mEnabled) {
113             mCondition.wait(mLock);
114             if (mExitThread) {
115                 ITRACE("exiting thread loop");
116                 return false;
117             }
118         }
119     } while (0);
120 
121     if(mEnabled && mDisplayDevice.isConnected()) {
122         int64_t timestamp;
123         bool ret = mVsyncControl->wait(mDevice, timestamp);
124         if (ret == false) {
125             WTRACE("failed to wait for vsync on display %d, vsync enabled %d", mDevice, mEnabled);
126             usleep(16000);
127             return true;
128         }
129 
130         // send vsync event notification every hwc.fps_divider
131         if ((mFpsCounter++) % mDisplayDevice.getFpsDivider() == 0)
132             mDisplayDevice.onVsync(timestamp);
133     }
134 
135     return true;
136 }
137 
138 } // namespace intel
139 } // namesapce android
140