blob: 070cf80e44d64ea1977e899a41d16ceb472702dc [file] [log] [blame]
/*
* 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.
*/
#pragma once
#ifndef LOG_TAG
#warning "HwcHal.h included without LOG_TAG"
#endif
#include <type_traits>
#include <composer-hal/2.3/ComposerHal.h>
#include <composer-passthrough/2.2/HwcHal.h>
namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_3 {
namespace passthrough {
namespace detail {
using common::V1_1::RenderIntent;
using common::V1_2::ColorMode;
using common::V1_2::Dataspace;
using common::V1_2::Hdr;
using common::V1_2::PixelFormat;
using V2_1::Display;
using V2_1::Error;
// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
template <typename Hal>
class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
public:
Error getPerFrameMetadataKeys_2_3(
Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override {
std::vector<V2_2::IComposerClient::PerFrameMetadataKey> castKeys;
Error error = getPerFrameMetadataKeys(display, &castKeys);
if (error != Error::NONE) {
return error;
}
outKeys->clear();
for (auto key : castKeys) {
outKeys->push_back(static_cast<IComposerClient::PerFrameMetadataKey>(key));
}
return Error::NONE;
}
Error setLayerPerFrameMetadata_2_3(
Display display, Layer layer,
const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
return setLayerPerFrameMetadata(
display, layer,
reinterpret_cast<const std::vector<V2_2::IComposerClient::PerFrameMetadata>&>(
metadata));
}
Error setColorMode_2_3(Display display, ColorMode mode, RenderIntent intent) override {
return setColorMode_2_2(display, static_cast<common::V1_1::ColorMode>(mode), intent);
}
Error getRenderIntents_2_3(Display display, ColorMode mode,
std::vector<RenderIntent>* outIntents) override {
return getRenderIntents(display, static_cast<common::V1_1::ColorMode>(mode), outIntents);
}
Error getColorModes_2_3(Display display, hidl_vec<ColorMode>* outModes) override {
return getColorModes_2_2(display,
reinterpret_cast<hidl_vec<common::V1_1::ColorMode>*>(outModes));
}
Error getHdrCapabilities_2_3(Display display, hidl_vec<Hdr>* outTypes, float* outMaxLuminance,
float* outMaxAverageLuminance, float* outMinLuminance) override {
return getHdrCapabilities(display, reinterpret_cast<hidl_vec<common::V1_0::Hdr>*>(outTypes),
outMaxLuminance, outMaxAverageLuminance, outMinLuminance);
}
Error getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height,
PixelFormat format, Dataspace dataspace) override {
return getClientTargetSupport_2_2(display, width, height,
static_cast<common::V1_1::PixelFormat>(format),
static_cast<common::V1_1::Dataspace>(dataspace));
}
Error getReadbackBufferAttributes_2_3(Display display, PixelFormat* outFormat,
Dataspace* outDataspace) override {
return getReadbackBufferAttributes(
display, reinterpret_cast<common::V1_1::PixelFormat*>(outFormat),
reinterpret_cast<common::V1_1::Dataspace*>(outDataspace));
}
Error getDisplayIdentificationData(Display display, uint8_t* outPort,
std::vector<uint8_t>* outData) override {
if (!mDispatch.getDisplayIdentificationData) {
return Error::UNSUPPORTED;
}
uint32_t size = 0;
int32_t error =
mDispatch.getDisplayIdentificationData(mDevice, display, outPort, &size, nullptr);
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
std::vector<uint8_t> data(size);
error =
mDispatch.getDisplayIdentificationData(mDevice, display, outPort, &size, data.data());
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
data.resize(size);
*outData = std::move(data);
return Error::NONE;
}
Error setLayerColorTransform(Display display, Layer layer, const float* matrix) override {
if (!mDispatch.setLayerColorTransform) {
return Error::UNSUPPORTED;
}
int32_t err = mDispatch.setLayerColorTransform(mDevice, display, layer, matrix);
return static_cast<Error>(err);
}
Error getDisplayedContentSamplingAttributes(
uint64_t display, PixelFormat& format, Dataspace& dataspace,
hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) override {
if (!mDispatch.getDisplayedContentSamplingAttributes) {
return Error::UNSUPPORTED;
}
int32_t formatRaw = 0;
int32_t dataspaceRaw = 0;
uint8_t componentMaskRaw = 0;
int32_t errorRaw = mDispatch.getDisplayedContentSamplingAttributes(
mDevice, display, &formatRaw, &dataspaceRaw, &componentMaskRaw);
auto error = static_cast<Error>(errorRaw);
if (error == Error::NONE) {
format = static_cast<PixelFormat>(formatRaw);
dataspace = static_cast<Dataspace>(dataspaceRaw);
componentMask =
static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(componentMaskRaw);
}
return error;
};
Error setDisplayedContentSamplingEnabled(
uint64_t display, IComposerClient::DisplayedContentSampling enable,
hidl_bitfield<IComposerClient::FormatColorComponent> componentMask,
uint64_t maxFrames) override {
if (!mDispatch.setDisplayedContentSamplingEnabled) {
return Error::UNSUPPORTED;
}
return static_cast<Error>(mDispatch.setDisplayedContentSamplingEnabled(
mDevice, display, static_cast<int32_t>(enable), componentMask, maxFrames));
}
Error getDisplayedContentSample(uint64_t display, uint64_t maxFrames, uint64_t timestamp,
uint64_t& frameCount, hidl_vec<uint64_t>& sampleComponent0,
hidl_vec<uint64_t>& sampleComponent1,
hidl_vec<uint64_t>& sampleComponent2,
hidl_vec<uint64_t>& sampleComponent3) override {
if (!mDispatch.getDisplayedContentSample) {
return Error::UNSUPPORTED;
}
int32_t size[4] = {0};
auto errorRaw = mDispatch.getDisplayedContentSample(mDevice, display, maxFrames, timestamp,
&frameCount, size, nullptr);
if (errorRaw != HWC2_ERROR_NONE) {
return static_cast<Error>(errorRaw);
}
sampleComponent0.resize(size[0]);
sampleComponent1.resize(size[1]);
sampleComponent2.resize(size[2]);
sampleComponent3.resize(size[3]);
uint64_t* samples[] = {sampleComponent0.data(), sampleComponent1.data(),
sampleComponent2.data(), sampleComponent3.data()};
errorRaw = mDispatch.getDisplayedContentSample(mDevice, display, maxFrames, timestamp,
&frameCount, size, samples);
return static_cast<Error>(errorRaw);
}
Error getDisplayCapabilities(
Display display, hidl_vec<IComposerClient::DisplayCapability>* outCapabilities) override {
if (!mDispatch.getDisplayCapabilities) {
return Error::UNSUPPORTED;
}
uint32_t count = 0;
int32_t error = mDispatch.getDisplayCapabilities(mDevice, display, &count, nullptr);
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
outCapabilities->resize(count);
error = mDispatch.getDisplayCapabilities(
mDevice, display, &count,
reinterpret_cast<std::underlying_type<IComposerClient::DisplayCapability>::type*>(
outCapabilities->data()));
if (error != HWC2_ERROR_NONE) {
*outCapabilities = hidl_vec<IComposerClient::DisplayCapability>();
return static_cast<Error>(error);
}
return Error::NONE;
}
Error setLayerPerFrameMetadataBlobs(
Display display, Layer layer,
std::vector<IComposerClient::PerFrameMetadataBlob>& metadata) override {
if (!mDispatch.setLayerPerFrameMetadataBlobs) {
return Error::UNSUPPORTED;
}
std::vector<IComposerClient::PerFrameMetadataKey> keys;
std::vector<uint32_t> sizes;
std::vector<uint8_t> blobs;
for (auto metadataBlob : metadata) {
keys.push_back(metadataBlob.key);
sizes.push_back(metadataBlob.blob.size());
int writeIndex = blobs.size();
blobs.resize(blobs.size() + metadataBlob.blob.size());
memcpy(blobs.data() + writeIndex, metadataBlob.blob.data(), metadataBlob.blob.size());
}
int32_t err = mDispatch.setLayerPerFrameMetadataBlobs(
mDevice, display, layer, static_cast<uint32_t>(metadata.size()),
reinterpret_cast<int32_t*>(keys.data()), reinterpret_cast<uint32_t*>(sizes.data()),
blobs.data());
return static_cast<Error>(err);
}
Error getDisplayBrightnessSupport(Display display, bool* outSupport) {
if (!mDispatch.getDisplayBrightnessSupport) {
return Error::UNSUPPORTED;
}
bool support = false;
int32_t error = mDispatch.getDisplayBrightnessSupport(mDevice, display, &support);
*outSupport = support;
return static_cast<Error>(error);
}
Error setDisplayBrightness(Display display, float brightness) {
if (std::isnan(brightness) || brightness > 1.0f ||
(brightness < 0.0f && brightness != -1.0f)) {
return Error::BAD_PARAMETER;
}
if (!mDispatch.setDisplayBrightness) {
return Error::UNSUPPORTED;
}
int32_t error = mDispatch.setDisplayBrightness(mDevice, display, brightness);
return static_cast<Error>(error);
}
protected:
bool initDispatch() override {
if (!BaseType2_2::initDispatch()) {
return false;
}
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_IDENTIFICATION_DATA,
&mDispatch.getDisplayIdentificationData);
this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_COLOR_TRANSFORM,
&mDispatch.setLayerColorTransform);
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
&mDispatch.getDisplayedContentSamplingAttributes);
this->initOptionalDispatch(HWC2_FUNCTION_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED,
&mDispatch.setDisplayedContentSamplingEnabled);
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAYED_CONTENT_SAMPLE,
&mDispatch.getDisplayedContentSample);
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_CAPABILITIES,
&mDispatch.getDisplayCapabilities);
this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA_BLOBS,
&mDispatch.setLayerPerFrameMetadataBlobs);
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_BRIGHTNESS_SUPPORT,
&mDispatch.getDisplayBrightnessSupport);
this->initOptionalDispatch(HWC2_FUNCTION_SET_DISPLAY_BRIGHTNESS,
&mDispatch.setDisplayBrightness);
return true;
}
private:
struct {
HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA getDisplayIdentificationData;
HWC2_PFN_SET_LAYER_COLOR_TRANSFORM setLayerColorTransform;
HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES getDisplayedContentSamplingAttributes;
HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED setDisplayedContentSamplingEnabled;
HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE getDisplayedContentSample;
HWC2_PFN_GET_DISPLAY_CAPABILITIES getDisplayCapabilities;
HWC2_PFN_SET_LAYER_PER_FRAME_METADATA_BLOBS setLayerPerFrameMetadataBlobs;
HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT getDisplayBrightnessSupport;
HWC2_PFN_SET_DISPLAY_BRIGHTNESS setDisplayBrightness;
} mDispatch = {};
using BaseType2_2 = V2_2::passthrough::detail::HwcHalImpl<Hal>;
using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
using BaseType2_1::getHdrCapabilities;
using BaseType2_1::mDevice;
using BaseType2_2::getClientTargetSupport_2_2;
using BaseType2_2::getColorModes_2_2;
using BaseType2_2::getPerFrameMetadataKeys;
using BaseType2_2::getReadbackBufferAttributes;
using BaseType2_2::getRenderIntents;
using BaseType2_2::setColorMode_2_2;
using BaseType2_2::setLayerPerFrameMetadata;
};
} // namespace detail
using HwcHal = detail::HwcHalImpl<hal::ComposerHal>;
} // namespace passthrough
} // namespace V2_3
} // namespace composer
} // namespace graphics
} // namespace hardware
} // namespace android