diff options
| author | 2018-11-19 10:52:38 -0800 | |
|---|---|---|
| committer | 2018-12-03 13:45:01 -0800 | |
| commit | 74e53776ddca1b658589a59e29b226e1afb3f2fa (patch) | |
| tree | b54c7421cf9ffa5f8c06ac739ecb4ddf293d3a4e | |
| parent | face176394e0a28bd7b7b8bed13b4696e79668a2 (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.cpp | 51 | ||||
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 8 | ||||
| -rw-r--r-- | libs/gui/include/gui/ISurfaceComposer.h | 9 | ||||
| -rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 2 | ||||
| -rw-r--r-- | libs/gui/tests/DisplayedContentSampling_test.cpp | 49 | ||||
| -rw-r--r-- | libs/gui/tests/Surface_test.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/ComposerHal.cpp | 12 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/ComposerHal.h | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/HWC2.cpp | 7 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/HWC2.h | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 14 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 19 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h | 1 |
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>*)); }; |