|
|
/* |
|
|
// Copyright (c) 2014 Intel Corporation |
|
|
// |
|
|
// 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 express or implied. |
|
|
// See the License for the specific language governing permissions and |
|
|
// limitations under the License. |
|
|
*/ |
|
|
|
|
|
#include <HwcTrace.h> |
|
|
#include <IDisplayDevice.h> |
|
|
#include <DisplayQuery.h> |
|
|
#include <BufferManager.h> |
|
|
#include <DisplayPlaneManager.h> |
|
|
#include <Hwcomposer.h> |
|
|
#include <VsyncManager.h> |
|
|
|
|
|
|
|
|
namespace android { |
|
|
namespace intel { |
|
|
|
|
|
VsyncManager::VsyncManager(Hwcomposer &hwc) |
|
|
:mHwc(hwc), |
|
|
mInitialized(false), |
|
|
mEnableDynamicVsync(true), |
|
|
mEnabled(false), |
|
|
mVsyncSource(IDisplayDevice::DEVICE_COUNT), |
|
|
mLock() |
|
|
{ |
|
|
} |
|
|
|
|
|
VsyncManager::~VsyncManager() |
|
|
{ |
|
|
WARN_IF_NOT_DEINIT(); |
|
|
} |
|
|
|
|
|
bool VsyncManager::initialize() |
|
|
{ |
|
|
|
|
|
mEnabled = false; |
|
|
mVsyncSource = IDisplayDevice::DEVICE_COUNT; |
|
|
mEnableDynamicVsync = !scUsePrimaryVsyncOnly; |
|
|
mInitialized = true; |
|
|
return true; |
|
|
} |
|
|
|
|
|
void VsyncManager::deinitialize() |
|
|
{ |
|
|
if (mEnabled) { |
|
|
WTRACE("vsync is still enabled"); |
|
|
} |
|
|
|
|
|
mVsyncSource = IDisplayDevice::DEVICE_COUNT; |
|
|
mEnabled = false; |
|
|
mEnableDynamicVsync = !scUsePrimaryVsyncOnly; |
|
|
mInitialized = false; |
|
|
} |
|
|
|
|
|
bool VsyncManager::handleVsyncControl(int disp, bool enabled) |
|
|
{ |
|
|
Mutex::Autolock l(mLock); |
|
|
|
|
|
if (disp != IDisplayDevice::DEVICE_PRIMARY) { |
|
|
WTRACE("vsync control on non-primary device %d", disp); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (mEnabled == enabled) { |
|
|
WTRACE("vsync state %d is not changed", enabled); |
|
|
return true; |
|
|
} |
|
|
|
|
|
if (!enabled) { |
|
|
disableVsync(); |
|
|
mEnabled = false; |
|
|
return true; |
|
|
} else { |
|
|
mEnabled = enableVsync(getCandidate()); |
|
|
return mEnabled; |
|
|
} |
|
|
|
|
|
return false; |
|
|
} |
|
|
|
|
|
void VsyncManager::resetVsyncSource() |
|
|
{ |
|
|
Mutex::Autolock l(mLock); |
|
|
|
|
|
if (!mEnableDynamicVsync) { |
|
|
ITRACE("dynamic vsync source switch is not supported"); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (!mEnabled) { |
|
|
return; |
|
|
} |
|
|
|
|
|
int vsyncSource = getCandidate(); |
|
|
if (vsyncSource == mVsyncSource) { |
|
|
return; |
|
|
} |
|
|
|
|
|
disableVsync(); |
|
|
enableVsync(vsyncSource); |
|
|
} |
|
|
|
|
|
int VsyncManager::getVsyncSource() |
|
|
{ |
|
|
return mVsyncSource; |
|
|
} |
|
|
|
|
|
void VsyncManager::enableDynamicVsync(bool enable) |
|
|
{ |
|
|
Mutex::Autolock l(mLock); |
|
|
if (scUsePrimaryVsyncOnly) { |
|
|
WTRACE("dynamic vsync is not supported"); |
|
|
return; |
|
|
} |
|
|
|
|
|
mEnableDynamicVsync = enable; |
|
|
|
|
|
if (!mEnabled) { |
|
|
return; |
|
|
} |
|
|
|
|
|
int vsyncSource = getCandidate(); |
|
|
if (vsyncSource == mVsyncSource) { |
|
|
return; |
|
|
} |
|
|
|
|
|
disableVsync(); |
|
|
enableVsync(vsyncSource); |
|
|
} |
|
|
|
|
|
IDisplayDevice* VsyncManager::getDisplayDevice(int dispType ) { |
|
|
return mHwc.getDisplayDevice(dispType); |
|
|
} |
|
|
|
|
|
int VsyncManager::getCandidate() |
|
|
{ |
|
|
if (!mEnableDynamicVsync) { |
|
|
return IDisplayDevice::DEVICE_PRIMARY; |
|
|
} |
|
|
|
|
|
IDisplayDevice *device = NULL; |
|
|
// use HDMI vsync when connected |
|
|
device = getDisplayDevice(IDisplayDevice::DEVICE_EXTERNAL); |
|
|
if (device && device->isConnected()) { |
|
|
return IDisplayDevice::DEVICE_EXTERNAL; |
|
|
} |
|
|
|
|
|
// use vsync from virtual display when video extended mode is entered |
|
|
if (Hwcomposer::getInstance().getDisplayAnalyzer()->isVideoExtModeActive()) { |
|
|
device = getDisplayDevice(IDisplayDevice::DEVICE_VIRTUAL); |
|
|
if (device && device->isConnected()) { |
|
|
return IDisplayDevice::DEVICE_VIRTUAL; |
|
|
} |
|
|
WTRACE("Could not use vsync from secondary device"); |
|
|
} |
|
|
return IDisplayDevice::DEVICE_PRIMARY; |
|
|
} |
|
|
|
|
|
bool VsyncManager::enableVsync(int candidate) |
|
|
{ |
|
|
if (mVsyncSource != IDisplayDevice::DEVICE_COUNT) { |
|
|
WTRACE("vsync has been enabled on %d", mVsyncSource); |
|
|
return true; |
|
|
} |
|
|
|
|
|
IDisplayDevice *device = getDisplayDevice(candidate); |
|
|
if (!device) { |
|
|
ETRACE("invalid vsync source candidate %d", candidate); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (device->vsyncControl(true)) { |
|
|
mVsyncSource = candidate; |
|
|
return true; |
|
|
} |
|
|
|
|
|
if (candidate != IDisplayDevice::DEVICE_PRIMARY) { |
|
|
WTRACE("failed to enable vsync on display %d, fall back to primary", candidate); |
|
|
device = getDisplayDevice(IDisplayDevice::DEVICE_PRIMARY); |
|
|
if (device && device->vsyncControl(true)) { |
|
|
mVsyncSource = IDisplayDevice::DEVICE_PRIMARY; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
ETRACE("failed to enable vsync on the primary display"); |
|
|
return false; |
|
|
} |
|
|
|
|
|
void VsyncManager::disableVsync() |
|
|
{ |
|
|
if (mVsyncSource == IDisplayDevice::DEVICE_COUNT) { |
|
|
WTRACE("vsync has been disabled"); |
|
|
return; |
|
|
} |
|
|
|
|
|
IDisplayDevice *device = getDisplayDevice(mVsyncSource); |
|
|
if (device && !device->vsyncControl(false)) { |
|
|
WTRACE("failed to disable vsync on device %d", mVsyncSource); |
|
|
} |
|
|
mVsyncSource = IDisplayDevice::DEVICE_COUNT; |
|
|
} |
|
|
|
|
|
} // namespace intel |
|
|
} // namespace android |
|
|
|
|
|
|