Merge changes from topic 'single_buffer_mode'
* changes:
SF: Force refresh when in single buffer mode
BQ: Add support for single buffer mode
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 7324907..8bba81b 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -99,6 +99,7 @@
} },
{ "irq", "IRQ Events", 0, {
{ REQ, "/sys/kernel/debug/tracing/events/irq/enable" },
+ { OPT, "/sys/kernel/debug/tracing/events/ipi/enable" },
} },
{ "freq", "CPU Frequency", 0, {
{ REQ, "/sys/kernel/debug/tracing/events/power/cpu_frequency/enable" },
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 1da7308..e460059 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -314,9 +314,7 @@
dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
dump_file("KERNEL SYNC", "/d/sync");
- run_command("PROCESSES", 10, "ps", "-P", NULL);
- run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
- run_command("PROCESSES (SELINUX LABELS)", 10, "ps", "-Z", NULL);
+ run_command("PROCESSES AND THREADS", 10, "ps", "-Z", "-t", "-p", "-P", NULL);
run_command("LIBRANK", 10, "librank", NULL);
do_dmesg();
diff --git a/include/batteryservice/BatteryService.h b/include/batteryservice/BatteryService.h
index 9a8e2f7..912dcf6 100644
--- a/include/batteryservice/BatteryService.h
+++ b/include/batteryservice/BatteryService.h
@@ -58,6 +58,7 @@
bool chargerUsbOnline;
bool chargerWirelessOnline;
int maxChargingCurrent;
+ int maxChargingVoltage;
int batteryStatus;
int batteryHealth;
bool batteryPresent;
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index ae76ffb..430c3ff 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -125,6 +125,8 @@
status_t writeCharVector(const std::vector<char16_t>& val);
status_t writeString16Vector(const std::vector<String16>& val);
+ status_t writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
+
template<typename T>
status_t write(const Flattenable<T>& val);
@@ -202,7 +204,9 @@
wp<IBinder> readWeakBinder() const;
template<typename T>
- status_t readStrongBinder(sp<T>* val) const;
+ status_t readStrongBinder(sp<T>* val) const;
+
+ status_t readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
status_t readByteVector(std::vector<int8_t>* val) const;
status_t readInt32Vector(std::vector<int32_t>* val) const;
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index f9d0e7d..b7aa463 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -74,7 +74,7 @@
height(0),
format(PIXEL_FORMAT_NONE),
stride(0),
- crop(0, 0, 0, 0),
+ crop(Rect::EMPTY_RECT),
transform(0),
scalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
timestamp(0),
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 4c80f43..56cde8a 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -745,25 +745,25 @@
status_t Parcel::writeByteVector(const std::vector<int8_t>& val)
{
+ status_t status;
if (val.size() > std::numeric_limits<int32_t>::max()) {
- return BAD_VALUE;
+ status = BAD_VALUE;
+ return status;
}
- status_t status = writeInt32(val.size());
-
+ status = writeInt32(val.size());
if (status != OK) {
return status;
}
- for (const auto& item : val) {
- status = writeByte(item);
-
- if (status != OK) {
- return status;
- }
+ void* data = writeInplace(val.size());
+ if (!data) {
+ status = BAD_VALUE;
+ return status;
}
- return OK;
+ memcpy(data, val.data(), val.size());
+ return status;
}
status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
@@ -1071,6 +1071,56 @@
return flatten_binder(ProcessState::self(), val, this);
}
+status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeStrongBinder(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->resize(size);
+
+ for (auto& v : *val) {
+ status = readStrongBinder(&v);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
@@ -1367,21 +1417,19 @@
return status;
}
- if (size < 0) {
- return BAD_VALUE;
+ if (size < 0 || size_t(size) > dataAvail()) {
+ status = BAD_VALUE;
+ return status;
}
-
+ const void* data = readInplace(size);
+ if (!data) {
+ status = BAD_VALUE;
+ return status;
+ }
val->resize(size);
+ memcpy(val->data(), data, size);
- for (auto& v : *val) {
- status = readByte(&v);
-
- if (status != OK) {
- return status;
- }
- }
-
- return OK;
+ return status;
}
status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
diff --git a/services/batteryservice/BatteryProperties.cpp b/services/batteryservice/BatteryProperties.cpp
index f13d6e8..07cc797 100644
--- a/services/batteryservice/BatteryProperties.cpp
+++ b/services/batteryservice/BatteryProperties.cpp
@@ -34,6 +34,7 @@
chargerUsbOnline = p->readInt32() == 1 ? true : false;
chargerWirelessOnline = p->readInt32() == 1 ? true : false;
maxChargingCurrent = p->readInt32();
+ maxChargingVoltage = p->readInt32();
batteryStatus = p->readInt32();
batteryHealth = p->readInt32();
batteryPresent = p->readInt32() == 1 ? true : false;
@@ -49,6 +50,7 @@
p->writeInt32(chargerUsbOnline ? 1 : 0);
p->writeInt32(chargerWirelessOnline ? 1 : 0);
p->writeInt32(maxChargingCurrent);
+ p->writeInt32(maxChargingVoltage);
p->writeInt32(batteryStatus);
p->writeInt32(batteryHealth);
p->writeInt32(batteryPresent ? 1 : 0);
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 3738a55..5ba387d 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -56,15 +56,17 @@
mStop(false),
mPeriod(0),
mPhase(0),
+ mReferenceTime(0),
mWakeupLatency(0) {
}
virtual ~DispSyncThread() {}
- void updateModel(nsecs_t period, nsecs_t phase) {
+ void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {
Mutex::Autolock lock(mMutex);
mPeriod = period;
mPhase = phase;
+ mReferenceTime = referenceTime;
mCond.signal();
}
@@ -246,7 +248,7 @@
ref = lastEventTime;
}
- nsecs_t phase = mPhase + listener.mPhase;
+ nsecs_t phase = mReferenceTime + mPhase + listener.mPhase;
nsecs_t t = (((ref - phase) / mPeriod) + 1) * mPeriod + phase;
if (t - listener.mLastEventTime < mPeriod / 2) {
@@ -266,6 +268,7 @@
nsecs_t mPeriod;
nsecs_t mPhase;
+ nsecs_t mReferenceTime;
nsecs_t mWakeupLatency;
Vector<EventListener> mEventListeners;
@@ -313,6 +316,9 @@
void DispSync::reset() {
Mutex::Autolock lock(mMutex);
+ mPhase = 0;
+ mReferenceTime = 0;
+ mModelUpdated = false;
mNumResyncSamples = 0;
mFirstResyncSample = 0;
mNumResyncSamplesSincePresent = 0;
@@ -340,12 +346,13 @@
updateErrorLocked();
- return mPeriod == 0 || mError > kErrorThreshold;
+ return !mModelUpdated || mError > kErrorThreshold;
}
void DispSync::beginResync() {
Mutex::Autolock lock(mMutex);
+ mModelUpdated = false;
mNumResyncSamples = 0;
}
@@ -354,6 +361,10 @@
size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
mResyncSamples[idx] = timestamp;
+ if (mNumResyncSamples == 0) {
+ mPhase = 0;
+ mReferenceTime = timestamp;
+ }
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
mNumResyncSamples++;
@@ -376,7 +387,7 @@
return mThread->hasAnyEventListeners();
}
- return mPeriod == 0 || mError > kErrorThreshold;
+ return !mModelUpdated || mError > kErrorThreshold;
}
void DispSync::endResync() {
@@ -405,7 +416,8 @@
Mutex::Autolock lock(mMutex);
mPeriod = period;
mPhase = 0;
- mThread->updateModel(mPeriod, mPhase);
+ mReferenceTime = 0;
+ mThread->updateModel(mPeriod, mPhase, mReferenceTime);
}
nsecs_t DispSync::getPeriod() {
@@ -430,7 +442,7 @@
double scale = 2.0 * M_PI / double(mPeriod);
for (size_t i = 0; i < mNumResyncSamples; i++) {
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
- nsecs_t sample = mResyncSamples[idx];
+ nsecs_t sample = mResyncSamples[idx] - mReferenceTime;
double samplePhase = double(sample % mPeriod) * scale;
sampleAvgX += cos(samplePhase);
sampleAvgY += sin(samplePhase);
@@ -453,12 +465,13 @@
// Artificially inflate the period if requested.
mPeriod += mPeriod * mRefreshSkipCount;
- mThread->updateModel(mPeriod, mPhase);
+ mThread->updateModel(mPeriod, mPhase, mReferenceTime);
+ mModelUpdated = true;
}
}
void DispSync::updateErrorLocked() {
- if (mPeriod == 0) {
+ if (!mModelUpdated) {
return;
}
@@ -470,7 +483,7 @@
nsecs_t sqErrSum = 0;
for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
- nsecs_t sample = mPresentTimes[i];
+ nsecs_t sample = mPresentTimes[i] - mReferenceTime;
if (sample > mPhase) {
nsecs_t sampleErr = (sample - mPhase) % period;
if (sampleErr > period / 2) {
@@ -504,7 +517,8 @@
nsecs_t DispSync::computeNextRefresh(int periodOffset) const {
Mutex::Autolock lock(mMutex);
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- return (((now - mPhase) / mPeriod) + periodOffset + 1) * mPeriod + mPhase;
+ nsecs_t phase = mReferenceTime + mPhase;
+ return (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase;
}
void DispSync::dump(String8& result) const {
diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h
index 67142b6..a8524b9 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -149,11 +149,18 @@
// number of nanoseconds from time 0 to the first vsync event.
nsecs_t mPhase;
+ // mReferenceTime is the reference time of the modeled vsync events.
+ // It is the nanosecond timestamp of the first vsync event after a resync.
+ nsecs_t mReferenceTime;
+
// mError is the computed model error. It is based on the difference
// between the estimated vsync event times and those observed in the
// mPresentTimes array.
nsecs_t mError;
+ // Whether we have updated the vsync event model since the last resync.
+ bool mModelUpdated;
+
// These member variables are the state used during the resynchronization
// process to store information about the hardware vsync event times used
// to compute the model.