From c53ea9f5f8e8d30ad79618d57b965a492962b546 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Tue, 2 Apr 2019 17:05:39 -0700 Subject: [PATCH] Mark layers with color transform client composition if not implemented. SET_LAYER_COLOR_TRANSFORM is an optional API, and thus when it's not implemented. we want to make sure we follow the spec to mark those layers as client composition and add them into changed layers list proactively. BUG: 115554640 Test: Verify with setting color transform manually. Change-Id: I53b4039eb63cccd1b174e3c6da3b6336b85e0321 --- .../include/composer-passthrough/2.1/HwcHal.h | 28 ++++- .../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(err); } @@ -327,6 +328,7 @@ class HwcHalImpl : public Hal { std::vector* outCompositionTypes, uint32_t* outDisplayRequestMask, std::vector* outRequestedLayers, std::vector* 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(err); } - err = mDispatch.getChangedCompositionTypes(mDevice, display, &typesCount, nullptr, nullptr); + err = getChangedCompositionTypes(display, &typesCount, nullptr, nullptr); if (err != HWC2_ERROR_NONE) { return static_cast(err); } std::vector changedLayers(typesCount); std::vector compositionTypes(typesCount); - err = mDispatch.getChangedCompositionTypes( - mDevice, display, &typesCount, changedLayers.data(), - reinterpret_cast::type*>( - compositionTypes.data())); + err = getChangedCompositionTypes(display, &typesCount, changedLayers.data(), + compositionTypes.data()); if (err != HWC2_ERROR_NONE) { return static_cast(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(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::type*>( + outCompositionTypes)); + } + hwc2_device_t* mDevice = nullptr; std::unordered_set 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 class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl { @@ -130,6 +144,16 @@ class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl { 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 { 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(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 { using BaseType2_2::getRenderIntents; using BaseType2_2::setColorMode_2_2; using BaseType2_2::setLayerPerFrameMetadata; + std::map> mClientCompositionLayers; + std::map> mChangedLayersCache; + std::map> mCompositionTypesCache; }; } // namespace detail