diff options
-rw-r--r-- | graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h | 28 | ||||
-rw-r--r-- | graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h | 101 |
2 files changed, 123 insertions, 6 deletions
diff --git a/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h index 436e4612bb..5826b126bb 100644 --- a/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h +++ b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h @@ -162,6 +162,7 @@ class HwcHalImpl : public Hal { Error destroyLayer(Display display, Layer layer) override { int32_t err = mDispatch.destroyLayer(mDevice, display, layer); + onLayerDestroyed(display, layer); return static_cast<Error>(err); } @@ -327,6 +328,7 @@ class HwcHalImpl : public Hal { std::vector<IComposerClient::Composition>* outCompositionTypes, uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers, std::vector<uint32_t>* outRequestMasks) override { + onBeforeValidateDisplay(display); uint32_t typesCount = 0; uint32_t reqsCount = 0; int32_t err = mDispatch.validateDisplay(mDevice, display, &typesCount, &reqsCount); @@ -335,17 +337,15 @@ class HwcHalImpl : public Hal { return static_cast<Error>(err); } - err = mDispatch.getChangedCompositionTypes(mDevice, display, &typesCount, nullptr, nullptr); + err = getChangedCompositionTypes(display, &typesCount, nullptr, nullptr); if (err != HWC2_ERROR_NONE) { return static_cast<Error>(err); } std::vector<Layer> changedLayers(typesCount); std::vector<IComposerClient::Composition> compositionTypes(typesCount); - err = mDispatch.getChangedCompositionTypes( - mDevice, display, &typesCount, changedLayers.data(), - reinterpret_cast<std::underlying_type<IComposerClient::Composition>::type*>( - compositionTypes.data())); + err = getChangedCompositionTypes(display, &typesCount, changedLayers.data(), + compositionTypes.data()); if (err != HWC2_ERROR_NONE) { return static_cast<Error>(err); } @@ -578,6 +578,15 @@ class HwcHalImpl : public Hal { return true; } + virtual int32_t getChangedCompositionTypes(Display display, uint32_t* outTypesCount, + Layer* outChangedLayers, + IComposerClient::Composition* outCompositionTypes) { + return getChangedCompositionTypesInternal(display, outTypesCount, outChangedLayers, + outCompositionTypes); + } + virtual void onLayerDestroyed(Display /* display */, Layer /* layer */) {} + virtual void onBeforeValidateDisplay(Display /* display */) {} + static void hotplugHook(hwc2_callback_data_t callbackData, hwc2_display_t display, int32_t connected) { auto hal = static_cast<HwcHalImpl*>(callbackData); @@ -596,6 +605,15 @@ class HwcHalImpl : public Hal { hal->mEventCallback->onVsync(display, timestamp); } + int32_t getChangedCompositionTypesInternal(Display display, uint32_t* outTypesCount, + Layer* outChangedLayers, + IComposerClient::Composition* outCompositionTypes) { + return mDispatch.getChangedCompositionTypes( + mDevice, display, outTypesCount, outChangedLayers, + reinterpret_cast<std::underlying_type<IComposerClient::Composition>::type*>( + outCompositionTypes)); + } + hwc2_device_t* mDevice = nullptr; std::unordered_set<hwc2_capability_t> mCapabilities; diff --git a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h index 070cf80e44..9d67e0442d 100644 --- a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h +++ b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h @@ -42,6 +42,20 @@ using common::V1_2::PixelFormat; using V2_1::Display; using V2_1::Error; +namespace { + +bool isIdentityMatrix(const float* matrix) { + if (matrix[0] == 1.0 && matrix[1] == 0.0 && matrix[2] == 0.0 && matrix[3] == 0.0 && + matrix[4] == 0.0 && matrix[5] == 1.0 && matrix[6] == 0.0 && matrix[7] == 0.0 && + matrix[8] == 0.0 && matrix[9] == 0.0 && matrix[10] == 1.0 && matrix[11] == 0.0 && + matrix[12] == 0.0 && matrix[13] == 0.0 && matrix[14] == 0.0 && matrix[15] == 1.0) { + return true; + } + return false; +} + +} // namespace + // HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2 template <typename Hal> class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> { @@ -130,6 +144,16 @@ class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> { Error setLayerColorTransform(Display display, Layer layer, const float* matrix) override { if (!mDispatch.setLayerColorTransform) { + if (isIdentityMatrix(matrix)) { + // If an identity matrix is set, then we can remove the layer from client + // composition list. + mClientCompositionLayers[display].erase(layer); + return Error::UNSUPPORTED; + } + // if setLayerColorTransform is not implemented, per spec we want to make sure the + // layer marked as client composition, and thus we maintain a list, and mark all these + // layers as client composition later before validate the display. + mClientCompositionLayers[display].insert(layer); return Error::UNSUPPORTED; } int32_t err = mDispatch.setLayerColorTransform(mDevice, display, layer, matrix); @@ -294,7 +318,79 @@ class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> { return true; } - private: + int32_t getChangedCompositionTypes(Display display, uint32_t* outTypesCount, + Layer* outChangedLayers, + IComposerClient::Composition* outCompositionTypes) override { + if (outChangedLayers == nullptr && outCompositionTypes == nullptr) { + uint32_t typesCount = 0; + int32_t error = BaseType2_1::getChangedCompositionTypesInternal(display, &typesCount, + nullptr, nullptr); + if (error != HWC2_ERROR_NONE) { + return error; + } + mChangedLayersCache[display].reserve(typesCount); + mCompositionTypesCache[display].reserve(typesCount); + error = BaseType2_1::getChangedCompositionTypesInternal( + display, &typesCount, mChangedLayersCache[display].data(), + mCompositionTypesCache[display].data()); + if (error != HWC2_ERROR_NONE) { + return error; + } + for (Layer layer : mClientCompositionLayers[display]) { + bool exist = false; + for (uint32_t i = 0; i < typesCount; ++i) { + if (mChangedLayersCache[display][i] == layer) { + exist = true; + break; + } + } + if (!exist) { + mChangedLayersCache[display].push_back(layer); + mCompositionTypesCache[display].push_back(IComposerClient::Composition::CLIENT); + } + } + *outTypesCount = mChangedLayersCache[display].size(); + return error; + } + for (uint32_t i = 0; i < *outTypesCount; ++i) { + if (outChangedLayers != nullptr) { + outChangedLayers[i] = mChangedLayersCache[display][i]; + } + if (outCompositionTypes != nullptr) { + outCompositionTypes[i] = mCompositionTypesCache[display][i]; + } + } + return HWC2_ERROR_NONE; + } + + void onLayerDestroyed(Display display, Layer layer) override { + if (mClientCompositionLayers.find(display) == mClientCompositionLayers.end()) { + return; + } + mClientCompositionLayers[display].erase(layer); + } + + void onBeforeValidateDisplay(Display display) override { + if (mClientCompositionLayers.find(display) == mClientCompositionLayers.end()) { + return; + } + + // clear the cache proactively so that we don't hold too much memory over time. + mChangedLayersCache[display].clear(); + mCompositionTypesCache[display].clear(); + + // SET_LAYER_COLOR_TRANSFORM is optional, and thus if it's not implemented, we need to + // follow the spec to make sure those layers marked as client composition before validate + // the display. + if (!mDispatch.setLayerColorTransform) { + for (Layer layer : mClientCompositionLayers[display]) { + BaseType2_1::setLayerCompositionType( + display, layer, static_cast<int32_t>(IComposerClient::Composition::CLIENT)); + } + } + } + + private: struct { HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA getDisplayIdentificationData; HWC2_PFN_SET_LAYER_COLOR_TRANSFORM setLayerColorTransform; @@ -318,6 +414,9 @@ class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> { using BaseType2_2::getRenderIntents; using BaseType2_2::setColorMode_2_2; using BaseType2_2::setLayerPerFrameMetadata; + std::map<Display, std::set<Layer>> mClientCompositionLayers; + std::map<Display, std::vector<Layer>> mChangedLayersCache; + std::map<Display, std::vector<IComposerClient::Composition>> mCompositionTypesCache; }; } // namespace detail |