Merge "Enable InputDeviceMetricsCollector" into udc-qpr-dev
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index ed69100..53a2f64 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1792,19 +1792,20 @@
int Surface::dispatchSetFrameTimelineInfo(va_list args) {
ATRACE_CALL();
- auto frameNumber = static_cast<uint64_t>(va_arg(args, uint64_t));
- auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t));
- auto inputEventId = static_cast<int32_t>(va_arg(args, int32_t));
- auto startTimeNanos = static_cast<int64_t>(va_arg(args, int64_t));
- auto useForRefreshRateSelection = static_cast<bool>(va_arg(args, int32_t));
-
ALOGV("Surface::%s", __func__);
+
+ const auto nativeWindowFtlInfo = static_cast<ANativeWindowFrameTimelineInfo>(
+ va_arg(args, ANativeWindowFrameTimelineInfo));
+
FrameTimelineInfo ftlInfo;
- ftlInfo.vsyncId = frameTimelineVsyncId;
- ftlInfo.inputEventId = inputEventId;
- ftlInfo.startTimeNanos = startTimeNanos;
- ftlInfo.useForRefreshRateSelection = useForRefreshRateSelection;
- return setFrameTimelineInfo(frameNumber, ftlInfo);
+ ftlInfo.vsyncId = nativeWindowFtlInfo.frameTimelineVsyncId;
+ ftlInfo.inputEventId = nativeWindowFtlInfo.inputEventId;
+ ftlInfo.startTimeNanos = nativeWindowFtlInfo.startTimeNanos;
+ ftlInfo.useForRefreshRateSelection = nativeWindowFtlInfo.useForRefreshRateSelection;
+ ftlInfo.skippedFrameVsyncId = nativeWindowFtlInfo.skippedFrameVsyncId;
+ ftlInfo.skippedFrameStartTimeNanos = nativeWindowFtlInfo.skippedFrameStartTimeNanos;
+
+ return setFrameTimelineInfo(nativeWindowFtlInfo.frameNumber, ftlInfo);
}
bool Surface::transformToDisplayInverse() const {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0fda358..5bc05ef 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1027,7 +1027,7 @@
mEarlyWakeupEnd = false;
mDesiredPresentTime = 0;
mIsAutoTimestamp = true;
- clearFrameTimelineInfo(mFrameTimelineInfo);
+ mFrameTimelineInfo = {};
mApplyToken = nullptr;
mMergedTransactionIds.clear();
}
@@ -2279,27 +2279,13 @@
if (t.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID &&
other.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
if (other.vsyncId > t.vsyncId) {
- t.vsyncId = other.vsyncId;
- t.inputEventId = other.inputEventId;
- t.startTimeNanos = other.startTimeNanos;
- t.useForRefreshRateSelection = other.useForRefreshRateSelection;
+ t = other;
}
} else if (t.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
- t.vsyncId = other.vsyncId;
- t.inputEventId = other.inputEventId;
- t.startTimeNanos = other.startTimeNanos;
- t.useForRefreshRateSelection = other.useForRefreshRateSelection;
+ t = other;
}
}
-// copied from FrameTimelineInfo::clear()
-void SurfaceComposerClient::Transaction::clearFrameTimelineInfo(FrameTimelineInfo& t) {
- t.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
- t.inputEventId = os::IInputConstants::INVALID_INPUT_EVENT_ID;
- t.startTimeNanos = 0;
- t.useForRefreshRateSelection = false;
-}
-
SurfaceComposerClient::Transaction&
SurfaceComposerClient::Transaction::setTrustedPresentationCallback(
const sp<SurfaceControl>& sc, TrustedPresentationCallback cb,
diff --git a/libs/gui/aidl/android/gui/FrameTimelineInfo.aidl b/libs/gui/aidl/android/gui/FrameTimelineInfo.aidl
index 6a86c6a..4b647a4 100644
--- a/libs/gui/aidl/android/gui/FrameTimelineInfo.aidl
+++ b/libs/gui/aidl/android/gui/FrameTimelineInfo.aidl
@@ -37,4 +37,10 @@
// Whether this vsyncId should be used to heuristically select the display refresh rate
// TODO(b/281695725): Clean this up once TextureView use setFrameRate API
boolean useForRefreshRateSelection = false;
+
+ // The VsyncId of a frame that was not drawn and squashed into this frame.
+ long skippedFrameVsyncId = INVALID_VSYNC_ID;
+
+ // The start time of a frame that was not drawn and squashed into this frame.
+ long skippedFrameStartTimeNanos = 0;
}
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index fb57f63..3cf57b1 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -410,7 +410,6 @@
static sp<IBinder> sApplyToken;
void releaseBufferIfOverwriting(const layer_state_t& state);
static void mergeFrameTimelineInfo(FrameTimelineInfo& t, const FrameTimelineInfo& other);
- static void clearFrameTimelineInfo(FrameTimelineInfo& t);
protected:
std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> mComposerStates;
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index f6b4648..4ecb641 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -4,6 +4,7 @@
// Provides a shared memory transport for input events.
//
#define LOG_TAG "InputTransport"
+#define ATRACE_TAG ATRACE_TAG_INPUT
#include <errno.h>
#include <fcntl.h>
@@ -449,6 +450,13 @@
ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ sent message of type %s", mName.c_str(),
ftl::enum_string(msg->header.type).c_str());
+
+ if (ATRACE_ENABLED()) {
+ std::string message =
+ StringPrintf("sendMessage(inputChannel=%s, seq=0x%" PRIx32 ", type=0x%" PRIx32 ")",
+ mName.c_str(), msg->header.seq, msg->header.type);
+ ATRACE_NAME(message.c_str());
+ }
return OK;
}
@@ -484,6 +492,13 @@
ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ received message of type %s", mName.c_str(),
ftl::enum_string(msg->header.type).c_str());
+
+ if (ATRACE_ENABLED()) {
+ std::string message = StringPrintf("receiveMessage(inputChannel=%s, seq=0x%" PRIx32
+ ", type=0x%" PRIx32 ")",
+ mName.c_str(), msg->header.seq, msg->header.type);
+ ATRACE_NAME(message.c_str());
+ }
return OK;
}
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 0fee3c1..edaa422 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -1066,12 +1066,33 @@
(int)compatibility, (int)changeFrameRateStrategy);
}
+struct ANativeWindowFrameTimelineInfo {
+ // Frame Id received from ANativeWindow_getNextFrameId.
+ uint64_t frameNumber;
+
+ // VsyncId received from the Choreographer callback that started this frame.
+ int64_t frameTimelineVsyncId;
+
+ // Input Event ID received from the input event that started this frame.
+ int32_t inputEventId;
+
+ // The time which this frame rendering started (i.e. when Choreographer callback actually run)
+ int64_t startTimeNanos;
+
+ // Whether or not to use the vsyncId to determine the refresh rate. Used for TextureView only.
+ int32_t useForRefreshRateSelection;
+
+ // The VsyncId of a frame that was not drawn and squashed into this frame.
+ // Used for UI thread updates that were not picked up by RenderThread on time.
+ int64_t skippedFrameVsyncId;
+
+ // The start time of a frame that was not drawn and squashed into this frame.
+ int64_t skippedFrameStartTimeNanos;
+};
+
static inline int native_window_set_frame_timeline_info(
- struct ANativeWindow* window, uint64_t frameNumber, int64_t frameTimelineVsyncId,
- int32_t inputEventId, int64_t startTimeNanos, int32_t useForRefreshRateSelection) {
- return window->perform(window, NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO, frameNumber,
- frameTimelineVsyncId, inputEventId, startTimeNanos,
- useForRefreshRateSelection);
+ struct ANativeWindow* window, struct ANativeWindowFrameTimelineInfo frameTimelineInfo) {
+ return window->perform(window, NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO, frameTimelineInfo);
}
// ------------------------------------------------------------------------------------------------
diff --git a/libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp b/libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp
index acb9b79..bbe58e0 100644
--- a/libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp
+++ b/libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp
@@ -249,7 +249,7 @@
jpegGainMap.data = gainMapEncoder.getCompressedImagePtr();
jpegGainMap.colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED;
ultrahdr_metadata_struct metadata;
- metadata.version = "1.3.1";
+ metadata.version = "1.0";
if (tf == ULTRAHDR_TF_HLG) {
metadata.maxContentBoost = kHlgMaxNits / kSdrWhiteNits;
} else if (tf == ULTRAHDR_TF_PQ) {
@@ -258,6 +258,11 @@
metadata.maxContentBoost = 1.0f;
}
metadata.minContentBoost = 1.0f;
+ metadata.gamma = 1.0f;
+ metadata.offsetSdr = 0.0f;
+ metadata.offsetHdr = 0.0f;
+ metadata.hdrCapacityMin = 1.0f;
+ metadata.hdrCapacityMax = metadata.maxContentBoost;
status = jpegHdr.encodeJPEGR(&jpegImg, &jpegGainMap, &metadata, &jpegImgR);
}
}
diff --git a/libs/ultrahdr/include/ultrahdr/gainmapmath.h b/libs/ultrahdr/include/ultrahdr/gainmapmath.h
index 13832db..edf152d 100644
--- a/libs/ultrahdr/include/ultrahdr/gainmapmath.h
+++ b/libs/ultrahdr/include/ultrahdr/gainmapmath.h
@@ -414,6 +414,10 @@
/*
* Calculate the 8-bit unsigned integer gain value for the given SDR and HDR
* luminances in linear space, and the hdr ratio to encode against.
+ *
+ * Note: since this library always uses gamma of 1.0, offsetSdr of 0.0, and
+ * offsetHdr of 0.0, this function doesn't handle different metadata values for
+ * these fields.
*/
uint8_t encodeGain(float y_sdr, float y_hdr, ultrahdr_metadata_ptr metadata);
uint8_t encodeGain(float y_sdr, float y_hdr, ultrahdr_metadata_ptr metadata,
@@ -422,6 +426,10 @@
/*
* Calculates the linear luminance in nits after applying the given gain
* value, with the given hdr ratio, to the given sdr input in the range [0, 1].
+ *
+ * Note: similar to encodeGain(), this function only supports gamma 1.0,
+ * offsetSdr 0.0, offsetHdr 0.0, hdrCapacityMin 1.0, and hdrCapacityMax equal to
+ * gainMapMax, as this library encodes.
*/
Color applyGain(Color e, float gain, ultrahdr_metadata_ptr metadata);
Color applyGain(Color e, float gain, ultrahdr_metadata_ptr metadata, float displayBoost);
diff --git a/libs/ultrahdr/include/ultrahdr/jpegr.h b/libs/ultrahdr/include/ultrahdr/jpegr.h
index 9546ca4..a35fd30 100644
--- a/libs/ultrahdr/include/ultrahdr/jpegr.h
+++ b/libs/ultrahdr/include/ultrahdr/jpegr.h
@@ -222,7 +222,11 @@
* Decompress JPEGR image.
*
* This method assumes that the JPEGR image contains an ICC profile with primaries that match
- * those of a color gamut that this library is aware of; Bt.709, Display-P3, or Bt.2100.
+ * those of a color gamut that this library is aware of; Bt.709, Display-P3, or Bt.2100. It also
+ * assumes the base image uses the sRGB transfer function.
+ *
+ * This method only supports single gain map metadata values for fields that allow multi-channel
+ * metadata values.
*
* @param compressed_jpegr_image compressed JPEGR image.
* @param dest destination of the uncompressed JPEGR image.
@@ -265,6 +269,9 @@
/*
* Gets Info from JPEGR file without decoding it.
*
+ * This method only supports single gain map metadata values for fields that allow multi-channel
+ * metadata values.
+ *
* The output is filled jpegr_info structure
* @param compressed_jpegr_image compressed JPEGR image
* @param jpegr_info pointer to output JPEGR info. Members of jpegr_info
diff --git a/libs/ultrahdr/include/ultrahdr/jpegrerrorcode.h b/libs/ultrahdr/include/ultrahdr/jpegrerrorcode.h
index 9f59c3e..0641232 100644
--- a/libs/ultrahdr/include/ultrahdr/jpegrerrorcode.h
+++ b/libs/ultrahdr/include/ultrahdr/jpegrerrorcode.h
@@ -42,6 +42,8 @@
ERROR_JPEGR_BUFFER_TOO_SMALL = JPEGR_IO_ERROR_BASE - 4,
ERROR_JPEGR_INVALID_COLORGAMUT = JPEGR_IO_ERROR_BASE - 5,
ERROR_JPEGR_INVALID_TRANS_FUNC = JPEGR_IO_ERROR_BASE - 6,
+ ERROR_JPEGR_INVALID_METADATA = JPEGR_IO_ERROR_BASE - 7,
+ ERROR_JPEGR_UNSUPPORTED_METADATA = JPEGR_IO_ERROR_BASE - 8,
JPEGR_RUNTIME_ERROR_BASE = -20000,
ERROR_JPEGR_ENCODE_ERROR = JPEGR_RUNTIME_ERROR_BASE - 1,
diff --git a/libs/ultrahdr/include/ultrahdr/ultrahdr.h b/libs/ultrahdr/include/ultrahdr/ultrahdr.h
index 21751b4..17cc971 100644
--- a/libs/ultrahdr/include/ultrahdr/ultrahdr.h
+++ b/libs/ultrahdr/include/ultrahdr/ultrahdr.h
@@ -49,14 +49,28 @@
/*
* Holds information for gain map related metadata.
+ *
+ * Not: all values stored in linear. This differs from the metadata encoding in XMP, where
+ * maxContentBoost (aka gainMapMax), minContentBoost (aka gainMapMin), hdrCapacityMin, and
+ * hdrCapacityMax are stored in log2 space.
*/
struct ultrahdr_metadata_struct {
- // Ultra HDR library version
+ // Ultra HDR format version
std::string version;
// Max Content Boost for the map
float maxContentBoost;
// Min Content Boost for the map
float minContentBoost;
+ // Gamma of the map data
+ float gamma;
+ // Offset for SDR data in map calculations
+ float offsetSdr;
+ // Offset for HDR data in map calculations
+ float offsetHdr;
+ // HDR capacity to apply the map at all
+ float hdrCapacityMin;
+ // HDR capacity to apply the map completely
+ float hdrCapacityMax;
};
typedef struct ultrahdr_metadata_struct* ultrahdr_metadata_ptr;
diff --git a/libs/ultrahdr/jpegr.cpp b/libs/ultrahdr/jpegr.cpp
index 9af5af7..9c57f34 100644
--- a/libs/ultrahdr/jpegr.cpp
+++ b/libs/ultrahdr/jpegr.cpp
@@ -644,13 +644,18 @@
ultrahdr_metadata_struct uhdr_metadata;
if (!getMetadataFromXMP(static_cast<uint8_t*>(gain_map_decoder.getXMPPtr()),
gain_map_decoder.getXMPSize(), &uhdr_metadata)) {
- return ERROR_JPEGR_DECODE_ERROR;
+ return ERROR_JPEGR_INVALID_METADATA;
}
if (metadata != nullptr) {
metadata->version = uhdr_metadata.version;
metadata->minContentBoost = uhdr_metadata.minContentBoost;
metadata->maxContentBoost = uhdr_metadata.maxContentBoost;
+ metadata->gamma = uhdr_metadata.gamma;
+ metadata->offsetSdr = uhdr_metadata.offsetSdr;
+ metadata->offsetHdr = uhdr_metadata.offsetHdr;
+ metadata->hdrCapacityMin = uhdr_metadata.hdrCapacityMin;
+ metadata->hdrCapacityMax = uhdr_metadata.hdrCapacityMax;
}
if (output_format == ULTRAHDR_OUTPUT_SDR) {
@@ -840,6 +845,12 @@
metadata->maxContentBoost = hdr_white_nits / kSdrWhiteNits;
metadata->minContentBoost = 1.0f;
+ metadata->gamma = 1.0f;
+ metadata->offsetSdr = 0.0f;
+ metadata->offsetHdr = 0.0f;
+ metadata->hdrCapacityMin = 1.0f;
+ metadata->hdrCapacityMax = metadata->maxContentBoost;
+
float log2MinBoost = log2(metadata->minContentBoost);
float log2MaxBoost = log2(metadata->maxContentBoost);
@@ -958,6 +969,26 @@
return ERROR_JPEGR_INVALID_NULL_PTR;
}
+ if (metadata->version.compare("1.0")) {
+ ALOGE("Unsupported metadata version: %s", metadata->version.c_str());
+ return ERROR_JPEGR_UNSUPPORTED_METADATA;
+ }
+ if (metadata->gamma != 1.0f) {
+ ALOGE("Unsupported metadata gamma: %f", metadata->gamma);
+ return ERROR_JPEGR_UNSUPPORTED_METADATA;
+ }
+ if (metadata->offsetSdr != 0.0f || metadata->offsetHdr != 0.0f) {
+ ALOGE("Unsupported metadata offset sdr, hdr: %f, %f", metadata->offsetSdr,
+ metadata->offsetHdr);
+ return ERROR_JPEGR_UNSUPPORTED_METADATA;
+ }
+ if (metadata->hdrCapacityMin != metadata->minContentBoost
+ || metadata->hdrCapacityMax != metadata->maxContentBoost) {
+ ALOGE("Unsupported metadata hdr capacity min, max: %f, %f", metadata->hdrCapacityMin,
+ metadata->hdrCapacityMax);
+ return ERROR_JPEGR_UNSUPPORTED_METADATA;
+ }
+
// TODO: remove once map scaling factor is computed based on actual map dims
size_t image_width = uncompressed_yuv_420_image->width;
size_t image_height = uncompressed_yuv_420_image->height;
@@ -1180,12 +1211,33 @@
return ERROR_JPEGR_INVALID_NULL_PTR;
}
- if (metadata->minContentBoost < 1.0f || metadata->maxContentBoost < metadata->minContentBoost) {
+ if (metadata->version.compare("1.0")) {
+ ALOGE("received bad value for version: %s", metadata->version.c_str());
+ return ERROR_JPEGR_INVALID_INPUT_TYPE;
+ }
+ if (metadata->maxContentBoost < metadata->minContentBoost) {
ALOGE("received bad value for content boost min %f, max %f", metadata->minContentBoost,
metadata->maxContentBoost);
return ERROR_JPEGR_INVALID_INPUT_TYPE;
}
+ if (metadata->hdrCapacityMax < metadata->hdrCapacityMin || metadata->hdrCapacityMin < 1.0f) {
+ ALOGE("received bad value for hdr capacity min %f, max %f", metadata->hdrCapacityMin,
+ metadata->hdrCapacityMax);
+ return ERROR_JPEGR_INVALID_INPUT_TYPE;
+ }
+
+ if (metadata->offsetSdr < 0.0f || metadata->offsetHdr < 0.0f) {
+ ALOGE("received bad value for offset sdr %f, hdr %f", metadata->offsetSdr,
+ metadata->offsetHdr);
+ return ERROR_JPEGR_INVALID_INPUT_TYPE;
+ }
+
+ if (metadata->gamma <= 0.0f) {
+ ALOGE("received bad value for gamma %f", metadata->gamma);
+ return ERROR_JPEGR_INVALID_INPUT_TYPE;
+ }
+
const string nameSpace = "http://ns.adobe.com/xap/1.0/";
const int nameSpaceLength = nameSpace.size() + 1; // need to count the null terminator
diff --git a/libs/ultrahdr/jpegrutils.cpp b/libs/ultrahdr/jpegrutils.cpp
index 6430af1..c434eb6 100644
--- a/libs/ultrahdr/jpegrutils.cpp
+++ b/libs/ultrahdr/jpegrutils.cpp
@@ -113,6 +113,15 @@
XMPXmlHandler() : XmlHandler() {
state = NotStrarted;
+ versionFound = false;
+ minContentBoostFound = false;
+ maxContentBoostFound = false;
+ gammaFound = false;
+ offsetSdrFound = false;
+ offsetHdrFound = false;
+ hdrCapacityMinFound = false;
+ hdrCapacityMaxFound = false;
+ baseRenditionIsHdrFound = false;
}
enum ParseState {
@@ -147,10 +156,24 @@
string val;
if (state == Started) {
if (context.BuildTokenValue(&val)) {
- if (!val.compare(maxContentBoostAttrName)) {
+ if (!val.compare(versionAttrName)) {
+ lastAttributeName = versionAttrName;
+ } else if (!val.compare(maxContentBoostAttrName)) {
lastAttributeName = maxContentBoostAttrName;
} else if (!val.compare(minContentBoostAttrName)) {
lastAttributeName = minContentBoostAttrName;
+ } else if (!val.compare(gammaAttrName)) {
+ lastAttributeName = gammaAttrName;
+ } else if (!val.compare(offsetSdrAttrName)) {
+ lastAttributeName = offsetSdrAttrName;
+ } else if (!val.compare(offsetHdrAttrName)) {
+ lastAttributeName = offsetHdrAttrName;
+ } else if (!val.compare(hdrCapacityMinAttrName)) {
+ lastAttributeName = hdrCapacityMinAttrName;
+ } else if (!val.compare(hdrCapacityMaxAttrName)) {
+ lastAttributeName = hdrCapacityMaxAttrName;
+ } else if (!val.compare(baseRenditionIsHdrAttrName)) {
+ lastAttributeName = baseRenditionIsHdrAttrName;
} else {
lastAttributeName = "";
}
@@ -163,18 +186,52 @@
string val;
if (state == Started) {
if (context.BuildTokenValue(&val, true)) {
- if (!lastAttributeName.compare(maxContentBoostAttrName)) {
+ if (!lastAttributeName.compare(versionAttrName)) {
+ versionStr = val;
+ versionFound = true;
+ } else if (!lastAttributeName.compare(maxContentBoostAttrName)) {
maxContentBoostStr = val;
+ maxContentBoostFound = true;
} else if (!lastAttributeName.compare(minContentBoostAttrName)) {
minContentBoostStr = val;
+ minContentBoostFound = true;
+ } else if (!lastAttributeName.compare(gammaAttrName)) {
+ gammaStr = val;
+ gammaFound = true;
+ } else if (!lastAttributeName.compare(offsetSdrAttrName)) {
+ offsetSdrStr = val;
+ offsetSdrFound = true;
+ } else if (!lastAttributeName.compare(offsetHdrAttrName)) {
+ offsetHdrStr = val;
+ offsetHdrFound = true;
+ } else if (!lastAttributeName.compare(hdrCapacityMinAttrName)) {
+ hdrCapacityMinStr = val;
+ hdrCapacityMinFound = true;
+ } else if (!lastAttributeName.compare(hdrCapacityMaxAttrName)) {
+ hdrCapacityMaxStr = val;
+ hdrCapacityMaxFound = true;
+ } else if (!lastAttributeName.compare(baseRenditionIsHdrAttrName)) {
+ baseRenditionIsHdrStr = val;
+ baseRenditionIsHdrFound = true;
}
}
}
return context.GetResult();
}
- bool getMaxContentBoost(float* max_content_boost) {
+ bool getVersion(string* version, bool* present) {
if (state == Done) {
+ *version = versionStr;
+ *present = versionFound;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool getMaxContentBoost(float* max_content_boost, bool* present) {
+ if (state == Done) {
+ *present = maxContentBoostFound;
stringstream ss(maxContentBoostStr);
float val;
if (ss >> val) {
@@ -188,8 +245,9 @@
}
}
- bool getMinContentBoost(float* min_content_boost) {
+ bool getMinContentBoost(float* min_content_boost, bool* present) {
if (state == Done) {
+ *present = minContentBoostFound;
stringstream ss(minContentBoostStr);
float val;
if (ss >> val) {
@@ -203,12 +261,141 @@
}
}
+ bool getGamma(float* gamma, bool* present) {
+ if (state == Done) {
+ *present = gammaFound;
+ stringstream ss(gammaStr);
+ float val;
+ if (ss >> val) {
+ *gamma = val;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+
+ bool getOffsetSdr(float* offset_sdr, bool* present) {
+ if (state == Done) {
+ *present = offsetSdrFound;
+ stringstream ss(offsetSdrStr);
+ float val;
+ if (ss >> val) {
+ *offset_sdr = val;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+
+ bool getOffsetHdr(float* offset_hdr, bool* present) {
+ if (state == Done) {
+ *present = offsetHdrFound;
+ stringstream ss(offsetHdrStr);
+ float val;
+ if (ss >> val) {
+ *offset_hdr = val;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+
+ bool getHdrCapacityMin(float* hdr_capacity_min, bool* present) {
+ if (state == Done) {
+ *present = hdrCapacityMinFound;
+ stringstream ss(hdrCapacityMinStr);
+ float val;
+ if (ss >> val) {
+ *hdr_capacity_min = exp2(val);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+
+ bool getHdrCapacityMax(float* hdr_capacity_max, bool* present) {
+ if (state == Done) {
+ *present = hdrCapacityMaxFound;
+ stringstream ss(hdrCapacityMaxStr);
+ float val;
+ if (ss >> val) {
+ *hdr_capacity_max = exp2(val);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+
+ bool getBaseRenditionIsHdr(bool* base_rendition_is_hdr, bool* present) {
+ if (state == Done) {
+ *present = baseRenditionIsHdrFound;
+ if (!baseRenditionIsHdrStr.compare("False")) {
+ *base_rendition_is_hdr = false;
+ return true;
+ } else if (!baseRenditionIsHdrStr.compare("True")) {
+ *base_rendition_is_hdr = true;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+
+
private:
static const string containerName;
+
+ static const string versionAttrName;
+ string versionStr;
+ bool versionFound;
static const string maxContentBoostAttrName;
string maxContentBoostStr;
+ bool maxContentBoostFound;
static const string minContentBoostAttrName;
string minContentBoostStr;
+ bool minContentBoostFound;
+ static const string gammaAttrName;
+ string gammaStr;
+ bool gammaFound;
+ static const string offsetSdrAttrName;
+ string offsetSdrStr;
+ bool offsetSdrFound;
+ static const string offsetHdrAttrName;
+ string offsetHdrStr;
+ bool offsetHdrFound;
+ static const string hdrCapacityMinAttrName;
+ string hdrCapacityMinStr;
+ bool hdrCapacityMinFound;
+ static const string hdrCapacityMaxAttrName;
+ string hdrCapacityMaxStr;
+ bool hdrCapacityMaxFound;
+ static const string baseRenditionIsHdrAttrName;
+ string baseRenditionIsHdrStr;
+ bool baseRenditionIsHdrFound;
+
string lastAttributeName;
ParseState state;
};
@@ -253,8 +440,15 @@
const string kMapBaseRenditionIsHDR = Name(kGainMapPrefix, "BaseRenditionIsHDR");
// GainMap XMP constants - names for XMP handlers
+const string XMPXmlHandler::versionAttrName = kMapVersion;
const string XMPXmlHandler::minContentBoostAttrName = kMapGainMapMin;
const string XMPXmlHandler::maxContentBoostAttrName = kMapGainMapMax;
+const string XMPXmlHandler::gammaAttrName = kMapGamma;
+const string XMPXmlHandler::offsetSdrAttrName = kMapOffsetSdr;
+const string XMPXmlHandler::offsetHdrAttrName = kMapOffsetHdr;
+const string XMPXmlHandler::hdrCapacityMinAttrName = kMapHDRCapacityMin;
+const string XMPXmlHandler::hdrCapacityMaxAttrName = kMapHDRCapacityMax;
+const string XMPXmlHandler::baseRenditionIsHdrAttrName = kMapBaseRenditionIsHDR;
bool getMetadataFromXMP(uint8_t* xmp_data, size_t xmp_size, ultrahdr_metadata_struct* metadata) {
string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
@@ -291,11 +485,48 @@
return false;
}
- if (!handler.getMaxContentBoost(&metadata->maxContentBoost)) {
+ // Apply default values to any not-present fields, except for Version,
+ // maxContentBoost, and hdrCapacityMax, which are required. Return false if
+ // we encounter a present field that couldn't be parsed, since this
+ // indicates it is invalid (eg. string where there should be a float).
+ bool present = false;
+ if (!handler.getVersion(&metadata->version, &present) || !present) {
return false;
}
+ if (!handler.getMaxContentBoost(&metadata->maxContentBoost, &present) || !present) {
+ return false;
+ }
+ if (!handler.getHdrCapacityMax(&metadata->hdrCapacityMax, &present) || !present) {
+ return false;
+ }
+ if (!handler.getMinContentBoost(&metadata->minContentBoost, &present)) {
+ if (present) return false;
+ metadata->minContentBoost = 1.0f;
+ }
+ if (!handler.getGamma(&metadata->gamma, &present)) {
+ if (present) return false;
+ metadata->gamma = 1.0f;
+ }
+ if (!handler.getOffsetSdr(&metadata->offsetSdr, &present)) {
+ if (present) return false;
+ metadata->offsetSdr = 1.0f / 64.0f;
+ }
+ if (!handler.getOffsetHdr(&metadata->offsetHdr, &present)) {
+ if (present) return false;
+ metadata->offsetHdr = 1.0f / 64.0f;
+ }
+ if (!handler.getHdrCapacityMin(&metadata->hdrCapacityMin, &present)) {
+ if (present) return false;
+ metadata->hdrCapacityMin = 1.0f;
+ }
- if (!handler.getMinContentBoost(&metadata->minContentBoost)) {
+ bool base_rendition_is_hdr;
+ if (!handler.getBaseRenditionIsHdr(&base_rendition_is_hdr, &present)) {
+ if (present) return false;
+ base_rendition_is_hdr = false;
+ }
+ if (base_rendition_is_hdr) {
+ ALOGE("Base rendition of HDR is not supported!");
return false;
}
@@ -355,12 +586,11 @@
writer.WriteAttributeNameAndValue(kMapVersion, metadata.version);
writer.WriteAttributeNameAndValue(kMapGainMapMin, log2(metadata.minContentBoost));
writer.WriteAttributeNameAndValue(kMapGainMapMax, log2(metadata.maxContentBoost));
- writer.WriteAttributeNameAndValue(kMapGamma, "1");
- writer.WriteAttributeNameAndValue(kMapOffsetSdr, "0");
- writer.WriteAttributeNameAndValue(kMapOffsetHdr, "0");
- writer.WriteAttributeNameAndValue(
- kMapHDRCapacityMin, std::max(log2(metadata.minContentBoost), 0.0f));
- writer.WriteAttributeNameAndValue(kMapHDRCapacityMax, log2(metadata.maxContentBoost));
+ writer.WriteAttributeNameAndValue(kMapGamma, metadata.gamma);
+ writer.WriteAttributeNameAndValue(kMapOffsetSdr, metadata.offsetSdr);
+ writer.WriteAttributeNameAndValue(kMapOffsetHdr, metadata.offsetHdr);
+ writer.WriteAttributeNameAndValue(kMapHDRCapacityMin, log2(metadata.hdrCapacityMin));
+ writer.WriteAttributeNameAndValue(kMapHDRCapacityMax, log2(metadata.hdrCapacityMax));
writer.WriteAttributeNameAndValue(kMapBaseRenditionIsHDR, "False");
writer.FinishWriting();
diff --git a/libs/ultrahdr/tests/data/minnie-320x240-yuv-icc.jpg b/libs/ultrahdr/tests/data/minnie-320x240-yuv-icc.jpg
index f61e0e8..c7f4538 100644
--- a/libs/ultrahdr/tests/data/minnie-320x240-yuv-icc.jpg
+++ b/libs/ultrahdr/tests/data/minnie-320x240-yuv-icc.jpg
Binary files differ
diff --git a/libs/ultrahdr/tests/jpegr_test.cpp b/libs/ultrahdr/tests/jpegr_test.cpp
index d482ea1..41d55ec 100644
--- a/libs/ultrahdr/tests/jpegr_test.cpp
+++ b/libs/ultrahdr/tests/jpegr_test.cpp
@@ -819,6 +819,52 @@
EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
&jpegR, nullptr, nullptr, &jpegR)) << "fail, API allows nullptr gainmap image";
+ // test metadata
+ ultrahdr_metadata_struct good_metadata;
+ good_metadata.version = "1.0";
+ good_metadata.minContentBoost = 1.0f;
+ good_metadata.maxContentBoost = 2.0f;
+ good_metadata.gamma = 1.0f;
+ good_metadata.offsetSdr = 0.0f;
+ good_metadata.offsetHdr = 0.0f;
+ good_metadata.hdrCapacityMin = 1.0f;
+ good_metadata.hdrCapacityMax = 2.0f;
+
+ ultrahdr_metadata_struct metadata = good_metadata;
+ metadata.version = "1.1";
+ EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
+ &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata version";
+
+ metadata = good_metadata;
+ metadata.minContentBoost = 3.0f;
+ EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
+ &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata content boost";
+
+ metadata = good_metadata;
+ metadata.gamma = -0.1f;
+ EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
+ &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata gamma";
+
+ metadata = good_metadata;
+ metadata.offsetSdr = -0.1f;
+ EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
+ &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata offset sdr";
+
+ metadata = good_metadata;
+ metadata.offsetHdr = -0.1f;
+ EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
+ &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata offset hdr";
+
+ metadata = good_metadata;
+ metadata.hdrCapacityMax = 0.5f;
+ EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
+ &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata hdr capacity max";
+
+ metadata = good_metadata;
+ metadata.hdrCapacityMin = 0.5f;
+ EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
+ &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata hdr capacity min";
+
free(jpegR.data);
}
@@ -864,8 +910,13 @@
TEST_F(JpegRTest, writeXmpThenRead) {
ultrahdr_metadata_struct metadata_expected;
metadata_expected.version = "1.0";
- metadata_expected.maxContentBoost = 1.25;
- metadata_expected.minContentBoost = 0.75;
+ metadata_expected.maxContentBoost = 1.25f;
+ metadata_expected.minContentBoost = 0.75f;
+ metadata_expected.gamma = 1.0f;
+ metadata_expected.offsetSdr = 0.0f;
+ metadata_expected.offsetHdr = 0.0f;
+ metadata_expected.hdrCapacityMin = 1.0f;
+ metadata_expected.hdrCapacityMax = metadata_expected.maxContentBoost;
const std::string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
const int nameSpaceLength = nameSpace.size() + 1; // need to count the null terminator
@@ -882,6 +933,11 @@
EXPECT_TRUE(getMetadataFromXMP(xmpData.data(), xmpData.size(), &metadata_read));
EXPECT_FLOAT_EQ(metadata_expected.maxContentBoost, metadata_read.maxContentBoost);
EXPECT_FLOAT_EQ(metadata_expected.minContentBoost, metadata_read.minContentBoost);
+ EXPECT_FLOAT_EQ(metadata_expected.gamma, metadata_read.gamma);
+ EXPECT_FLOAT_EQ(metadata_expected.offsetSdr, metadata_read.offsetSdr);
+ EXPECT_FLOAT_EQ(metadata_expected.offsetHdr, metadata_read.offsetHdr);
+ EXPECT_FLOAT_EQ(metadata_expected.hdrCapacityMin, metadata_read.hdrCapacityMin);
+ EXPECT_FLOAT_EQ(metadata_expected.hdrCapacityMax, metadata_read.hdrCapacityMax);
}
/* Test Encode API-0 */
@@ -1297,9 +1353,7 @@
JpegRBenchmark benchmark;
- ultrahdr_metadata_struct metadata = { .version = "1.0",
- .maxContentBoost = 8.0f,
- .minContentBoost = 1.0f / 8.0f };
+ ultrahdr_metadata_struct metadata = { .version = "1.0" };
jpegr_uncompressed_struct map = { .data = NULL,
.width = 0,
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 2c3ce16..bb3b43a 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -137,12 +137,14 @@
#endif
#endif
-static const char* DRIVER_SUFFIX_PROPERTY = "ro.hardware.egl";
+static const char* PERSIST_DRIVER_SUFFIX_PROPERTY = "persist.graphics.egl";
+static const char* RO_DRIVER_SUFFIX_PROPERTY = "ro.hardware.egl";
+static const char* RO_BOARD_PLATFORM_PROPERTY = "ro.board.platform";
static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {
- "persist.graphics.egl",
- DRIVER_SUFFIX_PROPERTY,
- "ro.board.platform",
+ PERSIST_DRIVER_SUFFIX_PROPERTY,
+ RO_DRIVER_SUFFIX_PROPERTY,
+ RO_BOARD_PLATFORM_PROPERTY,
};
static bool should_unload_system_driver(egl_connection_t* cnx) {
@@ -245,17 +247,20 @@
continue;
}
hnd = attempt_to_load_system_driver(cnx, prop.c_str(), true);
- if (hnd) {
- break;
- } else if (strcmp(key, DRIVER_SUFFIX_PROPERTY) == 0) {
+ if (!hnd) {
+ ALOGD("Failed to load drivers from property %s with value %s", key, prop.c_str());
failToLoadFromDriverSuffixProperty = true;
}
+
+ // Abort regardless of whether subsequent properties are set, the value must be set
+ // correctly with the first property that has a value.
+ break;
}
}
if (!hnd) {
- // Can't find graphics driver by appending system properties, now search for the exact name
- // without any suffix of the GLES userspace driver in both locations.
+ // Can't find graphics driver by appending the value from system properties, now search for
+ // the exact name without any suffix of the GLES userspace driver in both locations.
// i.e.:
// libGLES.so, or:
// libEGL.so, libGLESv1_CM.so, libGLESv2.so
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 8b74b25..8a49ba1 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -3644,6 +3644,9 @@
std::chrono::nanoseconds(interceptKeyTimeout).count());
}
+/**
+ * Keys with ACTION_UP are delivered immediately, even if a long 'intercept key timeout' is set.
+ */
TEST_F(InputDispatcherTest, InterceptKeyIfKeyUp) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher,
@@ -3655,12 +3658,14 @@
window->consumeFocusEvent(true);
- mFakePolicy->setInterceptKeyTimeout(150ms);
mDispatcher->notifyKey(generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT));
- mDispatcher->notifyKey(generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT));
-
- // Window should receive key event immediately when same key up.
window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
+
+ // Set a value that's significantly larger than the default consumption timeout. If the
+ // implementation is correct, the actual value doesn't matter; it won't slow down the test.
+ mFakePolicy->setInterceptKeyTimeout(600ms);
+ mDispatcher->notifyKey(generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT));
+ // Window should receive key event immediately when same key up.
window->consumeKeyUp(ADISPLAY_ID_DEFAULT);
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 398d602..90d7541 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1055,7 +1055,12 @@
if (count < 0) {
if(count == DEAD_OBJECT && device.isReconnecting()) {
device.reconnect();
- continue;
+ // There are no "real" events at this point, but do not skip the rest of the loop
+ // if there are pending runtime events.
+ Mutex::Autolock _l(&mLock);
+ if (mRuntimeSensorEventQueue.empty()) {
+ continue;
+ }
} else {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cf1b018..f627501 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1349,6 +1349,8 @@
mDrawingState.bufferSurfaceFrameTX =
createSurfaceFrameForBuffer(info, postTime, mTransactionName);
}
+
+ setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName);
}
void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
@@ -1380,11 +1382,13 @@
it->second = createSurfaceFrameForTransaction(info, postTime);
}
}
+
+ setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName);
}
void Layer::addSurfaceFrameDroppedForBuffer(
- std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame) {
- surfaceFrame->setDropTime(systemTime());
+ std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t dropTime) {
+ surfaceFrame->setDropTime(dropTime);
surfaceFrame->setPresentState(PresentState::Dropped);
mFlinger->mFrameTimeline->addSurfaceFrame(surfaceFrame);
}
@@ -1434,6 +1438,32 @@
return surfaceFrame;
}
+void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime,
+ std::string debugName) {
+ if (info.skippedFrameVsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
+ return;
+ }
+
+ FrameTimelineInfo skippedFrameTimelineInfo = info;
+ skippedFrameTimelineInfo.vsyncId = info.skippedFrameVsyncId;
+
+ auto surfaceFrame =
+ mFlinger->mFrameTimeline->createSurfaceFrameForToken(skippedFrameTimelineInfo,
+ mOwnerPid, mOwnerUid,
+ getSequence(), mName, debugName,
+ /*isBuffer*/ false, getGameMode());
+ surfaceFrame->setActualStartTime(skippedFrameTimelineInfo.skippedFrameStartTimeNanos);
+ // For Transactions, the post time is considered to be both queue and acquire fence time.
+ surfaceFrame->setActualQueueTime(postTime);
+ surfaceFrame->setAcquireFenceTime(postTime);
+ const auto fps = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
+ if (fps) {
+ surfaceFrame->setRenderRate(*fps);
+ }
+ onSurfaceFrameCreated(surfaceFrame);
+ addSurfaceFrameDroppedForBuffer(surfaceFrame, postTime);
+}
+
bool Layer::setFrameRateForLayerTreeLegacy(FrameRate frameRate) {
if (mDrawingState.frameRateForLayerTree == frameRate) {
return false;
@@ -3067,7 +3097,7 @@
decrementPendingBufferCount();
if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
- addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX);
+ addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX, systemTime());
mDrawingState.bufferSurfaceFrameTX.reset();
}
} else if (EARLY_RELEASE_ENABLED && mLastClientCompositionFence != nullptr) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f34fdd9..2fbbbdc 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -785,8 +785,8 @@
void setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
nsecs_t postTime);
- void addSurfaceFrameDroppedForBuffer(
- std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame);
+ void addSurfaceFrameDroppedForBuffer(std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame,
+ nsecs_t dropTime);
void addSurfaceFramePresentedForBuffer(
std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t acquireFenceTime,
nsecs_t currentLatchTime);
@@ -795,6 +795,8 @@
const FrameTimelineInfo& info, nsecs_t postTime);
std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForBuffer(
const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName);
+ void setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime,
+ std::string debugName);
bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
TrustedPresentationListener const& listener);
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
index 921cae4..9f0bdde 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
@@ -106,7 +106,7 @@
effectLayer->addSurfaceFramePresentedForBuffer(surfaceFrame,
mFdp.ConsumeIntegral<int64_t>() /*acquireTime*/,
mFdp.ConsumeIntegral<int64_t>() /*currentTime*/);
- effectLayer->addSurfaceFrameDroppedForBuffer(surfaceFrame1);
+ effectLayer->addSurfaceFrameDroppedForBuffer(surfaceFrame1, mFdp.ConsumeIntegral<nsecs_t>());
parent.clear();
client.clear();