diff options
| author | 2018-10-16 13:32:31 -0700 | |
|---|---|---|
| committer | 2018-11-28 16:37:53 -0800 | |
| commit | 9c0a1763cd293933f1773f8463daef1de5b8d08d (patch) | |
| tree | 42bceeee71bd7f4c99ada3b3d694101fd82c62a0 | |
| parent | 5363caaf84127c4661ab7489f94662fd0f038778 (diff) | |
[SurfaceFlinger] add getDisplayedContentSamplingAttributes i/f
Add interface to ISurfaceComposer that can query the
graphics.composer for querying the displayed content sampling
engine's supported attributes.
Bug: 116028618
Test: Boot
Test: ran test client against prototype, see attributes reported
Test: Ran new test './libgui_test --gtest_filter="DisplayedContentSamp*"'
Test: on hwc with and without new function hook.
Change-Id: Ie4bebd98d134e63a9f3e21f79ae519a1fe8055b0
| -rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 53 | ||||
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 9 | ||||
| -rw-r--r-- | libs/gui/include/gui/ISurfaceComposer.h | 8 | ||||
| -rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 5 | ||||
| -rw-r--r-- | libs/gui/tests/Android.bp | 1 | ||||
| -rw-r--r-- | libs/gui/tests/DisplayedContentSampling_test.cpp | 68 | ||||
| -rw-r--r-- | libs/gui/tests/Surface_test.cpp | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/ComposerHal.cpp | 27 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/ComposerHal.h | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/HWC2.cpp | 8 | ||||
| -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 | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 20 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h | 2 |
16 files changed, 237 insertions, 1 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 69e5379047..80d435f67b 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -599,6 +599,43 @@ public: } return err; } + + virtual status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask) const { + if (!outFormat || !outDataspace || !outComponentMask) return BAD_VALUE; + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + data.writeStrongBinder(display); + + status_t error = + remote()->transact(BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES, + data, &reply); + if (error != NO_ERROR) { + return error; + } + + uint32_t value = 0; + error = reply.readUint32(&value); + if (error != NO_ERROR) { + return error; + } + *outFormat = static_cast<ui::PixelFormat>(value); + + error = reply.readUint32(&value); + if (error != NO_ERROR) { + return error; + } + *outDataspace = static_cast<ui::Dataspace>(value); + + error = reply.readUint32(&value); + if (error != NO_ERROR) { + return error; + } + *outComponentMask = static_cast<uint8_t>(value); + return error; + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -951,6 +988,22 @@ status_t BnSurfaceComposer::onTransact( } return result; } + case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + + sp<IBinder> display = data.readStrongBinder(); + ui::PixelFormat format; + ui::Dataspace dataspace; + uint8_t component = 0; + auto result = + getDisplayedContentSamplingAttributes(display, &format, &dataspace, &component); + if (result == NO_ERROR) { + reply->writeUint32(static_cast<uint32_t>(format)); + reply->writeUint32(static_cast<uint32_t>(dataspace)); + reply->writeUint32(static_cast<uint32_t>(component)); + } + return result; + } default: { return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 87c6f27c57..41e5abbd0e 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1077,6 +1077,15 @@ status_t SurfaceComposerClient::getHdrCapabilities(const sp<IBinder>& display, outCapabilities); } +status_t SurfaceComposerClient::getDisplayedContentSamplingAttributes(const sp<IBinder>& display, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask) { + return ComposerService::getComposerService() + ->getDisplayedContentSamplingAttributes(display, outFormat, outDataspace, + outComponentMask); +} + // ---------------------------------------------------------------------------- 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 761f31a04b..3b6c6e44b1 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -293,6 +293,13 @@ public: ui::PixelFormat* defaultPixelFormat, ui::Dataspace* wideColorGamutDataspace, ui::PixelFormat* wideColorGamutPixelFormat) const = 0; + /* + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask) const = 0; }; // ---------------------------------------------------------------------------- @@ -332,6 +339,7 @@ public: CREATE_SCOPED_CONNECTION, GET_COMPOSITION_PREFERENCE, GET_COLOR_MANAGEMENT, + GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES, }; 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 10c27b1a33..cf55b6b33d 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -381,6 +381,11 @@ public: inline sp<ISurfaceComposerClient> getClient() { return mClient; } + static status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask); + private: virtual void onFirstRef(); diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp index a6295e0387..6de641d0e0 100644 --- a/libs/gui/tests/Android.bp +++ b/libs/gui/tests/Android.bp @@ -17,6 +17,7 @@ cc_test { "BufferQueue_test.cpp", "CpuConsumer_test.cpp", "EndToEndNativeInputTest.cpp", + "DisplayedContentSampling_test.cpp", "FillBuffer.cpp", "GLTest.cpp", "IGraphicBufferProducer_test.cpp", diff --git a/libs/gui/tests/DisplayedContentSampling_test.cpp b/libs/gui/tests/DisplayedContentSampling_test.cpp new file mode 100644 index 0000000000..f2c0e0ca7f --- /dev/null +++ b/libs/gui/tests/DisplayedContentSampling_test.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include <binder/ProcessState.h> +#include <gui/ISurfaceComposer.h> +#include <gui/Surface.h> +#include <gui/SurfaceComposerClient.h> +#include <inttypes.h> + +namespace android { + +using Transaction = SurfaceComposerClient::Transaction; + +static constexpr uint32_t INVALID_MASK = 0x10; +class DisplayedContentSamplingTest : public ::testing::Test { +protected: + void SetUp() { + mComposerClient = new SurfaceComposerClient; + ASSERT_EQ(OK, mComposerClient->initCheck()); + mDisplayToken = mComposerClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); + ASSERT_TRUE(mDisplayToken); + } + + bool shouldSkipTest(status_t status) { + if (status == PERMISSION_DENIED) { + SUCCEED() << "permissions denial, skipping test"; + return true; + } + if (status == INVALID_OPERATION) { + SUCCEED() << "optional function not supported, skipping test"; + return true; + } + return false; + } + + sp<SurfaceComposerClient> mComposerClient; + sp<IBinder> mDisplayToken; +}; + +TEST_F(DisplayedContentSamplingTest, GetDisplayedContentSamplingAttributesAreSane) { + 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); +} +} // namespace android diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 4ba7da3560..3950bb6258 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -641,6 +641,12 @@ public: ui::PixelFormat* /*outWideColorGamutPixelFormat*/) const override { return NO_ERROR; } + status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& /*display*/, + ui::PixelFormat* /*outFormat*/, + ui::Dataspace* /*outDataspace*/, + uint8_t* /*outComponentMask*/) 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 f0bccaabf1..b919da73e2 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -1023,6 +1023,33 @@ Error Composer::setLayerColorTransform(Display display, Layer layer, const float return Error::NONE; } +Error Composer::getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat, + Dataspace* outDataspace, + uint8_t* outComponentMask) { + if (!outFormat || !outDataspace || !outComponentMask) { + return Error::BAD_PARAMETER; + } + if (!mClient_2_3) { + return Error::UNSUPPORTED; + } + Error error = kDefaultError; + mClient_2_3->getDisplayedContentSamplingAttributes(display, + [&](const auto tmpError, + const auto& tmpFormat, + const auto& tmpDataspace, + const auto& tmpComponentMask) { + error = tmpError; + if (error == Error::NONE) { + *outFormat = tmpFormat; + *outDataspace = tmpDataspace; + *outComponentMask = + static_cast<uint8_t>( + tmpComponentMask); + } + }); + return error; +} + CommandReader::~CommandReader() { resetData(); diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 4188352a76..c39171efa1 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -193,6 +193,9 @@ public: std::vector<uint8_t>* outData) = 0; virtual Error setLayerColorTransform(Display display, Layer layer, const float* matrix) = 0; + virtual Error getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat, + Dataspace* outDataspace, + uint8_t* outComponentMask) = 0; }; namespace impl { @@ -392,6 +395,9 @@ public: Error getDisplayIdentificationData(Display display, uint8_t* outPort, std::vector<uint8_t>* outData) override; Error setLayerColorTransform(Display display, Layer layer, const float* matrix) override; + Error getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat, + Dataspace* outDataspace, + uint8_t* outComponentMask) override; private: class CommandWriter : public CommandWriterBase { diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index 393041d681..b4ac506c6b 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -538,6 +538,14 @@ Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) const return Error::None; } +Error Display::getDisplayedContentSamplingAttributes(PixelFormat* outFormat, + Dataspace* outDataspace, + uint8_t* outComponentMask) const { + auto intError = mComposer.getDisplayedContentSamplingAttributes(mId, outFormat, outDataspace, + outComponentMask); + 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 d274631f9d..607d9ef718 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -237,6 +237,9 @@ public: [[clang::warn_unused_result]] Error supportsDoze(bool* outSupport) const; [[clang::warn_unused_result]] Error getHdrCapabilities( android::HdrCapabilities* outCapabilities) const; + [[clang::warn_unused_result]] Error getDisplayedContentSamplingAttributes( + android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace, + uint8_t* outComponentMask) 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 9bbc37fe87..c93b4d6acd 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -733,6 +733,20 @@ mat4 HWComposer::getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace return matrix; } +status_t HWComposer::getDisplayedContentSamplingAttributes(DisplayId displayId, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask) { + RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); + const auto error = + mDisplayData[displayId] + .hwcDisplay->getDisplayedContentSamplingAttributes(outFormat, outDataspace, + outComponentMask); + if (error == HWC2::Error::Unsupported) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION); + 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 2f579077cc..1e5f971f83 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -125,6 +125,11 @@ public: mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace); + // Returns the attributes of the color sampling engine. + status_t getDisplayedContentSamplingAttributes(DisplayId displayId, ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask); + // Events handling --------------------------------------------------------- // Returns stable display ID (and display name on connection of new or previously disconnected diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1db87915bc..6bd43aa598 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1114,6 +1114,23 @@ status_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& displayToken, return NO_ERROR; } +status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder>& displayToken, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask) const { + if (!outFormat || !outDataspace || !outComponentMask) { + return BAD_VALUE; + } + Mutex::Autolock _l(mStateLock); + const auto display = getDisplayDeviceLocked(displayToken); + if (!display || !display->getId()) { + ALOGE("getDisplayedContentSamplingAttributes: Bad display token: %p", display.get()); + return BAD_VALUE; + } + return getHwComposer().getDisplayedContentSamplingAttributes(*display->getId(), outFormat, + outDataspace, outComponentMask); +} + status_t SurfaceFlinger::enableVSyncInjections(bool enable) { postMessageSync(new LambdaMessage([&] { Mutex::Autolock _l(mStateLock); @@ -4725,7 +4742,8 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case SET_ACTIVE_CONFIG: case SET_ACTIVE_COLOR_MODE: case INJECT_VSYNC: - case SET_POWER_MODE: { + case SET_POWER_MODE: + case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES: { 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 4a14de7f73..18accee837 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -480,6 +480,9 @@ private: status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat, ui::Dataspace* outWideColorGamutDataspace, ui::PixelFormat* outWideColorGamutPixelFormat) const override; + virtual status_t getDisplayedContentSamplingAttributes( + const sp<IBinder>& display, ui::PixelFormat* outFormat, ui::Dataspace* outDataspace, + uint8_t* outComponentMask) 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 c0395c01ce..03ef2f830e 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -113,6 +113,8 @@ public: MOCK_METHOD4(setLayerInfo, Error(Display, Layer, uint32_t, uint32_t)); MOCK_METHOD3(getRenderIntents, Error(Display, ColorMode, std::vector<RenderIntent>*)); MOCK_METHOD3(setLayerColorTransform, Error(Display, Layer, const float*)); + MOCK_METHOD4(getDisplayedContentSamplingAttributes, + Error(Display, PixelFormat*, Dataspace*, uint8_t*)); }; } // namespace mock |