18b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol/*
28b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Copyright (c) 2014 Intel Corporation 
38b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
48b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Licensed under the Apache License, Version 2.0 (the "License");
58b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// you may not use this file except in compliance with the License.
68b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// You may obtain a copy of the License at
78b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
88b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//      http://www.apache.org/licenses/LICENSE-2.0
98b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Unless required by applicable law or agreed to in writing, software
118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// distributed under the License is distributed on an "AS IS" BASIS,
128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// See the License for the specific language governing permissions and
148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// limitations under the License.
158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol*/
168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <HwcTrace.h>
178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <VsyncEventObserver.h>
188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <PhysicalDevice.h>
198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace android {
218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace intel {
228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolVsyncEventObserver::VsyncEventObserver(PhysicalDevice& disp)
248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    : mLock(),
258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mCondition(),
268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mDisplayDevice(disp),
278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mVsyncControl(NULL),
288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mDevice(IDisplayDevice::DEVICE_COUNT),
298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mEnabled(false),
308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mExitThread(false),
318b55c41553ee026c299578b158c4b85de50aaee1Victor Tasayco Loarte      mInitialized(false),
328b55c41553ee026c299578b158c4b85de50aaee1Victor Tasayco Loarte      mFpsCounter(0)
338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    CTRACE();
358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolVsyncEventObserver::~VsyncEventObserver()
388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    WARN_IF_NOT_DEINIT();
408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool VsyncEventObserver::initialize()
438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mInitialized) {
458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        WTRACE("object has been initialized");
468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return true;
478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mExitThread = false;
508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mEnabled = false;
518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mDevice = mDisplayDevice.getType();
528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mVsyncControl = mDisplayDevice.createVsyncControl();
538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mVsyncControl || !mVsyncControl->initialize()) {
548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        DEINIT_AND_RETURN_FALSE("failed to initialize vsync control");
558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mThread = new VsyncEventPollThread(this);
588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mThread.get()) {
598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        DEINIT_AND_RETURN_FALSE("failed to create vsync event poll thread.");
608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mThread->run("VsyncEventObserver", PRIORITY_URGENT_DISPLAY);
638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mInitialized = true;
658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid VsyncEventObserver::deinitialize()
698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mEnabled) {
718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        WTRACE("vsync is still enabled");
728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        control(false);
738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mInitialized = false;
758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mExitThread = true;
768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mEnabled = false;
778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mCondition.signal();
788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mThread.get()) {
808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mThread->requestExitAndWait();
818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mThread = NULL;
828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    DEINIT_AND_DELETE_OBJ(mVsyncControl);
858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool VsyncEventObserver::control(bool enabled)
888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    ATRACE("enabled = %d on device %d", enabled, mDevice);
908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (enabled == mEnabled) {
918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        WTRACE("vsync state %d is not changed", enabled);
928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return true;
938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    Mutex::Autolock _l(mLock);
968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    bool ret = mVsyncControl->control(mDevice, enabled);
978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!ret) {
988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to control (%d) vsync on display %d", enabled, mDevice);
998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
1008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mEnabled = enabled;
1038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mCondition.signal();
1048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
1058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool VsyncEventObserver::threadLoop()
1088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    do {
1108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        // scope for lock
1118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        Mutex::Autolock _l(mLock);
1128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        while (!mEnabled) {
1138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            mCondition.wait(mLock);
1148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            if (mExitThread) {
1158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol                ITRACE("exiting thread loop");
1168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol                return false;
1178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            }
1188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
1198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    } while (0);
1208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if(mEnabled && mDisplayDevice.isConnected()) {
1228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        int64_t timestamp;
1238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        bool ret = mVsyncControl->wait(mDevice, timestamp);
1248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (ret == false) {
1258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            WTRACE("failed to wait for vsync on display %d, vsync enabled %d", mDevice, mEnabled);
1268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            usleep(16000);
1278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            return true;
1288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
1298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1308b55c41553ee026c299578b158c4b85de50aaee1Victor Tasayco Loarte        // send vsync event notification every hwc.fps_divider
1318b55c41553ee026c299578b158c4b85de50aaee1Victor Tasayco Loarte        if ((mFpsCounter++) % mDisplayDevice.getFpsDivider() == 0)
1328b55c41553ee026c299578b158c4b85de50aaee1Victor Tasayco Loarte            mDisplayDevice.onVsync(timestamp);
1338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
1368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace intel
1398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namesapce android
140