diff options
| author | 2019-06-22 23:15:53 +0000 | |
|---|---|---|
| committer | 2019-06-22 23:15:53 +0000 | |
| commit | ae4a385d20f35faba4e39332f2cd033c2efd330c (patch) | |
| tree | 41d2ea9abe259f249173aa10a46bfa5ffff97735 | |
| parent | 5531408797caca34a22d7f9c0b787fcf7ad8d67d (diff) | |
| parent | 769ab6f949369468ee6355d00e490ad14a2f3721 (diff) | |
Snap for 5681502 from 769ab6f949369468ee6355d00e490ad14a2f3721 to qt-c2f2-release
Change-Id: I9f4d5bdd481032a7dcdda906446c02adef836bdf
| -rw-r--r-- | services/surfaceflinger/Android.bp | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/RegionSamplingThread.cpp | 16 | ||||
| -rw-r--r-- | services/surfaceflinger/Scheduler/DispSyncSource.cpp | 24 | ||||
| -rw-r--r-- | services/surfaceflinger/Scheduler/DispSyncSource.h | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/Scheduler/PhaseOffsets.cpp | 53 | ||||
| -rw-r--r-- | services/surfaceflinger/Scheduler/PhaseOffsets.h | 7 | ||||
| -rw-r--r-- | services/surfaceflinger/Scheduler/VSyncModulator.cpp | 178 | ||||
| -rw-r--r-- | services/surfaceflinger/Scheduler/VSyncModulator.h | 157 | ||||
| -rw-r--r-- | services/surfaceflinger/test.png | bin | 0 -> 3058273 bytes | |||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/FakePhaseOffsets.h | 14 | ||||
| -rw-r--r-- | services/vr/hardware_composer/Android.bp | 2 |
11 files changed, 298 insertions, 162 deletions
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 4cd0a13861..501d176401 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -149,9 +149,10 @@ filegroup { "Scheduler/LayerHistory.cpp", "Scheduler/LayerInfo.cpp", "Scheduler/MessageQueue.cpp", + "Scheduler/PhaseOffsets.cpp", "Scheduler/Scheduler.cpp", "Scheduler/SchedulerUtils.cpp", - "Scheduler/PhaseOffsets.cpp", + "Scheduler/VSyncModulator.cpp", "StartPropertySetThread.cpp", "SurfaceFlinger.cpp", "SurfaceInterceptor.cpp", diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp index 8b85d4cdbf..72bbf5dc26 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -342,9 +342,19 @@ void RegionSamplingThread::captureSample() { } const auto device = mFlinger.getDefaultDisplayDevice(); - const auto display = device->getCompositionDisplay(); - const auto state = display->getState(); - const auto orientation = static_cast<ui::Transform::orientation_flags>(state.orientation); + const auto orientation = [](uint32_t orientation) { + switch (orientation) { + default: + case DisplayState::eOrientationDefault: + return ui::Transform::ROT_0; + case DisplayState::eOrientation90: + return ui::Transform::ROT_90; + case DisplayState::eOrientation180: + return ui::Transform::ROT_180; + case DisplayState::eOrientation270: + return ui::Transform::ROT_270; + } + }(device->getOrientation()); std::vector<RegionSamplingThread::Descriptor> descriptors; Region sampleRegion; diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.cpp b/services/surfaceflinger/Scheduler/DispSyncSource.cpp index 265b8aa47f..026b55707c 100644 --- a/services/surfaceflinger/Scheduler/DispSyncSource.cpp +++ b/services/surfaceflinger/Scheduler/DispSyncSource.cpp @@ -34,6 +34,8 @@ DispSyncSource::DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, mTraceVsync(traceVsync), mVsyncOnLabel(base::StringPrintf("VsyncOn-%s", name)), mVsyncEventLabel(base::StringPrintf("VSYNC-%s", name)), + mVsyncOffsetLabel(base::StringPrintf("VsyncOffset-%s", name)), + mVsyncNegativeOffsetLabel(base::StringPrintf("VsyncNegativeOffset-%s", name)), mDispSync(dispSync), mPhaseOffset(phaseOffset), mOffsetThresholdForNextVsync(offsetThresholdForNextVsync) {} @@ -41,6 +43,7 @@ DispSyncSource::DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, void DispSyncSource::setVSyncEnabled(bool enable) { std::lock_guard lock(mVsyncMutex); if (enable) { + tracePhaseOffset(); status_t err = mDispSync->addEventListener(mName, mPhaseOffset, static_cast<DispSync::Callback*>(this), mLastCallbackTime); @@ -76,6 +79,7 @@ void DispSyncSource::setPhaseOffset(nsecs_t phaseOffset) { const int numPeriods = phaseOffset / period; phaseOffset -= numPeriods * period; mPhaseOffset = phaseOffset; + tracePhaseOffset(); // If we're not enabled, we don't need to mess with the listeners if (!mEnabled) { @@ -94,11 +98,11 @@ void DispSyncSource::onDispSyncEvent(nsecs_t when) { { std::lock_guard lock(mCallbackMutex); callback = mCallback; + } - if (mTraceVsync) { - mValue = (mValue + 1) % 2; - ATRACE_INT(mVsyncEventLabel.c_str(), mValue); - } + if (mTraceVsync) { + mValue = (mValue + 1) % 2; + ATRACE_INT(mVsyncEventLabel.c_str(), mValue); } if (callback != nullptr) { @@ -106,4 +110,14 @@ void DispSyncSource::onDispSyncEvent(nsecs_t when) { } } -} // namespace android
\ No newline at end of file +void DispSyncSource::tracePhaseOffset() { + if (mPhaseOffset > 0) { + ATRACE_INT(mVsyncOffsetLabel.c_str(), mPhaseOffset); + ATRACE_INT(mVsyncNegativeOffsetLabel.c_str(), 0); + } else { + ATRACE_INT(mVsyncOffsetLabel.c_str(), 0); + ATRACE_INT(mVsyncNegativeOffsetLabel.c_str(), -mPhaseOffset); + } +} + +} // namespace android diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.h b/services/surfaceflinger/Scheduler/DispSyncSource.h index b6785c5f74..50560a5a2b 100644 --- a/services/surfaceflinger/Scheduler/DispSyncSource.h +++ b/services/surfaceflinger/Scheduler/DispSyncSource.h @@ -39,12 +39,16 @@ private: // The following method is the implementation of the DispSync::Callback. virtual void onDispSyncEvent(nsecs_t when); + void tracePhaseOffset() REQUIRES(mVsyncMutex); + const char* const mName; int mValue = 0; const bool mTraceVsync; const std::string mVsyncOnLabel; const std::string mVsyncEventLabel; + const std::string mVsyncOffsetLabel; + const std::string mVsyncNegativeOffsetLabel; nsecs_t mLastCallbackTime GUARDED_BY(mVsyncMutex) = 0; DispSync* mDispSync; @@ -58,4 +62,4 @@ private: bool mEnabled GUARDED_BY(mVsyncMutex) = false; }; -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp index 276bce1f89..8a2604f4a3 100644 --- a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp +++ b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp @@ -25,6 +25,7 @@ using namespace android::sysprop; namespace scheduler { +using RefreshRateType = RefreshRateConfigs::RefreshRateType; PhaseOffsets::~PhaseOffsets() = default; namespace impl { @@ -72,25 +73,32 @@ PhaseOffsets::PhaseOffsets() { property_get("debug.sf.phase_offset_threshold_for_next_vsync_ns", value, "-1"); const int phaseOffsetThresholdForNextVsyncNs = atoi(value); - mDefaultRefreshRateOffsets.early = {earlySfOffsetNs != -1 ? earlySfOffsetNs - : sfVsyncPhaseOffsetNs, - earlyAppOffsetNs != -1 ? earlyAppOffsetNs - : vsyncPhaseOffsetNs}; - mDefaultRefreshRateOffsets.earlyGl = {earlyGlSfOffsetNs != -1 ? earlyGlSfOffsetNs - : sfVsyncPhaseOffsetNs, - earlyGlAppOffsetNs != -1 ? earlyGlAppOffsetNs - : vsyncPhaseOffsetNs}; - mDefaultRefreshRateOffsets.late = {sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs}; - - mHighRefreshRateOffsets.early = {highFpsEarlySfOffsetNs != -1 ? highFpsEarlySfOffsetNs - : highFpsLateSfOffsetNs, - highFpsEarlyAppOffsetNs != -1 ? highFpsEarlyAppOffsetNs - : highFpsLateAppOffsetNs}; - mHighRefreshRateOffsets.earlyGl = {highFpsEarlyGlSfOffsetNs != -1 ? highFpsEarlyGlSfOffsetNs - : highFpsLateSfOffsetNs, - highFpsEarlyGlAppOffsetNs != -1 ? highFpsEarlyGlAppOffsetNs - : highFpsLateAppOffsetNs}; - mHighRefreshRateOffsets.late = {highFpsLateSfOffsetNs, highFpsLateAppOffsetNs}; + Offsets defaultOffsets; + Offsets highFpsOffsets; + defaultOffsets.early = {RefreshRateType::DEFAULT, + earlySfOffsetNs != -1 ? earlySfOffsetNs : sfVsyncPhaseOffsetNs, + earlyAppOffsetNs != -1 ? earlyAppOffsetNs : vsyncPhaseOffsetNs}; + defaultOffsets.earlyGl = {RefreshRateType::DEFAULT, + earlyGlSfOffsetNs != -1 ? earlyGlSfOffsetNs : sfVsyncPhaseOffsetNs, + earlyGlAppOffsetNs != -1 ? earlyGlAppOffsetNs : vsyncPhaseOffsetNs}; + defaultOffsets.late = {RefreshRateType::DEFAULT, sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs}; + + highFpsOffsets.early = {RefreshRateType::PERFORMANCE, + highFpsEarlySfOffsetNs != -1 ? highFpsEarlySfOffsetNs + : highFpsLateSfOffsetNs, + highFpsEarlyAppOffsetNs != -1 ? highFpsEarlyAppOffsetNs + : highFpsLateAppOffsetNs}; + highFpsOffsets.earlyGl = {RefreshRateType::PERFORMANCE, + highFpsEarlyGlSfOffsetNs != -1 ? highFpsEarlyGlSfOffsetNs + : highFpsLateSfOffsetNs, + highFpsEarlyGlAppOffsetNs != -1 ? highFpsEarlyGlAppOffsetNs + : highFpsLateAppOffsetNs}; + highFpsOffsets.late = {RefreshRateType::PERFORMANCE, highFpsLateSfOffsetNs, + highFpsLateAppOffsetNs}; + + mOffsets.insert({RefreshRateType::POWER_SAVING, defaultOffsets}); + mOffsets.insert({RefreshRateType::DEFAULT, defaultOffsets}); + mOffsets.insert({RefreshRateType::PERFORMANCE, highFpsOffsets}); mOffsetThresholdForNextVsync = phaseOffsetThresholdForNextVsyncNs != -1 ? phaseOffsetThresholdForNextVsyncNs @@ -99,12 +107,7 @@ PhaseOffsets::PhaseOffsets() { PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate( android::scheduler::RefreshRateConfigs::RefreshRateType refreshRateType) const { - switch (refreshRateType) { - case RefreshRateConfigs::RefreshRateType::PERFORMANCE: - return mHighRefreshRateOffsets; - default: - return mDefaultRefreshRateOffsets; - } + return mOffsets.at(refreshRateType); } void PhaseOffsets::dump(std::string& result) const { diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.h b/services/surfaceflinger/Scheduler/PhaseOffsets.h index dc71e6eb60..2b5c2f10f1 100644 --- a/services/surfaceflinger/Scheduler/PhaseOffsets.h +++ b/services/surfaceflinger/Scheduler/PhaseOffsets.h @@ -17,6 +17,7 @@ #pragma once #include <cinttypes> +#include <unordered_map> #include "RefreshRateConfigs.h" #include "VSyncModulator.h" @@ -79,14 +80,10 @@ public: void dump(std::string& result) const override; private: - Offsets getDefaultRefreshRateOffsets() { return mDefaultRefreshRateOffsets; } - Offsets getHighRefreshRateOffsets() { return mHighRefreshRateOffsets; } - std::atomic<RefreshRateConfigs::RefreshRateType> mRefreshRateType = RefreshRateConfigs::RefreshRateType::DEFAULT; - Offsets mDefaultRefreshRateOffsets; - Offsets mHighRefreshRateOffsets; + std::unordered_map<RefreshRateConfigs::RefreshRateType, Offsets> mOffsets; nsecs_t mOffsetThresholdForNextVsync; }; } // namespace impl diff --git a/services/surfaceflinger/Scheduler/VSyncModulator.cpp b/services/surfaceflinger/Scheduler/VSyncModulator.cpp new file mode 100644 index 0000000000..381308ab34 --- /dev/null +++ b/services/surfaceflinger/Scheduler/VSyncModulator.cpp @@ -0,0 +1,178 @@ +/* + * Copyright 2019 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 express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include "VSyncModulator.h" + +#include <cutils/properties.h> +#include <utils/Trace.h> + +#include <cinttypes> +#include <mutex> + +namespace android { + +using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType; +VSyncModulator::VSyncModulator() { + char value[PROPERTY_VALUE_MAX]; + property_get("debug.sf.vsync_trace_detailed_info", value, "0"); + mTraceDetailedInfo = atoi(value); + // Populate the offset map with some default offsets. + const Offsets defaultOffsets = {RefreshRateType::DEFAULT, 0, 0}; + setPhaseOffsets(defaultOffsets, defaultOffsets, defaultOffsets, 0); +} + +void VSyncModulator::setPhaseOffsets(Offsets early, Offsets earlyGl, Offsets late, + nsecs_t thresholdForNextVsync) { + std::lock_guard<std::mutex> lock(mMutex); + mOffsetMap.insert_or_assign(OffsetType::Early, early); + mOffsetMap.insert_or_assign(OffsetType::EarlyGl, earlyGl); + mOffsetMap.insert_or_assign(OffsetType::Late, late); + mThresholdForNextVsync = thresholdForNextVsync; + updateOffsetsLocked(); +} + +void VSyncModulator::setTransactionStart(Scheduler::TransactionStart transactionStart) { + if (transactionStart == Scheduler::TransactionStart::EARLY) { + mRemainingEarlyFrameCount = MIN_EARLY_FRAME_COUNT_TRANSACTION; + } + + // An early transaction stays an early transaction. + if (transactionStart == mTransactionStart || + mTransactionStart == Scheduler::TransactionStart::EARLY) { + return; + } + mTransactionStart = transactionStart; + updateOffsets(); +} + +void VSyncModulator::onTransactionHandled() { + if (mTransactionStart == Scheduler::TransactionStart::NORMAL) return; + mTransactionStart = Scheduler::TransactionStart::NORMAL; + updateOffsets(); +} + +void VSyncModulator::onRefreshRateChangeInitiated() { + if (mRefreshRateChangePending) { + return; + } + mRefreshRateChangePending = true; + updateOffsets(); +} + +void VSyncModulator::onRefreshRateChangeCompleted() { + if (!mRefreshRateChangePending) { + return; + } + mRefreshRateChangePending = false; + updateOffsets(); +} + +void VSyncModulator::onRefreshed(bool usedRenderEngine) { + bool updateOffsetsNeeded = false; + if (mRemainingEarlyFrameCount > 0) { + mRemainingEarlyFrameCount--; + updateOffsetsNeeded = true; + } + if (usedRenderEngine) { + mRemainingRenderEngineUsageCount = MIN_EARLY_GL_FRAME_COUNT_TRANSACTION; + updateOffsetsNeeded = true; + } else if (mRemainingRenderEngineUsageCount > 0) { + mRemainingRenderEngineUsageCount--; + updateOffsetsNeeded = true; + } + if (updateOffsetsNeeded) { + updateOffsets(); + } +} + +VSyncModulator::Offsets VSyncModulator::getOffsets() { + std::lock_guard<std::mutex> lock(mMutex); + return mOffsetMap.at(mOffsetType); +} + +VSyncModulator::Offsets VSyncModulator::getNextOffsets() { + return mOffsetMap.at(getNextOffsetType()); +} + +VSyncModulator::OffsetType VSyncModulator::getNextOffsetType() { + // Early offsets are used if we're in the middle of a refresh rate + // change, or if we recently begin a transaction. + if (mTransactionStart == Scheduler::TransactionStart::EARLY || mRemainingEarlyFrameCount > 0 || + mRefreshRateChangePending) { + return OffsetType::Early; + } else if (mRemainingRenderEngineUsageCount > 0) { + return OffsetType::EarlyGl; + } else { + return OffsetType::Late; + } +} + +void VSyncModulator::updateOffsets() { + std::lock_guard<std::mutex> lock(mMutex); + updateOffsetsLocked(); +} + +void VSyncModulator::updateOffsetsLocked() { + const Offsets desired = getNextOffsets(); + const Offsets current = mOffsetMap.at(mOffsetType); + + bool changed = false; + if (desired.sf != current.sf) { + if (mSfConnectionHandle != nullptr) { + mScheduler->setPhaseOffset(mSfConnectionHandle, desired.sf); + } else { + mSfEventThread->setPhaseOffset(desired.sf); + } + changed = true; + } + if (desired.app != current.app) { + if (mAppConnectionHandle != nullptr) { + mScheduler->setPhaseOffset(mAppConnectionHandle, desired.app); + } else { + mAppEventThread->setPhaseOffset(desired.app); + } + changed = true; + } + + if (changed) { + updateOffsetType(); + } +} + +void VSyncModulator::updateOffsetType() { + mOffsetType = getNextOffsetType(); + if (!mTraceDetailedInfo) { + return; + } + OffsetType type = mOffsetType; + Offsets offsets = mOffsetMap.at(type); + ATRACE_INT("Vsync-EarlyOffsetsOn", + offsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::Early); + ATRACE_INT("Vsync-EarlyGLOffsetsOn", + offsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::EarlyGl); + ATRACE_INT("Vsync-LateOffsetsOn", + offsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::Late); + ATRACE_INT("Vsync-HighFpsEarlyOffsetsOn", + offsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::Early); + ATRACE_INT("Vsync-HighFpsEarlyGLOffsetsOn", + offsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::EarlyGl); + ATRACE_INT("Vsync-HighFpsLateOffsetsOn", + offsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::Late); +} + +} // namespace android diff --git a/services/surfaceflinger/Scheduler/VSyncModulator.h b/services/surfaceflinger/Scheduler/VSyncModulator.h index 73a1fb9816..c6374be83a 100644 --- a/services/surfaceflinger/Scheduler/VSyncModulator.h +++ b/services/surfaceflinger/Scheduler/VSyncModulator.h @@ -16,8 +16,6 @@ #pragma once -#include <utils/Errors.h> - #include <cinttypes> #include <mutex> @@ -41,11 +39,22 @@ private: const int MIN_EARLY_GL_FRAME_COUNT_TRANSACTION = 2; public: + VSyncModulator(); + + // Wrapper for a collection of surfaceflinger/app offsets for a particular + // configuration . struct Offsets { + scheduler::RefreshRateConfigs::RefreshRateType fpsMode; nsecs_t sf; nsecs_t app; }; + enum class OffsetType { + Early, + EarlyGl, + Late, + }; + // Sets the phase offsets // // sfEarly: The phase offset when waking up SF early, which happens when marking a transaction @@ -57,32 +66,15 @@ public: // appEarlyGl: Like sfEarlyGl, but for the app-vsync. // appLate: The regular app vsync phase offset. void setPhaseOffsets(Offsets early, Offsets earlyGl, Offsets late, - nsecs_t thresholdForNextVsync) { - mEarlyOffsets = early; - mEarlyGlOffsets = earlyGl; - mLateOffsets = late; - mThresholdForNextVsync = thresholdForNextVsync; - - if (mSfConnectionHandle && late.sf != mOffsets.load().sf) { - mScheduler->setPhaseOffset(mSfConnectionHandle, late.sf); - } - - if (mAppConnectionHandle && late.app != mOffsets.load().app) { - mScheduler->setPhaseOffset(mAppConnectionHandle, late.app); - } - - mOffsets = late; - } - - Offsets getEarlyOffsets() const { return mEarlyOffsets; } - - Offsets getEarlyGlOffsets() const { return mEarlyGlOffsets; } + nsecs_t thresholdForNextVsync) EXCLUDES(mMutex); + // Sets handles to the SF and app event threads. void setEventThreads(EventThread* sfEventThread, EventThread* appEventThread) { mSfEventThread = sfEventThread; mAppEventThread = appEventThread; } + // Sets the scheduler and vsync connection handlers. void setSchedulerAndHandles(Scheduler* scheduler, Scheduler::ConnectionHandle* appConnectionHandle, Scheduler::ConnectionHandle* sfConnectionHandle) { @@ -91,109 +83,42 @@ public: mSfConnectionHandle = sfConnectionHandle; } - void setTransactionStart(Scheduler::TransactionStart transactionStart) { - if (transactionStart == Scheduler::TransactionStart::EARLY) { - mRemainingEarlyFrameCount = MIN_EARLY_FRAME_COUNT_TRANSACTION; - } - - // An early transaction stays an early transaction. - if (transactionStart == mTransactionStart || - mTransactionStart == Scheduler::TransactionStart::EARLY) { - return; - } - mTransactionStart = transactionStart; - updateOffsets(); - } + // Signals that a transaction has started, and changes offsets accordingly. + void setTransactionStart(Scheduler::TransactionStart transactionStart); - void onTransactionHandled() { - if (mTransactionStart == Scheduler::TransactionStart::NORMAL) return; - mTransactionStart = Scheduler::TransactionStart::NORMAL; - updateOffsets(); - } + // Signals that a transaction has been completed, so that we can finish + // special handling for a transaction. + void onTransactionHandled(); // Called when we send a refresh rate change to hardware composer, so that // we can move into early offsets. - void onRefreshRateChangeInitiated() { - if (mRefreshRateChangePending) { - return; - } - mRefreshRateChangePending = true; - updateOffsets(); - } + void onRefreshRateChangeInitiated(); // Called when we detect from vsync signals that the refresh rate changed. // This way we can move out of early offsets if no longer necessary. - void onRefreshRateChangeCompleted() { - if (!mRefreshRateChangePending) { - return; - } - mRefreshRateChangePending = false; - updateOffsets(); - } + void onRefreshRateChangeCompleted(); - void onRefreshed(bool usedRenderEngine) { - bool updateOffsetsNeeded = false; - if (mRemainingEarlyFrameCount > 0) { - mRemainingEarlyFrameCount--; - updateOffsetsNeeded = true; - } - if (usedRenderEngine) { - mRemainingRenderEngineUsageCount = MIN_EARLY_GL_FRAME_COUNT_TRANSACTION; - updateOffsetsNeeded = true; - } else if (mRemainingRenderEngineUsageCount > 0) { - mRemainingRenderEngineUsageCount--; - updateOffsetsNeeded = true; - } - - if (updateOffsetsNeeded) { - updateOffsets(); - } - } + // Called when the display is presenting a new frame. usedRenderEngine + // should be set to true if RenderEngine was involved with composing the new + // frame. + void onRefreshed(bool usedRenderEngine); - Offsets getOffsets() { - // Early offsets are used if we're in the middle of a refresh rate - // change, or if we recently begin a transaction. - if (mTransactionStart == Scheduler::TransactionStart::EARLY || - mRemainingEarlyFrameCount > 0 || mRefreshRateChangePending) { - return mEarlyOffsets; - } else if (mRemainingRenderEngineUsageCount > 0) { - return mEarlyGlOffsets; - } else { - return mLateOffsets; - } - } + // Returns the offsets that we are currently using + Offsets getOffsets() EXCLUDES(mMutex); private: - void updateOffsets() { - const Offsets desired = getOffsets(); - const Offsets current = mOffsets; - - bool changed = false; - if (desired.sf != current.sf) { - if (mSfConnectionHandle != nullptr) { - mScheduler->setPhaseOffset(mSfConnectionHandle, desired.sf); - } else { - mSfEventThread->setPhaseOffset(desired.sf); - } - changed = true; - } - if (desired.app != current.app) { - if (mAppConnectionHandle != nullptr) { - mScheduler->setPhaseOffset(mAppConnectionHandle, desired.app); - } else { - mAppEventThread->setPhaseOffset(desired.app); - } - changed = true; - } - - if (changed) { - mOffsets = desired; - } - } - - Offsets mLateOffsets; - Offsets mEarlyOffsets; - Offsets mEarlyGlOffsets; + // Returns the next offsets that we should be using + Offsets getNextOffsets() REQUIRES(mMutex); + // Returns the next offset type that we should use. + OffsetType getNextOffsetType(); + // Updates offsets and persists them into the scheduler framework. + void updateOffsets() EXCLUDES(mMutex); + void updateOffsetsLocked() REQUIRES(mMutex); + // Updates the internal offset type. + void updateOffsetType() REQUIRES(mMutex); + + mutable std::mutex mMutex; + std::unordered_map<OffsetType, Offsets> mOffsetMap GUARDED_BY(mMutex); nsecs_t mThresholdForNextVsync; EventThread* mSfEventThread = nullptr; @@ -203,13 +128,15 @@ private: Scheduler::ConnectionHandle* mAppConnectionHandle = nullptr; Scheduler::ConnectionHandle* mSfConnectionHandle = nullptr; - std::atomic<Offsets> mOffsets; + OffsetType mOffsetType GUARDED_BY(mMutex) = OffsetType::Late; std::atomic<Scheduler::TransactionStart> mTransactionStart = Scheduler::TransactionStart::NORMAL; std::atomic<bool> mRefreshRateChangePending = false; std::atomic<int> mRemainingEarlyFrameCount = 0; std::atomic<int> mRemainingRenderEngineUsageCount = 0; + + bool mTraceDetailedInfo = false; }; } // namespace android diff --git a/services/surfaceflinger/test.png b/services/surfaceflinger/test.png Binary files differnew file mode 100644 index 0000000000..773dcc3e72 --- /dev/null +++ b/services/surfaceflinger/test.png diff --git a/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h b/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h index 96121bb088..1d7501102e 100644 --- a/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h +++ b/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h @@ -23,6 +23,8 @@ namespace android { namespace scheduler { +using RefreshRateType = RefreshRateConfigs::RefreshRateType; + class FakePhaseOffsets : public android::scheduler::PhaseOffsets { nsecs_t FAKE_PHASE_OFFSET_NS = 0; @@ -34,20 +36,20 @@ public: nsecs_t getCurrentSfOffset() override { return FAKE_PHASE_OFFSET_NS; } PhaseOffsets::Offsets getOffsetsForRefreshRate( - RefreshRateConfigs::RefreshRateType /*refreshRateType*/) const override { + RefreshRateType /*refreshRateType*/) const override { return getCurrentOffsets(); } // Returns early, early GL, and late offsets for Apps and SF. PhaseOffsets::Offsets getCurrentOffsets() const override { - return Offsets{{FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS}, - {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS}, - {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS}}; + return Offsets{{RefreshRateType::DEFAULT, FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS}, + {RefreshRateType::DEFAULT, FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS}, + {RefreshRateType::DEFAULT, FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS}}; } // This function should be called when the device is switching between different // refresh rates, to properly update the offsets. - void setRefreshRateType(RefreshRateConfigs::RefreshRateType /*refreshRateType*/) override {} + void setRefreshRateType(RefreshRateType /*refreshRateType*/) override {} nsecs_t getOffsetThresholdForNextVsync() const override { return FAKE_PHASE_OFFSET_NS; } @@ -56,4 +58,4 @@ public: }; } // namespace scheduler -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp index d9df204824..4c34b938c8 100644 --- a/services/vr/hardware_composer/Android.bp +++ b/services/vr/hardware_composer/Android.bp @@ -137,7 +137,7 @@ cc_binary { "libbinder", "liblog", "libhardware", - "libhwbinder", + "libhidlbase", "libui", "libutils", "libvr_hwc-hal", |