16a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu/*
2cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// Copyright (c) 2014 Intel Corporation 
3cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika//
4cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// Licensed under the Apache License, Version 2.0 (the "License");
5cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// you may not use this file except in compliance with the License.
6cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// You may obtain a copy of the License at
7cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika//
8cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika//      http://www.apache.org/licenses/LICENSE-2.0
9cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika//
10cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// Unless required by applicable law or agreed to in writing, software
11cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// distributed under the License is distributed on an "AS IS" BASIS,
12cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// See the License for the specific language governing permissions and
14cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika// limitations under the License.
15cd727f537d5085eec7f1b8f9c1d33922d4de75d4Prodyut Hazarika*/
160594c42af26255fd8d3d7d39c0cb0e2da5b8841bThierry Strudel#include <common/utils/HwcTrace.h>
170594c42af26255fd8d3d7d39c0cb0e2da5b8841bThierry Strudel#include <common/observers/VsyncEventObserver.h>
188a427146c6f68f9add960bbd18c4f84c9eeee4a5Andy Qiu#include <PhysicalDevice.h>
196a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
206a6081a46a83da606cf21548879b37695adc7e1fAndy Qiunamespace android {
216a6081a46a83da606cf21548879b37695adc7e1fAndy Qiunamespace intel {
226a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
23eb726af21649d79ed720bdf329e0849270995c45Andy QiuVsyncEventObserver::VsyncEventObserver(PhysicalDevice& disp)
24eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    : mLock(),
25eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mCondition(),
26eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mDisplayDevice(disp),
27eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mVsyncControl(NULL),
28eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mDevice(IDisplayDevice::DEVICE_COUNT),
29eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mEnabled(false),
30eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mExitThread(false),
31eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mInitialized(false)
326a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
33e2b2a5fe291662041d1bbec00996c2ba302dc4c9Andy Qiu    CTRACE();
346a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
356a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
366a6081a46a83da606cf21548879b37695adc7e1fAndy QiuVsyncEventObserver::~VsyncEventObserver()
376a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
38eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    WARN_IF_NOT_DEINIT();
39eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
40eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
41eb726af21649d79ed720bdf329e0849270995c45Andy Qiubool VsyncEventObserver::initialize()
42eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
43eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (mInitialized) {
444157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("object has been initialized");
45eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return true;
46eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
47eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
48eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mExitThread = false;
49eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mEnabled = false;
50eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mDevice = mDisplayDevice.getType();
51eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mVsyncControl = mDisplayDevice.createVsyncControl();
52eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!mVsyncControl || !mVsyncControl->initialize()) {
53eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        DEINIT_AND_RETURN_FALSE("failed to initialize vsync control");
54eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
55eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
563f1974031c88750a14adc8f2f49538837238abf9Lin Xie    mThread = new VsyncEventPollThread(this);
57eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!mThread.get()) {
583f1974031c88750a14adc8f2f49538837238abf9Lin Xie        DEINIT_AND_RETURN_FALSE("failed to create vsync event poll thread.");
59eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
60eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
61eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mThread->run("VsyncEventObserver", PRIORITY_URGENT_DISPLAY);
626a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
63eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mInitialized = true;
64eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    return true;
656a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
666a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
67eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid VsyncEventObserver::deinitialize()
686a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
69eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (mEnabled) {
704157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("vsync is still enabled");
71eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        control(false);
72eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
73eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mInitialized = false;
74eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mExitThread = true;
75eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mEnabled = false;
76eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mCondition.signal();
77eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
78eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (mThread.get()) {
79eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mThread->requestExitAndWait();
80eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mThread = NULL;
81eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
82eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
83eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    DEINIT_AND_DELETE_OBJ(mVsyncControl);
84eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
85eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
86eb726af21649d79ed720bdf329e0849270995c45Andy Qiubool VsyncEventObserver::control(bool enabled)
87eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
884157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev    ALOGTRACE("enabled = %d on device %d", enabled, mDevice);
89eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (enabled == mEnabled) {
904157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        WLOGTRACE("vsync state %d is not changed", enabled);
91eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return true;
92eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
93eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
942455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue    Mutex::Autolock _l(mLock);
95eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    bool ret = mVsyncControl->control(mDevice, enabled);
96eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!ret) {
974157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev        ELOGTRACE("failed to control (%d) vsync on display %d", enabled, mDevice);
98eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return false;
99eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
1006a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1016a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    mEnabled = enabled;
1026a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    mCondition.signal();
103eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    return true;
1046a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
1056a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1066a6081a46a83da606cf21548879b37695adc7e1fAndy Qiubool VsyncEventObserver::threadLoop()
1076a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
1082455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue    do {
109eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        // scope for lock
1106a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        Mutex::Autolock _l(mLock);
1116a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        while (!mEnabled) {
1126a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu            mCondition.wait(mLock);
113eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            if (mExitThread) {
1144157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev                ILOGTRACE("exiting thread loop");
115eb726af21649d79ed720bdf329e0849270995c45Andy Qiu                return false;
116eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            }
1176a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
118eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    } while (0);
1196a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
120c2f5edc24db3d596601651541f8ce9bdde967441Geng, Xiujun    if(mEnabled && mDisplayDevice.isConnected()) {
1212455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue        int64_t timestamp;
1222455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue        bool ret = mVsyncControl->wait(mDevice, timestamp);
1232455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue        if (ret == false) {
1244157ee3f6fb20e0a249b9eedc06f3b16785ba31bIliyan Malchev            WLOGTRACE("failed to wait for vsync on display %d, vsync enabled %d", mDevice, mEnabled);
125c2f5edc24db3d596601651541f8ce9bdde967441Geng, Xiujun            usleep(16000);
1262455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue            return true;
1272455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue        }
1286a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1292455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue        // notify device
1302455e0fdc92b3dcc6e9a40ee4fd90930c8b3d151Wang, Yue        mDisplayDevice.onVsync(timestamp);
1316a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
1326a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1336a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    return true;
1346a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
1356a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1366a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} // namespace intel
1376a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} // namesapce android
138