summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kevin DuBois <kevindubois@google.com> 2018-11-19 10:52:38 -0800
committer Kevin DuBois <kevindubois@google.com> 2018-12-03 13:45:01 -0800
commit74e53776ddca1b658589a59e29b226e1afb3f2fa (patch)
treeb54c7421cf9ffa5f8c06ac739ecb4ddf293d3a4e
parentface176394e0a28bd7b7b8bed13b4696e79668a2 (diff)
[SurfaceFlinger] add setDisplayContentSamplingEnabled i/f
Add interface to ISurfaceComposer that can enable or disable the graphics.composer's collection of the displayed content statistics. Bug: 116028618 Test: Boot Test: ran test client against prototype, see enable/disable working. Test: Ran new tests './libgui_test --gtest_filter="DisplayedContentSamp*"' Test: on hwc with and without new function hook. Change-Id: Ifb487e2bfbd8e0db6178ccbf762aa968c34576b9
-rw-r--r--libs/gui/ISurfaceComposer.cpp51
-rw-r--r--libs/gui/SurfaceComposerClient.cpp8
-rw-r--r--libs/gui/include/gui/ISurfaceComposer.h9
-rw-r--r--libs/gui/include/gui/SurfaceComposerClient.h2
-rw-r--r--libs/gui/tests/DisplayedContentSampling_test.cpp49
-rw-r--r--libs/gui/tests/Surface_test.cpp5
-rw-r--r--services/surfaceflinger/DisplayHardware/ComposerHal.cpp12
-rw-r--r--services/surfaceflinger/DisplayHardware/ComposerHal.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.cpp7
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.h3
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp14
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp19
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h3
-rw-r--r--services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h1
15 files changed, 181 insertions, 8 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 80d435f67b..7d2615166f 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -636,6 +636,21 @@ public:
*outComponentMask = static_cast<uint8_t>(value);
return error;
}
+
+ virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
+ uint8_t componentMask,
+ uint64_t maxFrames) const {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ data.writeStrongBinder(display);
+ data.writeBool(enable);
+ data.writeByte(static_cast<int8_t>(componentMask));
+ data.writeUint64(maxFrames);
+ status_t result =
+ remote()->transact(BnSurfaceComposer::SET_DISPLAY_CONTENT_SAMPLING_ENABLED, data,
+ &reply);
+ return result;
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -1004,6 +1019,42 @@ status_t BnSurfaceComposer::onTransact(
}
return result;
}
+ case SET_DISPLAY_CONTENT_SAMPLING_ENABLED: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+
+ sp<IBinder> display = nullptr;
+ bool enable = false;
+ int8_t componentMask = 0;
+ uint64_t maxFrames = 0;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("setDisplayContentSamplingEnabled failure in reading Display token: %d",
+ result);
+ return result;
+ }
+
+ result = data.readBool(&enable);
+ if (result != NO_ERROR) {
+ ALOGE("setDisplayContentSamplingEnabled failure in reading enable: %d", result);
+ return result;
+ }
+
+ result = data.readByte(static_cast<int8_t*>(&componentMask));
+ if (result != NO_ERROR) {
+ ALOGE("setDisplayContentSamplingEnabled failure in reading component mask: %d",
+ result);
+ return result;
+ }
+
+ result = data.readUint64(&maxFrames);
+ if (result != NO_ERROR) {
+ ALOGE("setDisplayContentSamplingEnabled failure in reading max frames: %d", result);
+ return result;
+ }
+
+ return setDisplayContentSamplingEnabled(display, enable,
+ static_cast<uint8_t>(componentMask), maxFrames);
+ }
default: {
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 9dfccc799e..405d2287be 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1098,6 +1098,14 @@ status_t SurfaceComposerClient::getDisplayedContentSamplingAttributes(const sp<I
outComponentMask);
}
+status_t SurfaceComposerClient::setDisplayContentSamplingEnabled(const sp<IBinder>& display,
+ bool enable, uint8_t componentMask,
+ uint64_t maxFrames) {
+ return ComposerService::getComposerService()->setDisplayContentSamplingEnabled(display, enable,
+ componentMask,
+ maxFrames);
+}
+
// ----------------------------------------------------------------------------
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 3b6c6e44b1..41369c855a 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -300,6 +300,14 @@ public:
ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) const = 0;
+
+ /* Turns on the color sampling engine on the display.
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
+ uint8_t componentMask,
+ uint64_t maxFrames) const = 0;
};
// ----------------------------------------------------------------------------
@@ -340,6 +348,7 @@ public:
GET_COMPOSITION_PREFERENCE,
GET_COLOR_MANAGEMENT,
GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
+ SET_DISPLAY_CONTENT_SAMPLING_ENABLED,
};
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 7d0551289e..ba943a0f8e 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -386,6 +386,8 @@ public:
ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask);
+ static status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
+ uint8_t componentMask, uint64_t maxFrames);
private:
virtual void onFirstRef();
diff --git a/libs/gui/tests/DisplayedContentSampling_test.cpp b/libs/gui/tests/DisplayedContentSampling_test.cpp
index f2c0e0ca7f..f9d5dd632b 100644
--- a/libs/gui/tests/DisplayedContentSampling_test.cpp
+++ b/libs/gui/tests/DisplayedContentSampling_test.cpp
@@ -36,7 +36,12 @@ protected:
ASSERT_TRUE(mDisplayToken);
}
- bool shouldSkipTest(status_t status) {
+ bool shouldSkipTest() {
+ ui::PixelFormat format;
+ ui::Dataspace dataspace;
+ status_t status =
+ mComposerClient->getDisplayedContentSamplingAttributes(mDisplayToken, &format,
+ &dataspace, &componentMask);
if (status == PERMISSION_DENIED) {
SUCCEED() << "permissions denial, skipping test";
return true;
@@ -50,19 +55,53 @@ protected:
sp<SurfaceComposerClient> mComposerClient;
sp<IBinder> mDisplayToken;
+ uint8_t componentMask = 0;
};
TEST_F(DisplayedContentSamplingTest, GetDisplayedContentSamplingAttributesAreSane) {
+ // tradefed infrastructure does not support use of GTEST_SKIP
+ if (shouldSkipTest()) return;
+
ui::PixelFormat format;
ui::Dataspace dataspace;
- uint8_t componentMask = 0;
status_t status =
mComposerClient->getDisplayedContentSamplingAttributes(mDisplayToken, &format,
&dataspace, &componentMask);
- if (shouldSkipTest(status)) {
- return;
- }
EXPECT_EQ(OK, status);
EXPECT_LE(componentMask, INVALID_MASK);
}
+
+TEST_F(DisplayedContentSamplingTest, EnableWithInvalidMaskReturnsBadValue) {
+ if (shouldSkipTest()) return;
+
+ status_t status =
+ mComposerClient->setDisplayContentSamplingEnabled(mDisplayToken, true, INVALID_MASK, 0);
+ EXPECT_EQ(BAD_VALUE, status);
+}
+
+TEST_F(DisplayedContentSamplingTest, EnableAndDisableSucceed) {
+ if (shouldSkipTest()) return;
+
+ status_t status = mComposerClient->setDisplayContentSamplingEnabled(mDisplayToken, true,
+ componentMask, 10);
+ EXPECT_EQ(OK, status);
+
+ status = mComposerClient->setDisplayContentSamplingEnabled(mDisplayToken, false, componentMask,
+ 0);
+ EXPECT_EQ(OK, status);
+}
+
+TEST_F(DisplayedContentSamplingTest, SelectivelyDisableComponentOk) {
+ if (shouldSkipTest()) return;
+
+ status_t status = mComposerClient->setDisplayContentSamplingEnabled(mDisplayToken, true,
+ componentMask, 0);
+ EXPECT_EQ(OK, status);
+
+ // Clear the lowest bit.
+ componentMask &= (componentMask - 1);
+ status = mComposerClient->setDisplayContentSamplingEnabled(mDisplayToken, false, componentMask,
+ 0);
+ EXPECT_EQ(OK, status);
+}
} // namespace android
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 3950bb6258..cb1756f15b 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -647,6 +647,11 @@ public:
uint8_t* /*outComponentMask*/) const override {
return NO_ERROR;
}
+ status_t setDisplayContentSamplingEnabled(const sp<IBinder>& /*display*/, bool /*enable*/,
+ uint8_t /*componentMask*/,
+ uint64_t /*maxFrames*/) const override {
+ return NO_ERROR;
+ }
virtual status_t getColorManagement(bool* /*outGetColorManagement*/) const { return NO_ERROR; }
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 5b641a23aa..3b7ed155ba 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -1067,6 +1067,18 @@ Error Composer::getDisplayCapabilities(Display display,
return error;
}
+Error Composer::setDisplayContentSamplingEnabled(Display display, bool enabled,
+ uint8_t componentMask, uint64_t maxFrames) {
+ if (!mClient_2_3) {
+ return Error::UNSUPPORTED;
+ }
+
+ auto enable = enabled ? V2_3::IComposerClient::DisplayedContentSampling::ENABLE
+ : V2_3::IComposerClient::DisplayedContentSampling::DISABLE;
+ return mClient_2_3->setDisplayedContentSamplingEnabled(display, enable, componentMask,
+ maxFrames);
+}
+
CommandReader::~CommandReader()
{
resetData();
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 61af34892b..0db12a16cf 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -192,6 +192,8 @@ public:
virtual Error getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat,
Dataspace* outDataspace,
uint8_t* outComponentMask) = 0;
+ virtual Error setDisplayContentSamplingEnabled(Display display, bool enabled,
+ uint8_t componentMask, uint64_t maxFrames) = 0;
virtual Error getDisplayCapabilities(Display display,
std::vector<DisplayCapability>* outCapabilities) = 0;
};
@@ -396,6 +398,8 @@ public:
Error getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat,
Dataspace* outDataspace,
uint8_t* outComponentMask) override;
+ Error setDisplayContentSamplingEnabled(Display display, bool enabled, uint8_t componentMask,
+ uint64_t maxFrames) override;
Error getDisplayCapabilities(Display display,
std::vector<DisplayCapability>* outCapabilities) override;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 2df2d3b5b9..733a5dae43 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -555,6 +555,13 @@ Error Display::getDisplayedContentSamplingAttributes(PixelFormat* outFormat,
return static_cast<Error>(intError);
}
+Error Display::setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask,
+ uint64_t maxFrames) const {
+ auto intError =
+ mComposer.setDisplayContentSamplingEnabled(mId, enabled, componentMask, maxFrames);
+ return static_cast<Error>(intError);
+}
+
Error Display::getReleaseFences(
std::unordered_map<Layer*, sp<Fence>>* outFences) const
{
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 8c0f50c068..2d65051dff 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -240,6 +240,9 @@ public:
[[clang::warn_unused_result]] Error getDisplayedContentSamplingAttributes(
android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace,
uint8_t* outComponentMask) const;
+ [[clang::warn_unused_result]] Error setDisplayContentSamplingEnabled(bool enabled,
+ uint8_t componentMask,
+ uint64_t maxFrames) const;
[[clang::warn_unused_result]] Error getReleaseFences(
std::unordered_map<Layer*,
android::sp<android::Fence>>* outFences) const;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index a752a7da4b..b27344d48e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -756,6 +756,20 @@ status_t HWComposer::getDisplayedContentSamplingAttributes(DisplayId displayId,
return NO_ERROR;
}
+status_t HWComposer::setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
+ uint8_t componentMask, uint64_t maxFrames) {
+ RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+ const auto error =
+ mDisplayData[displayId].hwcDisplay->setDisplayContentSamplingEnabled(enabled,
+ componentMask,
+ maxFrames);
+
+ if (error == HWC2::Error::Unsupported) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+ if (error == HWC2::Error::BadParameter) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+ RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+ return NO_ERROR;
+}
+
bool HWComposer::isUsingVrComposer() const {
return getComposer()->isUsingVrComposer();
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 0375f7489d..3f1328e90e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -131,6 +131,8 @@ public:
status_t getDisplayedContentSamplingAttributes(DisplayId displayId, ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask);
+ status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
+ uint8_t componentMask, uint64_t maxFrames);
// Events handling ---------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5b3c47713e..75363bf874 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1121,8 +1121,7 @@ status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder>
if (!outFormat || !outDataspace || !outComponentMask) {
return BAD_VALUE;
}
- Mutex::Autolock _l(mStateLock);
- const auto display = getDisplayDeviceLocked(displayToken);
+ const auto display = getDisplayDevice(displayToken);
if (!display || !display->getId()) {
ALOGE("getDisplayedContentSamplingAttributes: Bad display token: %p", display.get());
return BAD_VALUE;
@@ -1131,6 +1130,19 @@ status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder>
outDataspace, outComponentMask);
}
+status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken,
+ bool enable, uint8_t componentMask,
+ uint64_t maxFrames) const {
+ const auto display = getDisplayDevice(displayToken);
+ if (!display || !display->getId()) {
+ ALOGE("setDisplayContentSamplingEnabled: Bad display token: %p", display.get());
+ return BAD_VALUE;
+ }
+
+ return getHwComposer().setDisplayContentSamplingEnabled(*display->getId(), enable,
+ componentMask, maxFrames);
+}
+
status_t SurfaceFlinger::enableVSyncInjections(bool enable) {
postMessageSync(new LambdaMessage([&] {
Mutex::Autolock _l(mStateLock);
@@ -4776,7 +4788,8 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {
case SET_ACTIVE_COLOR_MODE:
case INJECT_VSYNC:
case SET_POWER_MODE:
- case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES: {
+ case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES:
+ case SET_DISPLAY_CONTENT_SAMPLING_ENABLED: {
if (!callingThreadHasUnscopedSurfaceFlingerAccess()) {
IPCThreadState* ipc = IPCThreadState::self();
ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d",
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index eff5fca95f..1dd6e23291 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -483,6 +483,9 @@ private:
virtual status_t getDisplayedContentSamplingAttributes(
const sp<IBinder>& display, ui::PixelFormat* outFormat, ui::Dataspace* outDataspace,
uint8_t* outComponentMask) const override;
+ virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
+ uint8_t componentMask,
+ uint64_t maxFrames) const override;
/* ------------------------------------------------------------------------
* DeathRecipient interface
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 5a46c26653..68fd8b4907 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -115,6 +115,7 @@ public:
MOCK_METHOD3(setLayerColorTransform, Error(Display, Layer, const float*));
MOCK_METHOD4(getDisplayedContentSamplingAttributes,
Error(Display, PixelFormat*, Dataspace*, uint8_t*));
+ MOCK_METHOD4(setDisplayContentSamplingEnabled, Error(Display, bool, uint8_t, uint64_t));
MOCK_METHOD2(getDisplayCapabilities, Error(Display, std::vector<DisplayCapability>*));
};