[SurfaceFlinger] add getDisplayedContentSample i/f
Add interface to ISurfaceComposer that can query the
graphics.composer for statistics on the displayed pixel content.
Bug: 116028618
Test: Boot
Test: ran test client, see data collected
Change-Id: Ide9b81b80c3399e7d648c7b611514e0d699120de
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 7d26151..f1fefcc 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -651,6 +651,49 @@
&reply);
return result;
}
+
+ virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
+ uint64_t timestamp,
+ DisplayedFrameStats* outStats) const {
+ if (!outStats) return BAD_VALUE;
+
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ data.writeStrongBinder(display);
+ data.writeUint64(maxFrames);
+ data.writeUint64(timestamp);
+
+ status_t result =
+ remote()->transact(BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLE, data, &reply);
+
+ if (result != NO_ERROR) {
+ return result;
+ }
+
+ result = reply.readUint64(&outStats->numFrames);
+ if (result != NO_ERROR) {
+ return result;
+ }
+
+ result = reply.readInt64Vector(
+ reinterpret_cast<std::vector<int64_t>*>(&outStats->component_0_sample));
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt64Vector(
+ reinterpret_cast<std::vector<int64_t>*>(&outStats->component_1_sample));
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt64Vector(
+ reinterpret_cast<std::vector<int64_t>*>(&outStats->component_2_sample));
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt64Vector(
+ reinterpret_cast<std::vector<int64_t>*>(&outStats->component_3_sample));
+ return result;
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -1055,6 +1098,40 @@
return setDisplayContentSamplingEnabled(display, enable,
static_cast<uint8_t>(componentMask), maxFrames);
}
+ case GET_DISPLAYED_CONTENT_SAMPLE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+
+ sp<IBinder> display = data.readStrongBinder();
+ uint64_t maxFrames = 0;
+ uint64_t timestamp = 0;
+
+ status_t result = data.readUint64(&maxFrames);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayedContentSample failure in reading max frames: %d", result);
+ return result;
+ }
+
+ result = data.readUint64(×tamp);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayedContentSample failure in reading timestamp: %d", result);
+ return result;
+ }
+
+ DisplayedFrameStats stats;
+ result = getDisplayedContentSample(display, maxFrames, timestamp, &stats);
+ if (result == NO_ERROR) {
+ reply->writeUint64(stats.numFrames);
+ reply->writeInt64Vector(
+ *reinterpret_cast<std::vector<int64_t>*>(&stats.component_0_sample));
+ reply->writeInt64Vector(
+ *reinterpret_cast<std::vector<int64_t>*>(&stats.component_1_sample));
+ reply->writeInt64Vector(
+ *reinterpret_cast<std::vector<int64_t>*>(&stats.component_2_sample));
+ reply->writeInt64Vector(
+ *reinterpret_cast<std::vector<int64_t>*>(&stats.component_3_sample));
+ }
+ return result;
+ }
default: {
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 405d228..070b253 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1106,6 +1106,12 @@
maxFrames);
}
+status_t SurfaceComposerClient::getDisplayedContentSample(const sp<IBinder>& display,
+ uint64_t maxFrames, uint64_t timestamp,
+ DisplayedFrameStats* outStats) {
+ return ComposerService::getComposerService()->getDisplayedContentSample(display, maxFrames,
+ timestamp, outStats);
+}
// ----------------------------------------------------------------------------
status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 41369c8..3052c0b 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -27,10 +27,11 @@
#include <binder/IInterface.h>
+#include <ui/DisplayedFrameStats.h>
#include <ui/FrameStats.h>
-#include <ui/PixelFormat.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicTypes.h>
+#include <ui/PixelFormat.h>
#include <vector>
@@ -308,6 +309,14 @@
virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
uint8_t componentMask,
uint64_t maxFrames) const = 0;
+
+ /* Returns statistics on the color profile of the last frame displayed for a given display
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
+ uint64_t timestamp,
+ DisplayedFrameStats* outStats) const = 0;
};
// ----------------------------------------------------------------------------
@@ -349,6 +358,7 @@
GET_COLOR_MANAGEMENT,
GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
SET_DISPLAY_CONTENT_SAMPLING_ENABLED,
+ GET_DISPLAYED_CONTENT_SAMPLE,
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index ba943a0..2b107aa 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -30,6 +30,7 @@
#include <utils/SortedVector.h>
#include <utils/threads.h>
+#include <ui/DisplayedFrameStats.h>
#include <ui/FrameStats.h>
#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
@@ -389,6 +390,9 @@
static status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
uint8_t componentMask, uint64_t maxFrames);
+ static status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
+ uint64_t timestamp, DisplayedFrameStats* outStats);
+
private:
virtual void onFirstRef();
diff --git a/libs/gui/tests/DisplayedContentSampling_test.cpp b/libs/gui/tests/DisplayedContentSampling_test.cpp
index f9d5dd6..5443812 100644
--- a/libs/gui/tests/DisplayedContentSampling_test.cpp
+++ b/libs/gui/tests/DisplayedContentSampling_test.cpp
@@ -104,4 +104,19 @@
0);
EXPECT_EQ(OK, status);
}
+
+TEST_F(DisplayedContentSamplingTest, SampleCollectionCoherentWithSupportMask) {
+ if (shouldSkipTest()) return;
+
+ DisplayedFrameStats stats;
+ status_t status = mComposerClient->getDisplayedContentSample(mDisplayToken, 0, 0, &stats);
+ EXPECT_EQ(OK, status);
+ if (stats.numFrames <= 0) return;
+
+ if (componentMask & (0x1 << 0)) EXPECT_NE(0, stats.component_0_sample.size());
+ if (componentMask & (0x1 << 1)) EXPECT_NE(0, stats.component_1_sample.size());
+ if (componentMask & (0x1 << 2)) EXPECT_NE(0, stats.component_2_sample.size());
+ if (componentMask & (0x1 << 3)) EXPECT_NE(0, stats.component_3_sample.size());
+}
+
} // namespace android
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index cb1756f..d37b810 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -652,6 +652,11 @@
uint64_t /*maxFrames*/) const override {
return NO_ERROR;
}
+ status_t getDisplayedContentSample(const sp<IBinder>& /*display*/, uint64_t /*maxFrames*/,
+ uint64_t /*timestamp*/,
+ DisplayedFrameStats* /*outStats*/) const override {
+ return NO_ERROR;
+ }
virtual status_t getColorManagement(bool* /*outGetColorManagement*/) const { return NO_ERROR; }