VsyncEventObserver.cpp revision 3f1974031c88750a14adc8f2f49538837238abf9
16a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu/*
26a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * Copyright © 2012 Intel Corporation
36a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * All rights reserved.
46a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu *
56a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * Permission is hereby granted, free of charge, to any person obtaining a
66a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * copy of this software and associated documentation files (the "Software"),
76a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * to deal in the Software without restriction, including without limitation
86a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
96a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * and/or sell copies of the Software, and to permit persons to whom the
106a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * Software is furnished to do so, subject to the following conditions:
116a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu *
126a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * The above copyright notice and this permission notice (including the next
136a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * paragraph) shall be included in all copies or substantial portions of the
146a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * Software.
156a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu *
166a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
176a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
186a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
196a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
206a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
216a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
226a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * IN THE SOFTWARE.
236a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu *
246a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu * Authors:
256a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu *    Jackie Li <yaodong.li@intel.com>
266a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu *
276a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu */
28e2b2a5fe291662041d1bbec00996c2ba302dc4c9Andy Qiu#include <HwcTrace.h>
296a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu#include <VsyncEventObserver.h>
308a427146c6f68f9add960bbd18c4f84c9eeee4a5Andy Qiu#include <PhysicalDevice.h>
316a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
326a6081a46a83da606cf21548879b37695adc7e1fAndy Qiunamespace android {
336a6081a46a83da606cf21548879b37695adc7e1fAndy Qiunamespace intel {
346a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
35eb726af21649d79ed720bdf329e0849270995c45Andy QiuVsyncEventObserver::VsyncEventObserver(PhysicalDevice& disp)
36eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    : mLock(),
37eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mCondition(),
38eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mDisplayDevice(disp),
39eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mVsyncControl(NULL),
40eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mDevice(IDisplayDevice::DEVICE_COUNT),
41eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mEnabled(false),
42eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mExitThread(false),
43eb726af21649d79ed720bdf329e0849270995c45Andy Qiu      mInitialized(false)
446a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
45e2b2a5fe291662041d1bbec00996c2ba302dc4c9Andy Qiu    CTRACE();
466a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
476a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
486a6081a46a83da606cf21548879b37695adc7e1fAndy QiuVsyncEventObserver::~VsyncEventObserver()
496a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
50eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    WARN_IF_NOT_DEINIT();
51eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
52eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
53eb726af21649d79ed720bdf329e0849270995c45Andy Qiubool VsyncEventObserver::initialize()
54eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
55eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (mInitialized) {
56eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        WTRACE("object has been initialized");
57eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return true;
58eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
59eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
60eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mExitThread = false;
61eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mEnabled = false;
62eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mDevice = mDisplayDevice.getType();
63eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mVsyncControl = mDisplayDevice.createVsyncControl();
64eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!mVsyncControl || !mVsyncControl->initialize()) {
65eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        DEINIT_AND_RETURN_FALSE("failed to initialize vsync control");
66eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
67eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
683f1974031c88750a14adc8f2f49538837238abf9Lin Xie    mThread = new VsyncEventPollThread(this);
69eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!mThread.get()) {
703f1974031c88750a14adc8f2f49538837238abf9Lin Xie        DEINIT_AND_RETURN_FALSE("failed to create vsync event poll thread.");
71eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
72eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
73eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mThread->run("VsyncEventObserver", PRIORITY_URGENT_DISPLAY);
746a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
75eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mInitialized = true;
76eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    return true;
776a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
786a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
79eb726af21649d79ed720bdf329e0849270995c45Andy Qiuvoid VsyncEventObserver::deinitialize()
806a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
81eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (mEnabled) {
82eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        WTRACE("vsync is still enabled");
83eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        control(false);
84eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
85eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mInitialized = false;
86eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mExitThread = true;
87eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mEnabled = false;
88eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    mCondition.signal();
89eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
90eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (mThread.get()) {
91eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mThread->requestExitAndWait();
92eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        mThread = NULL;
93eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
94eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
95eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    DEINIT_AND_DELETE_OBJ(mVsyncControl);
96eb726af21649d79ed720bdf329e0849270995c45Andy Qiu}
97eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
98eb726af21649d79ed720bdf329e0849270995c45Andy Qiubool VsyncEventObserver::control(bool enabled)
99eb726af21649d79ed720bdf329e0849270995c45Andy Qiu{
100eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    ATRACE("enabled = %d on device %d", enabled, mDevice);
101eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (enabled == mEnabled) {
102eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        WTRACE("vsync state %d is not changed", enabled);
103eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return true;
104eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
105eb726af21649d79ed720bdf329e0849270995c45Andy Qiu
106eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    bool ret = mVsyncControl->control(mDevice, enabled);
107eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    if (!ret) {
108eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        ETRACE("failed to control (%d) vsync on display %d", enabled, mDevice);
109eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        return false;
110eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    }
1116a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1126a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    Mutex::Autolock _l(mLock);
1136a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    mEnabled = enabled;
1146a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    mCondition.signal();
115eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    return true;
1166a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
1176a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1186a6081a46a83da606cf21548879b37695adc7e1fAndy Qiubool VsyncEventObserver::threadLoop()
1196a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu{
120eb726af21649d79ed720bdf329e0849270995c45Andy Qiu     do {
121eb726af21649d79ed720bdf329e0849270995c45Andy Qiu        // scope for lock
1226a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        Mutex::Autolock _l(mLock);
1236a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        while (!mEnabled) {
1246a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu            mCondition.wait(mLock);
125eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            if (mExitThread) {
126eb726af21649d79ed720bdf329e0849270995c45Andy Qiu                ITRACE("exiting thread loop");
127eb726af21649d79ed720bdf329e0849270995c45Andy Qiu                return false;
128eb726af21649d79ed720bdf329e0849270995c45Andy Qiu            }
1296a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        }
130eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    } while (0);
1316a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1326a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    int64_t timestamp;
133eb726af21649d79ed720bdf329e0849270995c45Andy Qiu    bool ret = mVsyncControl->wait(mDevice, timestamp);
1346a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1356a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    if (ret == false) {
136e2b2a5fe291662041d1bbec00996c2ba302dc4c9Andy Qiu        WTRACE("failed to wait for vsync, check vsync enabling...");
1376a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu        return true;
1386a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    }
1396a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1406a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    // notify device
1416a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    mDisplayDevice.onVsync(timestamp);
1426a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu    return true;
1436a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu}
1446a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu
1456a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} // namespace intel
1466a6081a46a83da606cf21548879b37695adc7e1fAndy Qiu} // namesapce android
147