82 lines
2.3 KiB
C++
82 lines
2.3 KiB
C++
// Copyright 2021 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
#include "VsyncThread.h"
|
|
|
|
#include "aemu/base/system/System.h"
|
|
|
|
namespace gfxstream {
|
|
|
|
VsyncThread::VsyncThread(uint64_t vsyncPeriodNs) :
|
|
mPeriodNs(vsyncPeriodNs),
|
|
mThread([this] { threadFunc(); }) {
|
|
mThread.start();
|
|
}
|
|
|
|
VsyncThread::~VsyncThread() {
|
|
exit();
|
|
}
|
|
|
|
void VsyncThread::schedule(VsyncTask task) {
|
|
mChannel.send({ CommandType::Default, task });
|
|
}
|
|
|
|
void VsyncThread::setPeriod(uint64_t newPeriod) {
|
|
mChannel.send({ CommandType::ChangePeriod, {}, newPeriod });
|
|
}
|
|
|
|
void VsyncThread::exit() {
|
|
mChannel.send({ CommandType::Exit });
|
|
mThread.wait();
|
|
}
|
|
|
|
void VsyncThread::threadFunc() {
|
|
VsyncThreadCommand currentCommand;
|
|
uint64_t lastTimeUs = ~0ULL;
|
|
uint64_t phasedWaitTimeUs;
|
|
uint64_t currentUs;
|
|
|
|
while (true) {
|
|
uint64_t periodUs = mPeriodNs / 1000ULL;
|
|
currentUs = android::base::getHighResTimeUs();
|
|
|
|
if (lastTimeUs == ~0ULL) {
|
|
phasedWaitTimeUs = currentUs + periodUs;
|
|
} else {
|
|
phasedWaitTimeUs =
|
|
periodUs * ((currentUs - lastTimeUs) / periodUs + 1) +
|
|
lastTimeUs;
|
|
}
|
|
|
|
android::base::sleepToUs(phasedWaitTimeUs);
|
|
|
|
lastTimeUs = phasedWaitTimeUs;
|
|
|
|
while (mChannel.tryReceive(¤tCommand)) {
|
|
switch (currentCommand.type) {
|
|
case CommandType::Exit:
|
|
return;
|
|
case CommandType::ChangePeriod:
|
|
mPeriodNs = currentCommand.newPeriod;
|
|
break;
|
|
case CommandType::Default:
|
|
default:
|
|
currentCommand.task(mCount);
|
|
}
|
|
}
|
|
|
|
++mCount;
|
|
}
|
|
}
|
|
|
|
} // namespace gfxstream
|