Revert "Revert "Mark layers with color transform client composition if not implemented.""

This reverts commit 6f5a48f7af.

Reason for revert: Reinstating with fix
Below is the original commit message:
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: Ia2e8634b01ee1b5c99893e86ef451f90337ef90f
This commit is contained in:
Valerie Hau 2019-04-04 21:46:41 +00:00 committed by Peiyong Lin
parent 6f5a48f7af
commit 7ae8af54b3
2 changed files with 123 additions and 6 deletions

View file

@ -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;

View file

@ -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].resize(typesCount);
mCompositionTypesCache[display].resize(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