diff options
| author | 2020-05-07 20:15:50 -0700 | |
|---|---|---|
| committer | 2020-05-07 20:41:42 -0700 | |
| commit | dfc3f7ca7440a7b8f82e7efedbbbb9ab1f8db0ec (patch) | |
| tree | 53ddcbfe5933a0e9af906347e659db7449a1d3ff | |
| parent | 50f6c0e2d3446a904f702b3c54a393ebf42481f1 (diff) | |
Plumb client target property.
After validation, the hardware composer can request client target
properties and expect the client to use those to setup the client
target. This patch plumbs the API through to make sure buffer format is
set correctly accordingly.
Bug: b/145968912
Test: manual
Change-Id: I4a21f741e640f35883f64392c463c61029ec6ff0
16 files changed, 84 insertions, 14 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h index 5ce2fdcf8c..f680460242 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h @@ -63,6 +63,12 @@ public: // Sets the dataspace used for rendering the surface virtual void setBufferDataspace(ui::Dataspace) = 0; + // Sets the pixel format used for rendering the surface. + // Changing the pixel format of the buffer will result in buffer + // reallocation as well as some reconfiguration of the graphics context, + // which are both expensive operations. + virtual void setBufferPixelFormat(ui::PixelFormat) = 0; + // Configures the protected rendering on the surface virtual void setProtected(bool useProtected) = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h index 9ca7d2f9fb..7a4f7383d0 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h @@ -70,11 +70,13 @@ public: using ChangedTypes = android::HWComposer::DeviceRequestedChanges::ChangedTypes; using DisplayRequests = android::HWComposer::DeviceRequestedChanges::DisplayRequests; using LayerRequests = android::HWComposer::DeviceRequestedChanges::LayerRequests; + using ClientTargetProperty = android::HWComposer::DeviceRequestedChanges::ClientTargetProperty; virtual bool anyLayersRequireClientComposition() const; virtual bool allLayersRequireClientComposition() const; virtual void applyChangedTypesToLayers(const ChangedTypes&); virtual void applyDisplayRequests(const DisplayRequests&); virtual void applyLayerRequestsToLayers(const LayerRequests&); + virtual void applyClientTargetRequests(const ClientTargetProperty&); // Internal virtual void setConfiguration(const compositionengine::DisplayCreationArgs&); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h index 692d78d825..5127a6f314 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h @@ -49,6 +49,7 @@ public: const sp<Fence>& getClientTargetAcquireFence() const override; void setBufferDataspace(ui::Dataspace) override; + void setBufferPixelFormat(ui::PixelFormat) override; void setDisplaySize(const ui::Size&) override; void setProtected(bool useProtected) override; status_t beginFrame(bool mustRecompose) override; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h index ed4d492654..a0cae6fcbb 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h @@ -36,6 +36,7 @@ public: MOCK_METHOD1(setDisplaySize, void(const ui::Size&)); MOCK_METHOD1(setProtected, void(bool)); MOCK_METHOD1(setBufferDataspace, void(ui::Dataspace)); + MOCK_METHOD1(setBufferPixelFormat, void(ui::PixelFormat)); MOCK_METHOD1(beginFrame, status_t(bool mustRecompose)); MOCK_METHOD2(prepareFrame, void(bool, bool)); MOCK_METHOD1(dequeueBuffer, sp<GraphicBuffer>(base::unique_fd*)); diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp index ab269392f2..d201104810 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -259,6 +259,7 @@ void Display::chooseCompositionStrategy() { applyChangedTypesToLayers(changes->changedTypes); applyDisplayRequests(changes->displayRequests); applyLayerRequestsToLayers(changes->layerRequests); + applyClientTargetRequests(changes->clientTargetProperty); } // Determine what type of composition we are doing from the final state @@ -326,6 +327,16 @@ void Display::applyLayerRequestsToLayers(const LayerRequests& layerRequests) { } } +void Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty) { + if (clientTargetProperty.dataspace == ui::Dataspace::UNKNOWN) { + return; + } + auto outputState = editState(); + outputState.dataspace = clientTargetProperty.dataspace; + getRenderSurface()->setBufferDataspace(clientTargetProperty.dataspace); + getRenderSurface()->setBufferPixelFormat(clientTargetProperty.pixelFormat); +} + compositionengine::Output::FrameFences Display::presentAndGetFrameFences() { auto result = impl::Output::presentAndGetFrameFences(); diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp index 660baffa3a..b59f9a8edc 100644 --- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp +++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp @@ -105,6 +105,10 @@ void RenderSurface::setBufferDataspace(ui::Dataspace dataspace) { static_cast<android_dataspace>(dataspace)); } +void RenderSurface::setBufferPixelFormat(ui::PixelFormat pixelFormat) { + native_window_set_buffers_format(mNativeWindow.get(), static_cast<int32_t>(pixelFormat)); +} + void RenderSurface::setProtected(bool useProtected) { uint64_t usageFlags = GRALLOC_USAGE_HW_RENDER; if (useProtected) { diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index 59889b696a..6b9c883f38 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -650,6 +650,7 @@ TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) { {{nullptr, hal::Composition::CLIENT}}, hal::DisplayRequest::FLIP_CLIENT_TARGET, {{nullptr, hal::LayerRequest::CLEAR_CLIENT_TARGET}}, + {hal::PixelFormat::RGBA_8888, hal::Dataspace::UNKNOWN}, }; // Since two calls are made to anyLayersRequireClientComposition with different return diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 97eeea2e2f..dbdffecf0a 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -1354,6 +1354,12 @@ V2_4::Error Composer::getLayerGenericMetadataKeys( return error; } +Error Composer::getClientTargetProperty( + Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) { + mReader.takeClientTargetProperty(display, outClientTargetProperty); + return Error::NONE; +} + CommandReader::~CommandReader() { resetData(); @@ -1662,10 +1668,22 @@ void CommandReader::takePresentOrValidateStage(Display display, uint32_t* state) *state = data.presentOrValidateState; } -} // namespace impl +void CommandReader::takeClientTargetProperty( + Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) { + auto found = mReturnData.find(display); -} // namespace Hwc2 + // If not found, return the default values. + if (found == mReturnData.end()) { + outClientTargetProperty->pixelFormat = PixelFormat::RGBA_8888; + outClientTargetProperty->dataspace = Dataspace::UNKNOWN; + } + + ReturnData& data = found->second; + *outClientTargetProperty = data.clientTargetProperty; +} +} // namespace impl +} // namespace Hwc2 } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index aa43f09892..00ef782ef7 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -240,6 +240,8 @@ public: const std::vector<uint8_t>& value) = 0; virtual V2_4::Error getLayerGenericMetadataKeys( std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) = 0; + virtual Error getClientTargetProperty( + Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) = 0; }; namespace impl { @@ -282,6 +284,10 @@ public: // Get what stage succeeded during PresentOrValidate: Present or Validate void takePresentOrValidateStage(Display display, uint32_t * state); + // Get the client target properties requested by hardware composer. + void takeClientTargetProperty(Display display, + IComposerClient::ClientTargetProperty* outClientTargetProperty); + private: void resetData(); @@ -479,6 +485,9 @@ public: bool mandatory, const std::vector<uint8_t>& value) override; V2_4::Error getLayerGenericMetadataKeys( std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override; + Error getClientTargetProperty( + Display display, + IComposerClient::ClientTargetProperty* outClientTargetProperty) override; private: #if defined(USE_VR_COMPOSER) && USE_VR_COMPOSER diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index 0ea33408db..6a63023612 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -668,6 +668,11 @@ Error Display::setContentType(ContentType contentType) { return static_cast<Error>(intError); } +Error Display::getClientTargetProperty(ClientTargetProperty* outClientTargetProperty) { + const auto error = mComposer.getClientTargetProperty(mId, outClientTargetProperty); + return static_cast<Error>(error); +} + // For use by Device void Display::setConnected(bool connected) { diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index f4c7fddea9..6819ff43d2 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -234,6 +234,8 @@ public: [[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes( std::vector<hal::ContentType>*) const = 0; [[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) = 0; + [[clang::warn_unused_result]] virtual hal::Error getClientTargetProperty( + hal::ClientTargetProperty* outClientTargetProperty) = 0; }; namespace impl { @@ -305,6 +307,8 @@ public: hal::Error getSupportedContentTypes( std::vector<hal::ContentType>* outSupportedContentTypes) const override; hal::Error setContentType(hal::ContentType) override; + hal::Error getClientTargetProperty(hal::ClientTargetProperty* outClientTargetProperty) override; + // Other Display methods hal::HWDisplayId getId() const override { return mId; } bool isConnected() const override { return mIsConnected; } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 038cec4aa5..7a2f0f34ee 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -541,9 +541,12 @@ status_t HWComposer::getDeviceCompositionChanges( error = hwcDisplay->getRequests(&displayRequests, &layerRequests); RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX); - outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests), - std::move(layerRequests)}); + DeviceRequestedChanges::ClientTargetProperty clientTargetProperty; + error = hwcDisplay->getClientTargetProperty(&clientTargetProperty); + outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests), + std::move(layerRequests), + std::move(clientTargetProperty)}); error = hwcDisplay->acceptChanges(); RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX); diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index b7e9f3a693..c355ebd4a6 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -66,6 +66,18 @@ struct KnownHWCGenericLayerMetadata { class HWComposer { public: + struct DeviceRequestedChanges { + using ChangedTypes = std::unordered_map<HWC2::Layer*, hal::Composition>; + using ClientTargetProperty = hal::ClientTargetProperty; + using DisplayRequests = hal::DisplayRequest; + using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>; + + ChangedTypes changedTypes; + DisplayRequests displayRequests; + LayerRequests layerRequests; + ClientTargetProperty clientTargetProperty; + }; + virtual ~HWComposer(); virtual void setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) = 0; @@ -88,16 +100,6 @@ public: // Destroy a previously created layer virtual void destroyLayer(DisplayId displayId, HWC2::Layer* layer) = 0; - struct DeviceRequestedChanges { - using ChangedTypes = std::unordered_map<HWC2::Layer*, hal::Composition>; - using DisplayRequests = hal::DisplayRequest; - using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>; - - ChangedTypes changedTypes; - DisplayRequests displayRequests; - LayerRequests layerRequests; - }; - // Gets any required composition change requests from the HWC device. // // Note that frameUsesClientComposition must be set correctly based on diff --git a/services/surfaceflinger/DisplayHardware/Hal.h b/services/surfaceflinger/DisplayHardware/Hal.h index 66ee42586a..bb2888e0fb 100644 --- a/services/surfaceflinger/DisplayHardware/Hal.h +++ b/services/surfaceflinger/DisplayHardware/Hal.h @@ -53,6 +53,7 @@ using Composition = IComposerClient::Composition; using Connection = IComposerCallback::Connection; using ContentType = IComposerClient::ContentType; using Capability = IComposer::Capability; +using ClientTargetProperty = IComposerClient::ClientTargetProperty; using DisplayCapability = IComposerClient::DisplayCapability; using DisplayRequest = IComposerClient::DisplayRequest; using DisplayType = IComposerClient::DisplayType; diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h index 2a310786fa..c2c5072b24 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -140,6 +140,7 @@ public: const std::vector<uint8_t>&)); MOCK_METHOD1(getLayerGenericMetadataKeys, V2_4::Error(std::vector<IComposerClient::LayerGenericMetadataKey>*)); + MOCK_METHOD2(getClientTargetProperty, Error(Display, IComposerClient::ClientTargetProperty*)); }; } // namespace mock diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h index dade9fc1e0..fe99e77158 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h @@ -93,6 +93,7 @@ public: MOCK_METHOD1(setAutoLowLatencyMode, hal::Error(bool on)); MOCK_CONST_METHOD1(getSupportedContentTypes, hal::Error(std::vector<hal::ContentType>*)); MOCK_METHOD1(setContentType, hal::Error(hal::ContentType)); + MOCK_METHOD1(getClientTargetProperty, hal::Error(hal::ClientTargetProperty*)); MOCK_CONST_METHOD1(getConnectionType, hal::Error(android::DisplayConnectionType*)); MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool()); }; |