1049 lines
35 KiB
C++
1049 lines
35 KiB
C++
/*
|
|
* Copyright 2021, 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.
|
|
*/
|
|
|
|
#include "HalImpl.h"
|
|
|
|
#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
|
|
#include <android-base/logging.h>
|
|
#include <hardware/hwcomposer2.h>
|
|
|
|
#include "ExynosDevice.h"
|
|
#include "ExynosDeviceModule.h"
|
|
#include "ExynosDisplay.h"
|
|
#include "ExynosHWCService.h"
|
|
#include "ExynosLayer.h"
|
|
#include "TranslateHwcAidl.h"
|
|
#include "Util.h"
|
|
|
|
using namespace SOC_VERSION;
|
|
|
|
namespace aidl::android::hardware::graphics::composer3::impl {
|
|
|
|
std::unique_ptr<IComposerHal> IComposerHal::create() {
|
|
auto device = std::make_unique<ExynosDeviceModule>();
|
|
if (!device) {
|
|
return nullptr;
|
|
}
|
|
|
|
return std::make_unique<HalImpl>(std::move(device));
|
|
}
|
|
|
|
namespace hook {
|
|
|
|
void hotplug(hwc2_callback_data_t callbackData, hwc2_display_t hwcDisplay,
|
|
int32_t connected) {
|
|
auto hal = static_cast<HalImpl*>(callbackData);
|
|
int64_t display;
|
|
|
|
h2a::translate(hwcDisplay, display);
|
|
hal->getEventCallback()->onHotplug(display, connected == HWC2_CONNECTION_CONNECTED);
|
|
}
|
|
|
|
void refresh(hwc2_callback_data_t callbackData, hwc2_display_t hwcDisplay) {
|
|
auto hal = static_cast<HalImpl*>(callbackData);
|
|
int64_t display;
|
|
|
|
h2a::translate(hwcDisplay, display);
|
|
hal->getEventCallback()->onRefresh(display);
|
|
}
|
|
|
|
void vsync(hwc2_callback_data_t callbackData, hwc2_display_t hwcDisplay,
|
|
int64_t timestamp, hwc2_vsync_period_t hwcVsyncPeriodNanos) {
|
|
auto hal = static_cast<HalImpl*>(callbackData);
|
|
int64_t display;
|
|
int32_t vsyncPeriodNanos;
|
|
|
|
h2a::translate(hwcDisplay, display);
|
|
h2a::translate(hwcVsyncPeriodNanos, vsyncPeriodNanos);
|
|
hal->getEventCallback()->onVsync(display, timestamp, vsyncPeriodNanos);
|
|
}
|
|
|
|
void vsyncPeriodTimingChanged(hwc2_callback_data_t callbackData,
|
|
hwc2_display_t hwcDisplay,
|
|
hwc_vsync_period_change_timeline_t* hwcTimeline) {
|
|
auto hal = static_cast<HalImpl*>(callbackData);
|
|
int64_t display;
|
|
VsyncPeriodChangeTimeline timeline;
|
|
|
|
h2a::translate(hwcDisplay, display);
|
|
h2a::translate(*hwcTimeline, timeline);
|
|
hal->getEventCallback()->onVsyncPeriodTimingChanged(display, timeline);
|
|
}
|
|
|
|
void vsyncIdle(hwc2_callback_data_t callbackData, hwc2_display_t hwcDisplay) {
|
|
auto hal = static_cast<HalImpl*>(callbackData);
|
|
int64_t display;
|
|
|
|
h2a::translate(hwcDisplay, display);
|
|
hal->getEventCallback()->onVsyncIdle(display);
|
|
}
|
|
|
|
void seamlessPossible(hwc2_callback_data_t callbackData, hwc2_display_t hwcDisplay) {
|
|
auto hal = static_cast<HalImpl*>(callbackData);
|
|
int64_t display;
|
|
|
|
h2a::translate(hwcDisplay, display);
|
|
hal->getEventCallback()->onSeamlessPossible(display);
|
|
}
|
|
|
|
} // nampesapce hook
|
|
|
|
HalImpl::HalImpl(std::unique_ptr<ExynosDevice> device) : mDevice(std::move(device)) {
|
|
initCaps();
|
|
#ifdef USES_HWC_SERVICES
|
|
LOG(DEBUG) << "Start HWCService";
|
|
mHwcCtx = std::make_unique<ExynosHWCCtx>();
|
|
memset(&mHwcCtx->base, 0, sizeof(mHwcCtx->base));
|
|
mHwcCtx->device = mDevice.get();
|
|
|
|
auto hwcService = ::android::ExynosHWCService::getExynosHWCService();
|
|
hwcService->setExynosHWCCtx(mHwcCtx.get());
|
|
// This callback is for DP hotplug event if connected
|
|
// hwcService->setBootFinishedCallback(...);
|
|
#endif
|
|
}
|
|
|
|
void HalImpl::initCaps() {
|
|
uint32_t count = 0;
|
|
mDevice->getCapabilities(&count, nullptr);
|
|
|
|
std::vector<int32_t> halCaps(count);
|
|
mDevice->getCapabilities(&count, halCaps.data());
|
|
|
|
for (auto hwcCap : halCaps) {
|
|
Capability cap;
|
|
h2a::translate(hwcCap, cap);
|
|
mCaps.insert(cap);
|
|
}
|
|
|
|
mCaps.insert(Capability::BOOT_DISPLAY_CONFIG);
|
|
}
|
|
|
|
int32_t HalImpl::getHalDisplay(int64_t display, ExynosDisplay*& halDisplay) {
|
|
hwc2_display_t hwcDisplay;
|
|
a2h::translate(display, hwcDisplay);
|
|
halDisplay = mDevice->getDisplay(static_cast<uint32_t>(hwcDisplay));
|
|
|
|
if (!halDisplay) { [[unlikely]]
|
|
return HWC2_ERROR_BAD_DISPLAY;
|
|
}
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getHalLayer(int64_t display, int64_t layer, ExynosLayer*& halLayer) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
hwc2_layer_t hwcLayer;
|
|
a2h::translate(layer, hwcLayer);
|
|
halLayer = halDisplay->checkLayer(hwcLayer);
|
|
if (!halLayer) { [[unlikely]]
|
|
return HWC2_ERROR_BAD_LAYER;
|
|
}
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
bool HalImpl::hasCapability(Capability cap) {
|
|
return mCaps.find(cap) != mCaps.end();
|
|
}
|
|
|
|
void HalImpl::getCapabilities(std::vector<Capability>* caps) {
|
|
caps->clear();
|
|
caps->insert(caps->begin(), mCaps.begin(), mCaps.end());
|
|
}
|
|
|
|
void HalImpl::dumpDebugInfo(std::string* output) {
|
|
if (output == nullptr) return;
|
|
|
|
String8 result;
|
|
mDevice->dump(result);
|
|
|
|
output->resize(result.size());
|
|
output->assign(result.c_str());
|
|
}
|
|
|
|
void HalImpl::registerEventCallback(EventCallback* callback) {
|
|
mEventCallback = callback;
|
|
|
|
mDevice->registerCallback(HWC2_CALLBACK_HOTPLUG, this,
|
|
reinterpret_cast<hwc2_function_pointer_t>(hook::hotplug));
|
|
mDevice->registerCallback(HWC2_CALLBACK_REFRESH, this,
|
|
reinterpret_cast<hwc2_function_pointer_t>(hook::refresh));
|
|
mDevice->registerCallback(HWC2_CALLBACK_VSYNC_2_4, this,
|
|
reinterpret_cast<hwc2_function_pointer_t>(hook::vsync));
|
|
mDevice->registerCallback(HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this,
|
|
reinterpret_cast<hwc2_function_pointer_t>(hook::vsyncPeriodTimingChanged));
|
|
mDevice->registerCallback(HWC2_CALLBACK_SEAMLESS_POSSIBLE, this,
|
|
reinterpret_cast<hwc2_function_pointer_t>(hook::seamlessPossible));
|
|
|
|
// register HWC3 Callback
|
|
mDevice->registerHwc3Callback(IComposerCallback::TRANSACTION_onVsyncIdle, this,
|
|
reinterpret_cast<hwc2_function_pointer_t>(hook::vsyncIdle));
|
|
}
|
|
|
|
void HalImpl::unregisterEventCallback() {
|
|
mDevice->registerCallback(HWC2_CALLBACK_HOTPLUG, this, nullptr);
|
|
mDevice->registerCallback(HWC2_CALLBACK_REFRESH, this, nullptr);
|
|
mDevice->registerCallback(HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
|
|
mDevice->registerCallback(HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this, nullptr);
|
|
mDevice->registerCallback(HWC2_CALLBACK_SEAMLESS_POSSIBLE, this, nullptr);
|
|
|
|
// unregister HWC3 Callback
|
|
mDevice->registerHwc3Callback(IComposerCallback::TRANSACTION_onVsyncIdle, this, nullptr);
|
|
|
|
mEventCallback = nullptr;
|
|
}
|
|
|
|
int32_t HalImpl::acceptDisplayChanges(int64_t display) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->acceptDisplayChanges();
|
|
}
|
|
|
|
int32_t HalImpl::createLayer(int64_t display, int64_t* outLayer) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
hwc2_layer_t hwcLayer = 0;
|
|
RET_IF_ERR(halDisplay->createLayer(&hwcLayer));
|
|
|
|
h2a::translate(hwcLayer, *outLayer);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::destroyLayer(int64_t display, int64_t layer) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
return halDisplay->destroyLayer(reinterpret_cast<hwc2_layer_t>(halLayer));
|
|
}
|
|
|
|
int32_t HalImpl::createVirtualDisplay(uint32_t width, uint32_t height, AidlPixelFormat format,
|
|
VirtualDisplay* outDisplay) {
|
|
int32_t hwcFormat;
|
|
a2h::translate(format, hwcFormat);
|
|
hwc2_display_t hwcDisplay = getDisplayId(HWC_DISPLAY_VIRTUAL, 0);
|
|
auto halDisplay = mDevice->getDisplay(static_cast<uint32_t>(hwcDisplay));
|
|
if (!halDisplay) {
|
|
return HWC2_ERROR_BAD_PARAMETER;
|
|
}
|
|
|
|
RET_IF_ERR(mDevice->createVirtualDisplay(width, height, &hwcFormat, halDisplay));
|
|
|
|
h2a::translate(hwcDisplay, outDisplay->display);
|
|
h2a::translate(hwcFormat, outDisplay->format);
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::destroyVirtualDisplay(int64_t display) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return mDevice->destroyVirtualDisplay(halDisplay);
|
|
}
|
|
|
|
int32_t HalImpl::getActiveConfig(int64_t display, int32_t* outConfig) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
hwc2_config_t hwcConfig;
|
|
RET_IF_ERR(halDisplay->getActiveConfig(&hwcConfig));
|
|
|
|
h2a::translate(hwcConfig, *outConfig);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getColorModes(int64_t display, std::vector<ColorMode>* outModes) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t count = 0;
|
|
RET_IF_ERR(halDisplay->getColorModes(&count, nullptr));
|
|
|
|
std::vector<int32_t> hwcModes(count);
|
|
RET_IF_ERR(halDisplay->getColorModes(&count, hwcModes.data()));
|
|
|
|
h2a::translate(hwcModes, *outModes);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDataspaceSaturationMatrix([[maybe_unused]] common::Dataspace dataspace,
|
|
std::vector<float>* matrix) {
|
|
// Pixel HWC does not support dataspace saturation matrix, return unit matrix.
|
|
std::vector<float> unitMatrix = {
|
|
1.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 1.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 1.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 1.0f,
|
|
};
|
|
|
|
*matrix = std::move(unitMatrix);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayAttribute(int64_t display, int32_t config,
|
|
DisplayAttribute attribute, int32_t* outValue) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
hwc2_config_t hwcConfig;
|
|
int32_t hwcAttr;
|
|
a2h::translate(config, hwcConfig);
|
|
a2h::translate(attribute, hwcAttr);
|
|
|
|
auto err = halDisplay->getDisplayAttribute(hwcConfig, hwcAttr, outValue);
|
|
if (err != HWC2_ERROR_NONE && *outValue == -1) {
|
|
return HWC2_ERROR_BAD_PARAMETER;
|
|
}
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayBrightnessSupport(int64_t display, bool& outSupport) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->getDisplayBrightnessSupport(&outSupport);
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayCapabilities(int64_t display,
|
|
std::vector<DisplayCapability>* caps) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t count = 0;
|
|
RET_IF_ERR(halDisplay->getDisplayCapabilities(&count, nullptr));
|
|
|
|
std::vector<uint32_t> hwcCaps(count);
|
|
RET_IF_ERR(halDisplay->getDisplayCapabilities(&count, hwcCaps.data()));
|
|
|
|
h2a::translate(hwcCaps, *caps);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayConfigs(int64_t display, std::vector<int32_t>* configs) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t count = 0;
|
|
RET_IF_ERR(halDisplay->getDisplayConfigs(&count, nullptr));
|
|
|
|
std::vector<hwc2_config_t> hwcConfigs(count);
|
|
RET_IF_ERR(halDisplay->getDisplayConfigs(&count, hwcConfigs.data()));
|
|
|
|
h2a::translate(hwcConfigs, *configs);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayConnectionType(int64_t display, DisplayConnectionType* outType) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t hwcType = HWC2_DISPLAY_CONNECTION_TYPE_INTERNAL;
|
|
RET_IF_ERR(halDisplay->getDisplayConnectionType(&hwcType));
|
|
h2a::translate(hwcType, *outType);
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayIdentificationData(int64_t display, DisplayIdentification *id) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint8_t port;
|
|
uint32_t count = 0;
|
|
RET_IF_ERR(halDisplay->getDisplayIdentificationData(&port, &count, nullptr));
|
|
|
|
id->data.resize(count);
|
|
RET_IF_ERR(halDisplay->getDisplayIdentificationData(&port, &count, id->data.data()));
|
|
|
|
h2a::translate(port, id->port);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayName(int64_t display, std::string* outName) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t count = 0;
|
|
RET_IF_ERR(halDisplay->getDisplayName(&count, nullptr));
|
|
|
|
outName->resize(count);
|
|
RET_IF_ERR(halDisplay->getDisplayName(&count, outName->data()));
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayVsyncPeriod(int64_t display, int32_t* outVsyncPeriod) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
hwc2_vsync_period_t hwcVsyncPeriod;
|
|
RET_IF_ERR(halDisplay->getDisplayVsyncPeriod(&hwcVsyncPeriod));
|
|
|
|
h2a::translate(hwcVsyncPeriod, *outVsyncPeriod);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayedContentSample([[maybe_unused]] int64_t display,
|
|
[[maybe_unused]] int64_t maxFrames,
|
|
[[maybe_unused]] int64_t timestamp,
|
|
[[maybe_unused]] DisplayContentSample* samples) {
|
|
return HWC2_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayedContentSamplingAttributes(
|
|
[[maybe_unused]] int64_t display,
|
|
[[maybe_unused]] DisplayContentSamplingAttributes* attrs) {
|
|
return HWC2_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayPhysicalOrientation(int64_t display,
|
|
common::Transform* orientation) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
HwcMountOrientation hwcOrientation;
|
|
RET_IF_ERR(halDisplay->getMountOrientation(&hwcOrientation));
|
|
h2a::translate(hwcOrientation, *orientation);
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getDozeSupport(int64_t display, bool& support) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t hwcSupport;
|
|
RET_IF_ERR(halDisplay->getDozeSupport(&hwcSupport));
|
|
|
|
h2a::translate(hwcSupport, support);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getHdrCapabilities(int64_t display, HdrCapabilities* caps) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t count = 0;
|
|
RET_IF_ERR(halDisplay->getHdrCapabilities(&count, nullptr, &caps->maxLuminance,
|
|
&caps->maxAverageLuminance,
|
|
&caps->minLuminance));
|
|
std::vector<int32_t> hwcHdrTypes(count);
|
|
RET_IF_ERR(halDisplay->getHdrCapabilities(&count, hwcHdrTypes.data(),
|
|
&caps->maxLuminance,
|
|
&caps->maxAverageLuminance,
|
|
&caps->minLuminance));
|
|
|
|
h2a::translate(hwcHdrTypes, caps->types);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getMaxVirtualDisplayCount(int32_t* count) {
|
|
uint32_t hwcCount = mDevice->getMaxVirtualDisplayCount();
|
|
h2a::translate(hwcCount, *count);
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getPerFrameMetadataKeys(int64_t display,
|
|
std::vector<PerFrameMetadataKey>* keys) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t numKeys = 0;
|
|
auto resManager = mDevice->mResourceManager;
|
|
if (resManager->hasHDR10PlusMPP()) {
|
|
numKeys = HWC2_HDR10_PLUS_SEI + 1;
|
|
} else {
|
|
numKeys = HWC2_MAX_FRAME_AVERAGE_LIGHT_LEVEL + 1;
|
|
}
|
|
for (uint32_t i = 0; i < numKeys; ++i) {
|
|
PerFrameMetadataKey key;
|
|
h2a::translate(i, key);
|
|
keys->push_back(key);
|
|
}
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getReadbackBufferAttributes(int64_t display,
|
|
ReadbackBufferAttributes* attrs) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t format = -1;
|
|
int32_t dataspace = -1;
|
|
RET_IF_ERR(halDisplay->getReadbackBufferAttributes(&format, &dataspace));
|
|
|
|
h2a::translate(format, attrs->format);
|
|
h2a::translate(dataspace, attrs->dataspace);
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getReadbackBufferFence(int64_t display,
|
|
ndk::ScopedFileDescriptor* acquireFence) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t fd = -1;
|
|
RET_IF_ERR(halDisplay->getReadbackBufferFence(&fd));
|
|
|
|
h2a::translate(fd, *acquireFence);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getRenderIntents(int64_t display, ColorMode mode,
|
|
std::vector<RenderIntent>* intents) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t hwcMode;
|
|
uint32_t count = 0;
|
|
a2h::translate(mode, hwcMode);
|
|
RET_IF_ERR(halDisplay->getRenderIntents(hwcMode, &count, nullptr));
|
|
|
|
std::vector<int32_t> hwcIntents(count);
|
|
RET_IF_ERR(halDisplay->getRenderIntents(hwcMode, &count, hwcIntents.data()));
|
|
|
|
h2a::translate(hwcIntents, *intents);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getSupportedContentTypes(int64_t display, std::vector<ContentType>* types) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t count = 0;
|
|
RET_IF_ERR(halDisplay->getSupportedContentTypes(&count, nullptr));
|
|
|
|
std::vector<uint32_t> hwcTypes(count);
|
|
RET_IF_ERR(halDisplay->getSupportedContentTypes(&count, hwcTypes.data()));
|
|
|
|
h2a::translate(hwcTypes, *types);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::flushDisplayBrightnessChange(int64_t display) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->flushDisplayBrightnessChange();
|
|
}
|
|
|
|
int32_t HalImpl::presentDisplay(int64_t display, ndk::ScopedFileDescriptor& fence,
|
|
std::vector<int64_t>* outLayers,
|
|
std::vector<ndk::ScopedFileDescriptor>* outReleaseFences) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
// TODO: not expect acceptDisplayChanges if there are no changes to accept
|
|
if (halDisplay->mRenderingState == RENDERING_STATE_VALIDATED) {
|
|
LOG(INFO) << halDisplay->mDisplayName.string()
|
|
<< ": acceptDisplayChanges was not called";
|
|
if (halDisplay->acceptDisplayChanges() != HWC2_ERROR_NONE) {
|
|
LOG(ERROR) << halDisplay->mDisplayName.string()
|
|
<< ": acceptDisplayChanges is failed";
|
|
}
|
|
}
|
|
|
|
int32_t hwcFence;
|
|
RET_IF_ERR(halDisplay->presentDisplay(&hwcFence));
|
|
h2a::translate(hwcFence, fence);
|
|
|
|
uint32_t count = 0;
|
|
RET_IF_ERR(halDisplay->getReleaseFences(&count, nullptr, nullptr));
|
|
|
|
std::vector<hwc2_layer_t> hwcLayers(count);
|
|
std::vector<int32_t> hwcFences(count);
|
|
RET_IF_ERR(halDisplay->getReleaseFences(&count, hwcLayers.data(), hwcFences.data()));
|
|
|
|
h2a::translate(hwcLayers, *outLayers);
|
|
h2a::translate(hwcFences, *outReleaseFences);
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::setActiveConfig(int64_t display, int32_t config) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
hwc2_config_t hwcConfig;
|
|
a2h::translate(config, hwcConfig);
|
|
return halDisplay->setActiveConfig(hwcConfig);
|
|
}
|
|
|
|
int32_t HalImpl::setActiveConfigWithConstraints(
|
|
int64_t display, int32_t config,
|
|
const VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
|
|
VsyncPeriodChangeTimeline* timeline) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
hwc2_config_t hwcConfig;
|
|
hwc_vsync_period_change_constraints_t hwcConstraints;
|
|
hwc_vsync_period_change_timeline_t hwcTimeline;
|
|
|
|
a2h::translate(config, hwcConfig);
|
|
a2h::translate(vsyncPeriodChangeConstraints, hwcConstraints);
|
|
RET_IF_ERR(halDisplay->setActiveConfigWithConstraints(hwcConfig, &hwcConstraints, &hwcTimeline));
|
|
|
|
h2a::translate(hwcTimeline, *timeline);
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::setBootDisplayConfig(int64_t display, int32_t config) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->setBootDisplayConfig(config);
|
|
}
|
|
|
|
int32_t HalImpl::clearBootDisplayConfig(int64_t display) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->clearBootDisplayConfig();
|
|
}
|
|
|
|
int32_t HalImpl::getPreferredBootDisplayConfig(int64_t display, int32_t* config) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->getPreferredBootDisplayConfig(config);
|
|
}
|
|
|
|
int32_t HalImpl::setAutoLowLatencyMode(int64_t display, bool on) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->setAutoLowLatencyMode(on);
|
|
}
|
|
|
|
int32_t HalImpl::setClientTarget(int64_t display, buffer_handle_t target,
|
|
const ndk::ScopedFileDescriptor& fence,
|
|
common::Dataspace dataspace,
|
|
const std::vector<common::Rect>& damage) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t hwcFence;
|
|
int32_t hwcDataspace;
|
|
std::vector<hwc_rect_t> hwcDamage;
|
|
|
|
a2h::translate(fence, hwcFence);
|
|
a2h::translate(dataspace, hwcDataspace);
|
|
a2h::translate(damage, hwcDamage);
|
|
hwc_region_t region = { hwcDamage.size(), hwcDamage.data() };
|
|
UNUSED(region);
|
|
|
|
return halDisplay->setClientTarget(target, hwcFence, hwcDataspace);
|
|
}
|
|
|
|
int32_t HalImpl::setColorMode(int64_t display, ColorMode mode, RenderIntent intent) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t hwcMode;
|
|
int32_t hwcIntent;
|
|
|
|
a2h::translate(mode, hwcMode);
|
|
a2h::translate(intent, hwcIntent);
|
|
return halDisplay->setColorModeWithRenderIntent(hwcMode, hwcIntent);
|
|
}
|
|
|
|
int32_t HalImpl::setColorTransform(int64_t display, const std::vector<float>& matrix) {
|
|
// clang-format off
|
|
constexpr std::array<float, 16> kIdentity = {
|
|
1.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 1.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 1.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 1.0f,
|
|
};
|
|
// clang-format on
|
|
const bool isIdentity = (std::equal(matrix.begin(), matrix.end(), kIdentity.begin()));
|
|
const common::ColorTransform hint = isIdentity ? common::ColorTransform::IDENTITY
|
|
: common::ColorTransform::ARBITRARY_MATRIX;
|
|
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t hwcHint;
|
|
a2h::translate(hint, hwcHint);
|
|
return halDisplay->setColorTransform(matrix.data(), hwcHint);
|
|
}
|
|
|
|
int32_t HalImpl::setContentType(int64_t display, ContentType contentType) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t type;
|
|
a2h::translate(contentType, type);
|
|
return halDisplay->setContentType(type);
|
|
}
|
|
|
|
int32_t HalImpl::setDisplayBrightness(int64_t display, float brightness) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->setDisplayBrightness(brightness, true /* wait present */);
|
|
}
|
|
|
|
int32_t HalImpl::setDisplayedContentSamplingEnabled(
|
|
[[maybe_unused]] int64_t display,
|
|
[[maybe_unused]] bool enable,
|
|
[[maybe_unused]] FormatColorComponent componentMask,
|
|
[[maybe_unused]] int64_t maxFrames) {
|
|
return HWC2_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
int32_t HalImpl::setLayerBlendMode(int64_t display, int64_t layer, common::BlendMode mode) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
int32_t hwcMode;
|
|
a2h::translate(mode, hwcMode);
|
|
return halLayer->setLayerBlendMode(hwcMode);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerBuffer(int64_t display, int64_t layer, buffer_handle_t buffer,
|
|
const ndk::ScopedFileDescriptor& acquireFence) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
int32_t hwcFd;
|
|
a2h::translate(acquireFence, hwcFd);
|
|
|
|
return halLayer->setLayerBuffer(buffer, hwcFd);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerColor(int64_t display, int64_t layer, Color color) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
hwc_color_t hwcColor;
|
|
a2h::translate(color, hwcColor);
|
|
return halLayer->setLayerColor(hwcColor);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerColorTransform(int64_t display, int64_t layer,
|
|
const std::vector<float>& matrix) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
return halLayer->setLayerColorTransform(matrix.data());
|
|
}
|
|
|
|
int32_t HalImpl::setLayerCompositionType(int64_t display, int64_t layer, Composition type) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
int32_t hwcType;
|
|
a2h::translate(type, hwcType);
|
|
return halLayer->setLayerCompositionType(hwcType);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
return halLayer->setCursorPosition(x, y);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerDataspace(int64_t display, int64_t layer, common::Dataspace dataspace) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
int32_t hwcDataspace;
|
|
a2h::translate(dataspace, hwcDataspace);
|
|
return halLayer->setLayerDataspace(hwcDataspace);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerDisplayFrame(int64_t display, int64_t layer, const common::Rect& frame) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
hwc_rect_t hwcFrame;
|
|
a2h::translate(frame, hwcFrame);
|
|
return halLayer->setLayerDisplayFrame(hwcFrame);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerPerFrameMetadata(int64_t display, int64_t layer,
|
|
const std::vector<std::optional<PerFrameMetadata>>& metadata) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
uint32_t count = metadata.size();
|
|
std::vector<int32_t> keys;
|
|
std::vector<float> values;
|
|
|
|
for (uint32_t ix = 0; ix < count; ++ix) {
|
|
if (metadata[ix]) {
|
|
int32_t key;
|
|
a2h::translate(metadata[ix]->key, key);
|
|
keys.push_back(key);
|
|
values.push_back(metadata[ix]->value);
|
|
}
|
|
}
|
|
|
|
return halLayer->setLayerPerFrameMetadata(count, keys.data(), values.data());
|
|
}
|
|
|
|
int32_t HalImpl::setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
|
|
const std::vector<std::optional<PerFrameMetadataBlob>>& blobs) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
uint32_t count = blobs.size();
|
|
std::vector<int32_t> keys;
|
|
std::vector<uint32_t> sizes;
|
|
std::vector<uint8_t> values;
|
|
|
|
for (uint32_t ix = 0; ix < count; ++ix) {
|
|
if (blobs[ix]) {
|
|
int32_t key;
|
|
a2h::translate(blobs[ix]->key, key);
|
|
keys.push_back(key);
|
|
sizes.push_back(blobs[ix]->blob.size());
|
|
values.insert(values.end(), blobs[ix]->blob.begin(), blobs[ix]->blob.end());
|
|
}
|
|
}
|
|
|
|
return halLayer->setLayerPerFrameMetadataBlobs(count, keys.data(), sizes.data(),
|
|
values.data());
|
|
}
|
|
|
|
int32_t HalImpl::setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
return halLayer->setLayerPlaneAlpha(alpha);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerSidebandStream([[maybe_unused]] int64_t display,
|
|
[[maybe_unused]] int64_t layer,
|
|
[[maybe_unused]] buffer_handle_t stream) {
|
|
return HWC2_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
int32_t HalImpl::setLayerSourceCrop(int64_t display, int64_t layer, const common::FRect& crop) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
hwc_frect_t hwcCrop;
|
|
a2h::translate(crop, hwcCrop);
|
|
return halLayer->setLayerSourceCrop(hwcCrop);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerSurfaceDamage(int64_t display, int64_t layer,
|
|
const std::vector<std::optional<common::Rect>>& damage) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
std::vector<hwc_rect_t> hwcDamage;
|
|
a2h::translate(damage, hwcDamage);
|
|
hwc_region_t region = { hwcDamage.size(), hwcDamage.data() };
|
|
|
|
return halLayer->setLayerSurfaceDamage(region);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerTransform(int64_t display, int64_t layer, common::Transform transform) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
int32_t hwcTransform;
|
|
a2h::translate(transform, hwcTransform);
|
|
|
|
return halLayer->setLayerTransform(hwcTransform);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerVisibleRegion(int64_t display, int64_t layer,
|
|
const std::vector<std::optional<common::Rect>>& visible) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
std::vector<hwc_rect_t> hwcVisible;
|
|
a2h::translate(visible, hwcVisible);
|
|
hwc_region_t region = { hwcVisible.size(), hwcVisible.data() };
|
|
|
|
return halLayer->setLayerVisibleRegion(region);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerBrightness(int64_t display, int64_t layer, float brightness) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
return halLayer->setLayerBrightness(brightness);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
|
|
ExynosLayer *halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
return halLayer->setLayerZOrder(z);
|
|
}
|
|
|
|
int32_t HalImpl::setOutputBuffer(int64_t display, buffer_handle_t buffer,
|
|
const ndk::ScopedFileDescriptor& releaseFence) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t hwcFence;
|
|
a2h::translate(releaseFence, hwcFence);
|
|
|
|
auto err = halDisplay->setOutputBuffer(buffer, hwcFence);
|
|
// unlike in setClientTarget, releaseFence is owned by us
|
|
if (err == HWC2_ERROR_NONE && hwcFence >= 0) {
|
|
close(hwcFence);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int32_t HalImpl::setPowerMode(int64_t display, PowerMode mode) {
|
|
if (mode == PowerMode::ON_SUSPEND || mode == PowerMode::DOZE_SUSPEND) {
|
|
return HWC2_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t hwcMode;
|
|
a2h::translate(mode, hwcMode);
|
|
return halDisplay->setPowerMode(hwcMode);
|
|
}
|
|
|
|
int32_t HalImpl::setReadbackBuffer(int64_t display, buffer_handle_t buffer,
|
|
const ndk::ScopedFileDescriptor& releaseFence) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
int32_t hwcFence;
|
|
a2h::translate(releaseFence, hwcFence);
|
|
|
|
return halDisplay->setReadbackBuffer(buffer, hwcFence);
|
|
}
|
|
|
|
int32_t HalImpl::setVsyncEnabled(int64_t display, bool enabled) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
hwc2_vsync_t hwcEnable;
|
|
a2h::translate(enabled, hwcEnable);
|
|
return halDisplay->setVsyncEnabled(hwcEnable);
|
|
}
|
|
|
|
int32_t HalImpl::setIdleTimerEnabled(int64_t display, int32_t timeout) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->setDisplayIdleTimer(timeout);
|
|
}
|
|
|
|
int32_t HalImpl::validateDisplay(int64_t display, std::vector<int64_t>* outChangedLayers,
|
|
std::vector<Composition>* outCompositionTypes,
|
|
uint32_t* outDisplayRequestMask,
|
|
std::vector<int64_t>* outRequestedLayers,
|
|
std::vector<int32_t>* outRequestMasks,
|
|
ClientTargetProperty* outClientTargetProperty,
|
|
DimmingStage* outDimmingStage) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
uint32_t typesCount = 0;
|
|
uint32_t reqsCount = 0;
|
|
auto err = halDisplay->validateDisplay(&typesCount, &reqsCount);
|
|
|
|
if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
|
|
return err;
|
|
}
|
|
|
|
std::vector<hwc2_layer_t> hwcChangedLayers(typesCount);
|
|
std::vector<int32_t> hwcCompositionTypes(typesCount);
|
|
RET_IF_ERR(halDisplay->getChangedCompositionTypes(&typesCount, hwcChangedLayers.data(),
|
|
hwcCompositionTypes.data()));
|
|
|
|
int32_t displayReqs;
|
|
std::vector<hwc2_layer_t> hwcRequestedLayers(reqsCount);
|
|
outRequestMasks->resize(reqsCount);
|
|
RET_IF_ERR(halDisplay->getDisplayRequests(&displayReqs, &reqsCount,
|
|
hwcRequestedLayers.data(), outRequestMasks->data()));
|
|
|
|
h2a::translate(hwcChangedLayers, *outChangedLayers);
|
|
h2a::translate(hwcCompositionTypes, *outCompositionTypes);
|
|
*outDisplayRequestMask = displayReqs;
|
|
h2a::translate(hwcRequestedLayers, *outRequestedLayers);
|
|
|
|
hwc_client_target_property hwcProperty;
|
|
HwcDimmingStage hwcDimmingStage;
|
|
if (!halDisplay->getClientTargetProperty(&hwcProperty, &hwcDimmingStage)) {
|
|
h2a::translate(hwcDimmingStage, *outDimmingStage);
|
|
h2a::translate(hwcProperty, *outClientTargetProperty);
|
|
} // else ignore this error
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int HalImpl::setExpectedPresentTime(
|
|
int64_t display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
if (!expectedPresentTime.has_value()) return HWC2_ERROR_NONE;
|
|
|
|
if (halDisplay->getPendingExpectedPresentTime() != 0) {
|
|
ALOGW("HalImpl: set expected present time multiple times in one frame");
|
|
}
|
|
|
|
halDisplay->setExpectedPresentTime(expectedPresentTime->timestampNanos);
|
|
|
|
return HWC2_ERROR_NONE;
|
|
}
|
|
|
|
int32_t HalImpl::getRCDLayerSupport(int64_t display, bool& outSupport) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->getRCDLayerSupport(outSupport);
|
|
}
|
|
|
|
int32_t HalImpl::setLayerBlockingRegion(
|
|
int64_t display, int64_t layer,
|
|
const std::vector<std::optional<common::Rect>>& blockingRegion) {
|
|
ExynosLayer* halLayer;
|
|
RET_IF_ERR(getHalLayer(display, layer, halLayer));
|
|
|
|
std::vector<hwc_rect_t> halBlockingRegion;
|
|
a2h::translate(blockingRegion, halBlockingRegion);
|
|
|
|
return halLayer->setLayerBlockingRegion(halBlockingRegion);
|
|
}
|
|
|
|
int32_t HalImpl::getDisplayIdleTimerSupport(int64_t display, bool& outSupport) {
|
|
ExynosDisplay* halDisplay;
|
|
RET_IF_ERR(getHalDisplay(display, halDisplay));
|
|
|
|
return halDisplay->getDisplayIdleTimerSupport(outSupport);
|
|
}
|
|
|
|
} // namespace aidl::android::hardware::graphics::composer3::impl
|