summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author android-build-team Robot <android-build-team-robot@google.com> 2019-06-22 23:15:53 +0000
committer android-build-team Robot <android-build-team-robot@google.com> 2019-06-22 23:15:53 +0000
commitae4a385d20f35faba4e39332f2cd033c2efd330c (patch)
tree41d2ea9abe259f249173aa10a46bfa5ffff97735
parent5531408797caca34a22d7f9c0b787fcf7ad8d67d (diff)
parent769ab6f949369468ee6355d00e490ad14a2f3721 (diff)
Snap for 5681502 from 769ab6f949369468ee6355d00e490ad14a2f3721 to qt-c2f2-release
Change-Id: I9f4d5bdd481032a7dcdda906446c02adef836bdf
-rw-r--r--services/surfaceflinger/Android.bp3
-rw-r--r--services/surfaceflinger/RegionSamplingThread.cpp16
-rw-r--r--services/surfaceflinger/Scheduler/DispSyncSource.cpp24
-rw-r--r--services/surfaceflinger/Scheduler/DispSyncSource.h6
-rw-r--r--services/surfaceflinger/Scheduler/PhaseOffsets.cpp53
-rw-r--r--services/surfaceflinger/Scheduler/PhaseOffsets.h7
-rw-r--r--services/surfaceflinger/Scheduler/VSyncModulator.cpp178
-rw-r--r--services/surfaceflinger/Scheduler/VSyncModulator.h157
-rw-r--r--services/surfaceflinger/test.pngbin0 -> 3058273 bytes
-rw-r--r--services/surfaceflinger/tests/unittests/FakePhaseOffsets.h14
-rw-r--r--services/vr/hardware_composer/Android.bp2
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
new file mode 100644
index 0000000000..773dcc3e72
--- /dev/null
+++ b/services/surfaceflinger/test.png
Binary files differ
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",