summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
author Xin Li <delphij@google.com> 2019-10-27 04:44:29 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2019-10-27 04:44:29 +0000
commit1aed8b369dd977fba69134fc03bf3762c26c560c (patch)
tree5840f75cb9669f1da1c4aae8ab1cf2dedd016fb8 /services/surfaceflinger/SurfaceFlinger.cpp
parent19c8513c7b7d75ddd78d1b4c6948e4dadc1e50f7 (diff)
parent0205f87a0121f1e6057055752365a01b390c60ec (diff)
Merge "Merge Coral/Flame into AOSP master"
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp180
1 files changed, 135 insertions, 45 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a15cf4a340..3057ed13e7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -48,6 +48,8 @@
#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <dvr/vr_flinger.h>
#include <gui/BufferQueue.h>
+#include <gui/DebugEGLImageTracker.h>
+
#include <gui/GuiConfig.h>
#include <gui/IDisplayEventConnection.h>
#include <gui/IProducerListener.h>
@@ -311,6 +313,9 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI
wideColorGamutCompositionPixelFormat =
static_cast<ui::PixelFormat>(wcg_composition_pixel_format(ui::PixelFormat::RGBA_8888));
+ mColorSpaceAgnosticDataspace =
+ static_cast<ui::Dataspace>(color_space_agnostic_dataspace(Dataspace::UNKNOWN));
+
useContextPriority = use_context_priority(true);
auto tmpPrimaryDisplayOrientation = primary_display_orientation(
@@ -382,7 +387,8 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI
mLumaSampling = atoi(value);
const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
- mVsyncModulator.setPhaseOffsets(early, gl, late);
+ mVsyncModulator.setPhaseOffsets(early, gl, late,
+ mPhaseOffsets->getOffsetThresholdForNextVsync());
// We should be reading 'persist.sys.sf.color_saturation' here
// but since /data may be encrypted, we need to wait until after vold
@@ -621,13 +627,16 @@ void SurfaceFlinger::init() {
mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
mAppConnectionHandle =
- mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(),
+ mScheduler->createConnection("app", mVsyncModulator.getOffsets().app,
+ mPhaseOffsets->getOffsetThresholdForNextVsync(),
resyncCallback,
impl::EventThread::InterceptVSyncsCallback());
- mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(),
- resyncCallback, [this](nsecs_t timestamp) {
- mInterceptor->saveVSyncEvent(timestamp);
- });
+ mSfConnectionHandle =
+ mScheduler->createConnection("sf", mVsyncModulator.getOffsets().sf,
+ mPhaseOffsets->getOffsetThresholdForNextVsync(),
+ resyncCallback, [this](nsecs_t timestamp) {
+ mInterceptor->saveVSyncEvent(timestamp);
+ });
mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
mVsyncModulator.setSchedulerAndHandles(mScheduler.get(), mAppConnectionHandle.get(),
@@ -711,6 +720,24 @@ void SurfaceFlinger::init() {
Mutex::Autolock lock(mStateLock);
setRefreshRateTo(type, event);
});
+ mScheduler->setGetCurrentRefreshRateTypeCallback([this] {
+ Mutex::Autolock lock(mStateLock);
+ const auto display = getDefaultDisplayDeviceLocked();
+ if (!display) {
+ // If we don't have a default display the fallback to the default
+ // refresh rate type
+ return RefreshRateType::DEFAULT;
+ }
+
+ const int configId = display->getActiveConfig();
+ for (const auto& [type, refresh] : mRefreshRateConfigs.getRefreshRates()) {
+ if (refresh && refresh->configId == configId) {
+ return type;
+ }
+ }
+ // This should never happen, but just gracefully fallback to default.
+ return RefreshRateType::DEFAULT;
+ });
mScheduler->setGetVsyncPeriodCallback([this] {
Mutex::Autolock lock(mStateLock);
return getVsyncPeriod();
@@ -940,15 +967,13 @@ void SurfaceFlinger::setDesiredActiveConfig(const ActiveConfigInfo& info) {
// Start receiving vsync samples now, so that we can detect a period
// switch.
mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
- // We should only move to early offsets when we know that the refresh
- // rate will change. Otherwise, we may be stuck in early offsets
- // forever, as onRefreshRateChangeDetected will not be called.
- if (mDesiredActiveConfig.event == Scheduler::ConfigEvent::Changed) {
- mVsyncModulator.onRefreshRateChangeInitiated();
- }
+ // As we called to set period, we will call to onRefreshRateChangeCompleted once
+ // DispSync model is locked.
+ mVsyncModulator.onRefreshRateChangeInitiated();
mPhaseOffsets->setRefreshRateType(info.type);
const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
- mVsyncModulator.setPhaseOffsets(early, gl, late);
+ mVsyncModulator.setPhaseOffsets(early, gl, late,
+ mPhaseOffsets->getOffsetThresholdForNextVsync());
}
mDesiredActiveConfigChanged = true;
ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged);
@@ -980,10 +1005,10 @@ void SurfaceFlinger::setActiveConfigInternal() {
display->setActiveConfig(mUpcomingActiveConfig.configId);
- mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
mPhaseOffsets->setRefreshRateType(mUpcomingActiveConfig.type);
const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
- mVsyncModulator.setPhaseOffsets(early, gl, late);
+ mVsyncModulator.setPhaseOffsets(early, gl, late,
+ mPhaseOffsets->getOffsetThresholdForNextVsync());
ATRACE_INT("ActiveConfigMode", mUpcomingActiveConfig.configId);
if (mUpcomingActiveConfig.event != Scheduler::ConfigEvent::None) {
@@ -992,6 +1017,19 @@ void SurfaceFlinger::setActiveConfigInternal() {
}
}
+void SurfaceFlinger::desiredActiveConfigChangeDone() {
+ std::lock_guard<std::mutex> lock(mActiveConfigLock);
+ mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
+ mDesiredActiveConfigChanged = false;
+ ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged);
+
+ mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
+ mPhaseOffsets->setRefreshRateType(mUpcomingActiveConfig.type);
+ const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
+ mVsyncModulator.setPhaseOffsets(early, gl, late,
+ mPhaseOffsets->getOffsetThresholdForNextVsync());
+}
+
bool SurfaceFlinger::performSetActiveConfig() {
ATRACE_CALL();
if (mCheckPendingFence) {
@@ -1021,14 +1059,7 @@ bool SurfaceFlinger::performSetActiveConfig() {
if (!display || display->getActiveConfig() == desiredActiveConfig.configId) {
// display is not valid or we are already in the requested mode
// on both cases there is nothing left to do
- std::lock_guard<std::mutex> lock(mActiveConfigLock);
- mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
- mDesiredActiveConfigChanged = false;
- // Update scheduler with the correct vsync period as a no-op.
- // Otherwise, there exists a race condition where we get stuck in the
- // incorrect vsync period.
- mScheduler->resyncToHardwareVsync(false, getVsyncPeriod());
- ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged);
+ desiredActiveConfigChangeDone();
return false;
}
@@ -1036,17 +1067,10 @@ bool SurfaceFlinger::performSetActiveConfig() {
// allowed configs might have change by the time we process the refresh.
// Make sure the desired config is still allowed
if (!isDisplayConfigAllowed(desiredActiveConfig.configId)) {
- std::lock_guard<std::mutex> lock(mActiveConfigLock);
- mDesiredActiveConfig.event = Scheduler::ConfigEvent::None;
- mDesiredActiveConfig.configId = display->getActiveConfig();
- mDesiredActiveConfigChanged = false;
- // Update scheduler with the current vsync period as a no-op.
- // Otherwise, there exists a race condition where we get stuck in the
- // incorrect vsync period.
- mScheduler->resyncToHardwareVsync(false, getVsyncPeriod());
- ATRACE_INT("DesiredActiveConfigChanged", mDesiredActiveConfigChanged);
+ desiredActiveConfigChangeDone();
return false;
}
+
mUpcomingActiveConfig = desiredActiveConfig;
const auto displayId = display->getId();
LOG_ALWAYS_FATAL_IF(!displayId);
@@ -1384,7 +1408,7 @@ status_t SurfaceFlinger::notifyPowerHint(int32_t hintId) {
// ----------------------------------------------------------------------------
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
- ISurfaceComposer::VsyncSource vsyncSource) {
+ ISurfaceComposer::VsyncSource vsyncSource, ISurfaceComposer::ConfigChanged configChanged) {
auto resyncCallback = mScheduler->makeResyncCallback([this] {
Mutex::Autolock lock(mStateLock);
return getVsyncPeriod();
@@ -1393,7 +1417,8 @@ sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
const auto& handle =
vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle;
- return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback));
+ return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback),
+ configChanged);
}
// ----------------------------------------------------------------------------
@@ -1542,10 +1567,23 @@ void SurfaceFlinger::onRefreshReceived(int sequenceId, hwc2_display_t /*hwcDispl
void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) {
ATRACE_CALL();
- Mutex::Autolock lock(mStateLock);
+
+ // Enable / Disable HWVsync from the main thread to avoid race conditions with
+ // display power state.
+ postMessageAsync(new LambdaMessage(
+ [=]() NO_THREAD_SAFETY_ANALYSIS { setPrimaryVsyncEnabledInternal(enabled); }));
+}
+
+void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) {
+ ATRACE_CALL();
+
+ mHWCVsyncPendingState = enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable;
+
if (const auto displayId = getInternalDisplayIdLocked()) {
- getHwComposer().setVsyncEnabled(*displayId,
- enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
+ sp<DisplayDevice> display = getDefaultDisplayDeviceLocked();
+ if (display && display->isPoweredOn()) {
+ setVsyncEnabledInHWC(*displayId, mHWCVsyncPendingState);
+ }
}
}
@@ -1655,22 +1693,26 @@ bool SurfaceFlinger::previousFrameMissed() NO_THREAD_SAFETY_ANALYSIS {
return fence != Fence::NO_FENCE && (fence->getStatus() == Fence::Status::Unsignaled);
}
-nsecs_t SurfaceFlinger::getExpectedPresentTime() NO_THREAD_SAFETY_ANALYSIS {
+void SurfaceFlinger::populateExpectedPresentTime() NO_THREAD_SAFETY_ANALYSIS {
DisplayStatInfo stats;
mScheduler->getDisplayStatInfo(&stats);
const nsecs_t presentTime = mScheduler->getDispSyncExpectedPresentTime();
// Inflate the expected present time if we're targetting the next vsync.
- const nsecs_t correctedTime =
+ mExpectedPresentTime =
mVsyncModulator.getOffsets().sf < mPhaseOffsets->getOffsetThresholdForNextVsync()
? presentTime
: presentTime + stats.vsyncPeriod;
- return correctedTime;
}
void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
+ // calculate the expected present time once and use the cached
+ // value throughout this frame to make sure all layers are
+ // seeing this same value.
+ populateExpectedPresentTime();
+
bool frameMissed = previousFrameMissed();
bool hwcFrameMissed = mHadDeviceComposition && frameMissed;
bool gpuFrameMissed = mHadClientComposition && frameMissed;
@@ -1873,7 +1915,14 @@ void SurfaceFlinger::calculateWorkingSet() {
RenderIntent renderIntent;
pickColorMode(displayDevice, &colorMode, &targetDataspace, &renderIntent);
display->setColorMode(colorMode, targetDataspace, renderIntent);
+
+ if (isHdrColorMode(colorMode)) {
+ targetDataspace = Dataspace::UNKNOWN;
+ } else if (mColorSpaceAgnosticDataspace != Dataspace::UNKNOWN) {
+ targetDataspace = mColorSpaceAgnosticDataspace;
+ }
}
+
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
if (layer->isHdrY410()) {
layer->forceClientComposition(displayDevice);
@@ -1900,9 +1949,7 @@ void SurfaceFlinger::calculateWorkingSet() {
const auto& displayState = display->getState();
layer->setPerFrameData(displayDevice, displayState.transform, displayState.viewport,
- displayDevice->getSupportedPerFrameMetadata(),
- isHdrColorMode(displayState.colorMode) ? Dataspace::UNKNOWN
- : targetDataspace);
+ displayDevice->getSupportedPerFrameMetadata(), targetDataspace);
}
}
@@ -3798,6 +3845,7 @@ void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
if (uncacheBuffer.isValid()) {
ClientCache::getInstance().erase(uncacheBuffer);
+ getRenderEngine().unbindExternalTextureBuffer(uncacheBuffer.id);
}
// If a synchronous transaction is explicitly requested without any changes, force a transaction
@@ -4152,9 +4200,18 @@ uint32_t SurfaceFlinger::setClientStateLocked(
bool bufferChanged = what & layer_state_t::eBufferChanged;
bool cacheIdChanged = what & layer_state_t::eCachedBufferChanged;
sp<GraphicBuffer> buffer;
- if (bufferChanged && cacheIdChanged) {
- ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
+ if (bufferChanged && cacheIdChanged && s.buffer != nullptr) {
buffer = s.buffer;
+ bool success = ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
+ if (success) {
+ getRenderEngine().cacheExternalTextureBuffer(s.buffer);
+ success = ClientCache::getInstance()
+ .registerErasedRecipient(s.cachedBuffer,
+ wp<ClientCache::ErasedRecipient>(this));
+ if (!success) {
+ getRenderEngine().unbindExternalTextureBuffer(s.buffer->getId());
+ }
+ }
} else if (cacheIdChanged) {
buffer = ClientCache::getInstance().get(s.cachedBuffer);
} else if (bufferChanged) {
@@ -4437,6 +4494,13 @@ void SurfaceFlinger::initializeDisplays() {
new LambdaMessage([this]() NO_THREAD_SAFETY_ANALYSIS { onInitializeDisplays(); }));
}
+void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, HWC2::Vsync enabled) {
+ if (mHWCVsyncState != enabled) {
+ getHwComposer().setVsyncEnabled(displayId, enabled);
+ mHWCVsyncState = enabled;
+ }
+}
+
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int mode) {
if (display->isVirtual()) {
ALOGE("%s: Invalid operation on virtual display", __FUNCTION__);
@@ -4463,6 +4527,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int
// Turn on the display
getHwComposer().setPowerMode(*displayId, mode);
if (display->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
+ setVsyncEnabledInHWC(*displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
}
@@ -4488,6 +4553,9 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int
mScheduler->onScreenReleased(mAppConnectionHandle);
}
+ // Make sure HWVsync is disabled before turning off the display
+ setVsyncEnabledInHWC(*displayId, HWC2::Vsync::Disable);
+
getHwComposer().setPowerMode(*displayId, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
@@ -4514,6 +4582,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int
if (display->isPrimary()) {
mTimeStats->setPowerMode(mode);
mRefreshRateStats.setPowerMode(mode);
+ mScheduler->setDisplayPowerState(mode == HWC_POWER_MODE_NORMAL);
}
ALOGD("Finished setting power mode %d on display %s", mode, to_string(*displayId).c_str());
@@ -4682,6 +4751,16 @@ void SurfaceFlinger::dumpVSync(std::string& result) const {
StringAppendF(&result, "Scheduler enabled.");
StringAppendF(&result, "+ Smart 90 for video detection: %s\n\n",
mUseSmart90ForVideo ? "on" : "off");
+ StringAppendF(&result, "Allowed Display Configs: ");
+ for (int32_t configId : mAllowedDisplayConfigs) {
+ for (auto refresh : mRefreshRateConfigs.getRefreshRates()) {
+ if (refresh.second && refresh.second->configId == configId) {
+ StringAppendF(&result, "%dHz, ", refresh.second->fps);
+ }
+ }
+ }
+ StringAppendF(&result, "(config override by backdoor: %s)\n\n",
+ mDebugDisplayConfigSetByBackdoor ? "yes" : "no");
mScheduler->dump(mAppConnectionHandle, result);
}
@@ -4964,6 +5043,8 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co
getRenderEngine().dump(result);
+ DebugEGLImageTracker::getInstance()->dump(result);
+
if (const auto display = getDefaultDisplayDeviceLocked()) {
display->getCompositionDisplay()->getState().undefinedRegion.dump(result,
"undefinedRegion");
@@ -5377,7 +5458,12 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r
return NO_ERROR;
}
case 1023: { // Set native mode
+ int32_t colorMode;
+
mDisplayColorSetting = static_cast<DisplayColorSetting>(data.readInt32());
+ if (data.readInt32(&colorMode) == NO_ERROR) {
+ mForceColorMode = static_cast<ColorMode>(colorMode);
+ }
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
@@ -6173,6 +6259,10 @@ sp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) {
return nullptr;
}
+void SurfaceFlinger::bufferErased(const client_cache_t& clientCacheId) {
+ getRenderEngine().unbindExternalTextureBuffer(clientCacheId.id);
+}
+
} // namespace android
#if defined(__gl_h_)