mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
graphics: add composer 2.2 default impl
This adds android.hardware.graphics.composer@2.2-hal android.hardware.graphics.composer@2.2-passthrough android.hardware.graphics.composer@2.2-service The -hal module makes it easier to write composer 2.2 HAL and is reusable by vendors. The -passthrough module provides a HwcHal class that implements ComposerHal 2.2 on top of hwcomposer2, and is also resuable by vendors. Finally, the -service module provides a (stub) default implementation. Test: boots and VTS Change-Id: I4f940a9dea656abc7d9d485bf48d852c13d2ed56
This commit is contained in:
31
graphics/composer/2.2/default/Android.bp
Normal file
31
graphics/composer/2.2/default/Android.bp
Normal file
@@ -0,0 +1,31 @@
|
||||
cc_binary {
|
||||
name: "android.hardware.graphics.composer@2.2-service",
|
||||
defaults: ["hidl_defaults"],
|
||||
vendor: true,
|
||||
relative_install_path: "hw",
|
||||
srcs: ["service.cpp"],
|
||||
init_rc: ["android.hardware.graphics.composer@2.2-service.rc"],
|
||||
header_libs: [
|
||||
"android.hardware.graphics.composer@2.2-passthrough",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.graphics.composer@2.1",
|
||||
"android.hardware.graphics.composer@2.2",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"libbase",
|
||||
"libbinder",
|
||||
"libcutils",
|
||||
"libfmq",
|
||||
"libhardware",
|
||||
"libhidlbase",
|
||||
"libhidltransport",
|
||||
"libhwc2on1adapter",
|
||||
"libhwc2onfbadapter",
|
||||
"liblog",
|
||||
"libsync",
|
||||
"libutils",
|
||||
],
|
||||
cflags: [
|
||||
"-DLOG_TAG=\"ComposerHal\""
|
||||
],
|
||||
}
|
||||
5
graphics/composer/2.2/default/OWNERS
Normal file
5
graphics/composer/2.2/default/OWNERS
Normal file
@@ -0,0 +1,5 @@
|
||||
# Graphics team
|
||||
courtneygo@google.com
|
||||
jessehall@google.com
|
||||
olv@google.com
|
||||
stoza@google.com
|
||||
@@ -0,0 +1,6 @@
|
||||
service vendor.hwcomposer-2-2 /vendor/bin/hw/android.hardware.graphics.composer@2.2-service
|
||||
class hal animation
|
||||
user system
|
||||
group graphics drmrpc
|
||||
capabilities SYS_NICE
|
||||
onrestart restart surfaceflinger
|
||||
55
graphics/composer/2.2/default/service.cpp
Normal file
55
graphics/composer/2.2/default/service.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sched.h>
|
||||
|
||||
#include <android/hardware/graphics/composer/2.2/IComposer.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <composer-passthrough/2.2/HwcLoader.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
using android::hardware::graphics::composer::V2_2::IComposer;
|
||||
using android::hardware::graphics::composer::V2_2::passthrough::HwcLoader;
|
||||
|
||||
int main() {
|
||||
// the conventional HAL might start binder services
|
||||
android::ProcessState::initWithDriver("/dev/vndbinder");
|
||||
android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
|
||||
android::ProcessState::self()->startThreadPool();
|
||||
|
||||
// same as SF main thread
|
||||
struct sched_param param = {0};
|
||||
param.sched_priority = 2;
|
||||
if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) {
|
||||
ALOGE("Couldn't set SCHED_FIFO: %d", errno);
|
||||
}
|
||||
|
||||
android::hardware::configureRpcThreadpool(4, true /* will join */);
|
||||
|
||||
android::sp<IComposer> composer = HwcLoader::load();
|
||||
if (composer == nullptr) {
|
||||
return 1;
|
||||
}
|
||||
if (composer->registerAsService() != android::NO_ERROR) {
|
||||
ALOGE("failed to register service");
|
||||
return 1;
|
||||
}
|
||||
|
||||
android::hardware::joinRpcThreadpool();
|
||||
|
||||
ALOGE("service is terminating");
|
||||
return 1;
|
||||
}
|
||||
35
graphics/composer/2.2/utils/hal/Android.bp
Normal file
35
graphics/composer/2.2/utils/hal/Android.bp
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright (C) 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.
|
||||
|
||||
cc_library_headers {
|
||||
name: "android.hardware.graphics.composer@2.2-hal",
|
||||
defaults: ["hidl_defaults"],
|
||||
vendor_available: true,
|
||||
shared_libs: [
|
||||
"android.hardware.graphics.composer@2.2",
|
||||
],
|
||||
export_shared_lib_headers: [
|
||||
"android.hardware.graphics.composer@2.2",
|
||||
],
|
||||
header_libs: [
|
||||
"android.hardware.graphics.composer@2.2-command-buffer",
|
||||
"android.hardware.graphics.composer@2.1-hal",
|
||||
],
|
||||
export_header_lib_headers: [
|
||||
"android.hardware.graphics.composer@2.2-command-buffer",
|
||||
"android.hardware.graphics.composer@2.1-hal",
|
||||
],
|
||||
export_include_dirs: ["include"],
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 "Composer.h included without LOG_TAG"
|
||||
#endif
|
||||
|
||||
#include <android/hardware/graphics/composer/2.2/IComposer.h>
|
||||
#include <composer-hal/2.1/Composer.h>
|
||||
#include <composer-hal/2.2/ComposerClient.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace graphics {
|
||||
namespace composer {
|
||||
namespace V2_2 {
|
||||
namespace hal {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// ComposerImpl implements V2_*::IComposer on top of V2_*::ComposerHal
|
||||
template <typename Interface, typename Hal>
|
||||
class ComposerImpl : public V2_1::hal::detail::ComposerImpl<Interface, Hal> {
|
||||
public:
|
||||
static std::unique_ptr<ComposerImpl> create(std::unique_ptr<Hal> hal) {
|
||||
return std::make_unique<ComposerImpl>(std::move(hal));
|
||||
}
|
||||
|
||||
ComposerImpl(std::unique_ptr<Hal> hal) : BaseType2_1(std::move(hal)) {}
|
||||
|
||||
protected:
|
||||
V2_1::IComposerClient* createClient() override {
|
||||
auto client = ComposerClient::create(mHal.get());
|
||||
if (!client) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto clientDestroyed = [this]() { onClientDestroyed(); };
|
||||
client->setOnClientDestroyed(clientDestroyed);
|
||||
|
||||
return client.release();
|
||||
}
|
||||
|
||||
private:
|
||||
using BaseType2_1 = V2_1::hal::detail::ComposerImpl<Interface, Hal>;
|
||||
using BaseType2_1::mHal;
|
||||
using BaseType2_1::onClientDestroyed;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
using Composer = detail::ComposerImpl<IComposer, ComposerHal>;
|
||||
|
||||
} // namespace hal
|
||||
} // namespace V2_2
|
||||
} // namespace composer
|
||||
} // namespace graphics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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 "ComposerClient.h included without LOG_TAG"
|
||||
#endif
|
||||
|
||||
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
|
||||
#include <composer-hal/2.1/ComposerClient.h>
|
||||
#include <composer-hal/2.2/ComposerCommandEngine.h>
|
||||
#include <composer-hal/2.2/ComposerHal.h>
|
||||
#include <composer-hal/2.2/ComposerResources.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace graphics {
|
||||
namespace composer {
|
||||
namespace V2_2 {
|
||||
namespace hal {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// ComposerClientImpl implements V2_*::IComposerClient on top of V2_*::ComposerHal
|
||||
template <typename Interface, typename Hal>
|
||||
class ComposerClientImpl : public V2_1::hal::detail::ComposerClientImpl<Interface, Hal> {
|
||||
public:
|
||||
static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
|
||||
auto client = std::make_unique<ComposerClientImpl>(hal);
|
||||
return client->init() ? std::move(client) : nullptr;
|
||||
}
|
||||
|
||||
ComposerClientImpl(Hal* hal) : BaseType2_1(hal) {}
|
||||
|
||||
// IComposerClient 2.2 interface
|
||||
|
||||
Return<void> getPerFrameMetadataKeys(
|
||||
Display display, IComposerClient::getPerFrameMetadataKeys_cb hidl_cb) override {
|
||||
std::vector<IComposerClient::PerFrameMetadataKey> keys;
|
||||
Error error = mHal->getPerFrameMetadataKeys(display, &keys);
|
||||
hidl_cb(error, keys);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> getReadbackBufferAttributes(
|
||||
Display display, IComposerClient::getReadbackBufferAttributes_cb hidl_cb) override {
|
||||
PixelFormat format = static_cast<PixelFormat>(0);
|
||||
Dataspace dataspace = Dataspace::UNKNOWN;
|
||||
Error error = mHal->getReadbackBufferAttributes(display, &format, &dataspace);
|
||||
hidl_cb(error, format, dataspace);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> getReadbackBufferFence(
|
||||
Display display, IComposerClient::getReadbackBufferFence_cb hidl_cb) override {
|
||||
base::unique_fd fenceFd;
|
||||
Error error = mHal->getReadbackBufferFence(display, &fenceFd);
|
||||
if (error != Error::NONE) {
|
||||
hidl_cb(error, nullptr);
|
||||
return Void();
|
||||
}
|
||||
|
||||
NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
|
||||
hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Error> setReadbackBuffer(Display display, const hidl_handle& buffer,
|
||||
const hidl_handle& releaseFence) override {
|
||||
base::unique_fd fenceFd;
|
||||
Error error = getFenceFd(releaseFence, &fenceFd);
|
||||
if (error != Error::NONE) {
|
||||
return error;
|
||||
}
|
||||
|
||||
auto resources = static_cast<ComposerResources*>(mResources.get());
|
||||
const native_handle_t* readbackBuffer;
|
||||
ComposerResources::ReplacedBufferHandle replacedReadbackBuffer;
|
||||
error = resources->getDisplayReadbackBuffer(display, buffer.getNativeHandle(),
|
||||
&readbackBuffer, &replacedReadbackBuffer);
|
||||
if (error != Error::NONE) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return mHal->setReadbackBuffer(display, readbackBuffer, std::move(fenceFd));
|
||||
}
|
||||
|
||||
Return<Error> setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
|
||||
return mHal->setPowerMode_2_2(display, mode);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<V2_1::hal::ComposerResources> createResources() override {
|
||||
return ComposerResources::create();
|
||||
}
|
||||
|
||||
std::unique_ptr<V2_1::hal::ComposerCommandEngine> createCommandEngine() override {
|
||||
return std::make_unique<ComposerCommandEngine>(
|
||||
mHal, static_cast<ComposerResources*>(mResources.get()));
|
||||
}
|
||||
|
||||
// convert fenceFd to or from hidl_handle
|
||||
static Error getFenceFd(const hidl_handle& fenceHandle, base::unique_fd* outFenceFd) {
|
||||
auto handle = fenceHandle.getNativeHandle();
|
||||
if (handle && handle->numFds > 1) {
|
||||
ALOGE("invalid fence handle with %d fds", handle->numFds);
|
||||
return Error::BAD_PARAMETER;
|
||||
}
|
||||
|
||||
int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
|
||||
if (fenceFd >= 0) {
|
||||
fenceFd = dup(fenceFd);
|
||||
if (fenceFd < 0) {
|
||||
return Error::NO_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
outFenceFd->reset(fenceFd);
|
||||
|
||||
return Error::NONE;
|
||||
}
|
||||
|
||||
static hidl_handle getFenceHandle(const base::unique_fd& fenceFd, char* handleStorage) {
|
||||
native_handle_t* handle = nullptr;
|
||||
if (fenceFd >= 0) {
|
||||
handle = native_handle_init(handleStorage, 1, 0);
|
||||
handle->data[0] = fenceFd;
|
||||
}
|
||||
|
||||
return hidl_handle(handle);
|
||||
}
|
||||
|
||||
private:
|
||||
using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
|
||||
using BaseType2_1::mHal;
|
||||
using BaseType2_1::mResources;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
using ComposerClient = detail::ComposerClientImpl<IComposerClient, ComposerHal>;
|
||||
|
||||
} // namespace hal
|
||||
} // namespace V2_2
|
||||
} // namespace composer
|
||||
} // namespace graphics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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 "ComposerCommandEngine.h included without LOG_TAG"
|
||||
#endif
|
||||
|
||||
#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
|
||||
#include <composer-hal/2.1/ComposerCommandEngine.h>
|
||||
#include <composer-hal/2.2/ComposerHal.h>
|
||||
#include <composer-hal/2.2/ComposerResources.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace graphics {
|
||||
namespace composer {
|
||||
namespace V2_2 {
|
||||
namespace hal {
|
||||
|
||||
class ComposerCommandEngine : public V2_1::hal::ComposerCommandEngine {
|
||||
public:
|
||||
ComposerCommandEngine(ComposerHal* hal, ComposerResources* resources)
|
||||
: BaseType2_1(hal, resources), mHal(hal) {}
|
||||
|
||||
protected:
|
||||
bool executeCommand(V2_1::IComposerClient::Command command, uint16_t length) override {
|
||||
switch (static_cast<IComposerClient::Command>(command)) {
|
||||
case IComposerClient::Command::SET_PER_FRAME_METADATA:
|
||||
return executeSetPerFrameMetadata(length);
|
||||
case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
|
||||
return executeSetLayerFloatColor(length);
|
||||
default:
|
||||
return BaseType2_1::executeCommand(command, length);
|
||||
}
|
||||
}
|
||||
|
||||
bool executeSetPerFrameMetadata(uint16_t length) {
|
||||
// (key, value) pairs
|
||||
if (length % 2 != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<IComposerClient::PerFrameMetadata> metadata;
|
||||
metadata.reserve(length / 2);
|
||||
while (length > 0) {
|
||||
metadata.emplace_back(IComposerClient::PerFrameMetadata{
|
||||
static_cast<IComposerClient::PerFrameMetadataKey>(readSigned()), readFloat()});
|
||||
length -= 2;
|
||||
}
|
||||
|
||||
auto err = mHal->setPerFrameMetadata(mCurrentDisplay, metadata);
|
||||
if (err != Error::NONE) {
|
||||
mWriter.setError(getCommandLoc(), err);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool executeSetLayerFloatColor(uint16_t length) {
|
||||
if (length != CommandWriterBase::kSetLayerFloatColorLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto err = mHal->setLayerFloatColor(mCurrentDisplay, mCurrentLayer, readFloatColor());
|
||||
if (err != Error::NONE) {
|
||||
mWriter.setError(getCommandLoc(), err);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
IComposerClient::FloatColor readFloatColor() {
|
||||
return IComposerClient::FloatColor{readFloat(), readFloat(), readFloat(), readFloat()};
|
||||
}
|
||||
|
||||
private:
|
||||
using BaseType2_1 = V2_1::hal::ComposerCommandEngine;
|
||||
using BaseType2_1::mWriter;
|
||||
|
||||
ComposerHal* mHal;
|
||||
};
|
||||
|
||||
} // namespace hal
|
||||
} // namespace V2_2
|
||||
} // namespace composer
|
||||
} // namespace graphics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <android/hardware/graphics/composer/2.2/IComposer.h>
|
||||
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
|
||||
#include <composer-hal/2.1/ComposerHal.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace graphics {
|
||||
namespace composer {
|
||||
namespace V2_2 {
|
||||
namespace hal {
|
||||
|
||||
using common::V1_0::Dataspace;
|
||||
using common::V1_0::PixelFormat;
|
||||
using V2_1::Display;
|
||||
using V2_1::Error;
|
||||
using V2_1::Layer;
|
||||
|
||||
class ComposerHal : public V2_1::hal::ComposerHal {
|
||||
public:
|
||||
// superceded by setPowerMode_2_2
|
||||
Error setPowerMode(Display display, V2_1::IComposerClient::PowerMode mode) override {
|
||||
return setPowerMode_2_2(display, static_cast<IComposerClient::PowerMode>(mode));
|
||||
}
|
||||
|
||||
virtual Error getPerFrameMetadataKeys(
|
||||
Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
|
||||
virtual Error setPerFrameMetadata(
|
||||
Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
|
||||
|
||||
virtual Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
|
||||
Dataspace* outDataspace) = 0;
|
||||
virtual Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
|
||||
base::unique_fd fenceFd) = 0;
|
||||
virtual Error getReadbackBufferFence(Display display, base::unique_fd* outFenceFd) = 0;
|
||||
|
||||
virtual Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) = 0;
|
||||
|
||||
virtual Error setLayerFloatColor(Display display, Layer layer,
|
||||
IComposerClient::FloatColor color) = 0;
|
||||
};
|
||||
|
||||
} // namespace hal
|
||||
} // namespace V2_2
|
||||
} // namespace composer
|
||||
} // namespace graphics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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 "ComposerResources.h included without LOG_TAG"
|
||||
#endif
|
||||
|
||||
#include <composer-hal/2.1/ComposerResources.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace graphics {
|
||||
namespace composer {
|
||||
namespace V2_2 {
|
||||
namespace hal {
|
||||
|
||||
using V2_1::hal::ComposerHandleCache;
|
||||
using V2_1::hal::ComposerHandleImporter;
|
||||
|
||||
class ComposerDisplayResource : public V2_1::hal::ComposerDisplayResource {
|
||||
public:
|
||||
ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
|
||||
uint32_t outputBufferCacheSize)
|
||||
: V2_1::hal::ComposerDisplayResource(type, importer, outputBufferCacheSize),
|
||||
mReadbackBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, 1) {}
|
||||
|
||||
Error getReadbackBuffer(const native_handle_t* inHandle, const native_handle_t** outHandle,
|
||||
const native_handle** outReplacedHandle) {
|
||||
const uint32_t slot = 0;
|
||||
const bool fromCache = false;
|
||||
return mReadbackBufferCache.getHandle(slot, fromCache, inHandle, outHandle,
|
||||
outReplacedHandle);
|
||||
}
|
||||
|
||||
protected:
|
||||
ComposerHandleCache mReadbackBufferCache;
|
||||
};
|
||||
|
||||
class ComposerResources : public V2_1::hal::ComposerResources {
|
||||
public:
|
||||
static std::unique_ptr<ComposerResources> create() {
|
||||
auto resources = std::make_unique<ComposerResources>();
|
||||
return resources->init() ? std::move(resources) : nullptr;
|
||||
}
|
||||
|
||||
Error getDisplayReadbackBuffer(Display display, const native_handle_t* rawHandle,
|
||||
const native_handle_t** outHandle,
|
||||
ReplacedBufferHandle* outReplacedHandle) {
|
||||
// import buffer
|
||||
const native_handle_t* importedHandle;
|
||||
Error error = mImporter.importBuffer(rawHandle, &importedHandle);
|
||||
if (error != Error::NONE) {
|
||||
return error;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
|
||||
|
||||
auto iter = mDisplayResources.find(display);
|
||||
if (iter == mDisplayResources.end()) {
|
||||
mImporter.freeBuffer(importedHandle);
|
||||
return Error::BAD_DISPLAY;
|
||||
}
|
||||
ComposerDisplayResource& displayResource =
|
||||
*static_cast<ComposerDisplayResource*>(iter->second.get());
|
||||
|
||||
// update cache
|
||||
const native_handle_t* replacedHandle;
|
||||
error = displayResource.getReadbackBuffer(importedHandle, outHandle, &replacedHandle);
|
||||
if (error != Error::NONE) {
|
||||
mImporter.freeBuffer(importedHandle);
|
||||
return error;
|
||||
}
|
||||
|
||||
outReplacedHandle->reset(&mImporter, replacedHandle);
|
||||
return Error::NONE;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<V2_1::hal::ComposerDisplayResource> createDisplayResource(
|
||||
ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) override {
|
||||
return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace hal
|
||||
} // namespace V2_2
|
||||
} // namespace composer
|
||||
} // namespace graphics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
14
graphics/composer/2.2/utils/passthrough/Android.bp
Normal file
14
graphics/composer/2.2/utils/passthrough/Android.bp
Normal file
@@ -0,0 +1,14 @@
|
||||
cc_library_headers {
|
||||
name: "android.hardware.graphics.composer@2.2-passthrough",
|
||||
defaults: ["hidl_defaults"],
|
||||
vendor: true,
|
||||
header_libs: [
|
||||
"android.hardware.graphics.composer@2.1-passthrough",
|
||||
"android.hardware.graphics.composer@2.2-hal",
|
||||
],
|
||||
export_header_lib_headers: [
|
||||
"android.hardware.graphics.composer@2.1-passthrough",
|
||||
"android.hardware.graphics.composer@2.2-hal",
|
||||
],
|
||||
export_include_dirs: ["include"],
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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.2/ComposerHal.h>
|
||||
#include <composer-passthrough/2.1/HwcHal.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace graphics {
|
||||
namespace composer {
|
||||
namespace V2_2 {
|
||||
namespace passthrough {
|
||||
|
||||
namespace detail {
|
||||
|
||||
using common::V1_0::Dataspace;
|
||||
using common::V1_0::PixelFormat;
|
||||
using V2_1::Display;
|
||||
using V2_1::Error;
|
||||
using V2_1::Layer;
|
||||
|
||||
// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
|
||||
template <typename Hal>
|
||||
class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal> {
|
||||
public:
|
||||
// XXX when can we return Error::UNSUPPORTED?
|
||||
|
||||
Error getPerFrameMetadataKeys(
|
||||
Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override {
|
||||
if (!mDispatch.getPerFrameMetadataKeys) {
|
||||
return Error::UNSUPPORTED;
|
||||
}
|
||||
|
||||
uint32_t count = 0;
|
||||
int32_t error = mDispatch.getPerFrameMetadataKeys(mDevice, display, &count, nullptr);
|
||||
if (error != HWC2_ERROR_NONE) {
|
||||
return static_cast<Error>(error);
|
||||
}
|
||||
|
||||
std::vector<IComposerClient::PerFrameMetadataKey> keys(count);
|
||||
error = mDispatch.getPerFrameMetadataKeys(
|
||||
mDevice, display, &count,
|
||||
reinterpret_cast<std::underlying_type<IComposerClient::PerFrameMetadataKey>::type*>(
|
||||
keys.data()));
|
||||
if (error != HWC2_ERROR_NONE) {
|
||||
return static_cast<Error>(error);
|
||||
}
|
||||
|
||||
keys.resize(count);
|
||||
*outKeys = std::move(keys);
|
||||
return Error::NONE;
|
||||
}
|
||||
|
||||
Error setPerFrameMetadata(
|
||||
Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
|
||||
if (!mDispatch.setPerFrameMetadata) {
|
||||
return Error::UNSUPPORTED;
|
||||
}
|
||||
|
||||
std::vector<int32_t> keys;
|
||||
std::vector<float> values;
|
||||
keys.reserve(metadata.size());
|
||||
values.reserve(metadata.size());
|
||||
for (const auto& m : metadata) {
|
||||
keys.push_back(static_cast<int32_t>(m.key));
|
||||
values.push_back(m.value);
|
||||
}
|
||||
|
||||
int32_t error = mDispatch.setPerFrameMetadata(mDevice, display, metadata.size(),
|
||||
keys.data(), values.data());
|
||||
return static_cast<Error>(error);
|
||||
}
|
||||
|
||||
Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
|
||||
Dataspace* outDataspace) override {
|
||||
if (!mDispatch.getReadbackBufferAttributes) {
|
||||
return Error::UNSUPPORTED;
|
||||
}
|
||||
|
||||
int32_t format = 0;
|
||||
int32_t dataspace = 0;
|
||||
int32_t error =
|
||||
mDispatch.getReadbackBufferAttributes(mDevice, display, &format, &dataspace);
|
||||
if (error == HWC2_ERROR_NONE) {
|
||||
*outFormat = static_cast<PixelFormat>(format);
|
||||
*outDataspace = static_cast<Dataspace>(dataspace);
|
||||
}
|
||||
return static_cast<Error>(error);
|
||||
}
|
||||
|
||||
Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
|
||||
base::unique_fd fenceFd) override {
|
||||
if (!mDispatch.setReadbackBuffer) {
|
||||
return Error::UNSUPPORTED;
|
||||
}
|
||||
|
||||
int32_t error =
|
||||
mDispatch.setReadbackBuffer(mDevice, display, bufferHandle, fenceFd.release());
|
||||
return static_cast<Error>(error);
|
||||
}
|
||||
|
||||
Error getReadbackBufferFence(Display display, base::unique_fd* outFenceFd) override {
|
||||
if (!mDispatch.getReadbackBufferFence) {
|
||||
return Error::UNSUPPORTED;
|
||||
}
|
||||
|
||||
int32_t fenceFd = -1;
|
||||
int32_t error = mDispatch.getReadbackBufferFence(mDevice, display, &fenceFd);
|
||||
outFenceFd->reset(fenceFd);
|
||||
return static_cast<Error>(error);
|
||||
}
|
||||
|
||||
Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
|
||||
if (mode == IComposerClient::PowerMode::ON_SUSPEND) {
|
||||
return Error::UNSUPPORTED;
|
||||
}
|
||||
return setPowerMode(display, static_cast<V2_1::IComposerClient::PowerMode>(mode));
|
||||
}
|
||||
|
||||
Error setLayerFloatColor(Display display, Layer layer,
|
||||
IComposerClient::FloatColor color) override {
|
||||
if (!mDispatch.setLayerFloatColor) {
|
||||
return Error::UNSUPPORTED;
|
||||
}
|
||||
|
||||
int32_t error = mDispatch.setLayerFloatColor(
|
||||
mDevice, display, layer, hwc_float_color{color.r, color.g, color.b, color.a});
|
||||
return static_cast<Error>(error);
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename T>
|
||||
bool initOptionalDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
|
||||
auto pfn = mDevice->getFunction(mDevice, desc);
|
||||
if (pfn) {
|
||||
*outPfn = reinterpret_cast<T>(pfn);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool initDispatch() override {
|
||||
if (!BaseType2_1::initDispatch()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, &mDispatch.setLayerFloatColor);
|
||||
|
||||
initOptionalDispatch(HWC2_FUNCTION_SET_PER_FRAME_METADATA, &mDispatch.setPerFrameMetadata);
|
||||
initOptionalDispatch(HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS,
|
||||
&mDispatch.getPerFrameMetadataKeys);
|
||||
|
||||
initOptionalDispatch(HWC2_FUNCTION_SET_READBACK_BUFFER, &mDispatch.setReadbackBuffer);
|
||||
initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES,
|
||||
&mDispatch.getReadbackBufferAttributes);
|
||||
initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE,
|
||||
&mDispatch.getReadbackBufferFence);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct {
|
||||
HWC2_PFN_SET_LAYER_FLOAT_COLOR setLayerFloatColor;
|
||||
HWC2_PFN_SET_PER_FRAME_METADATA setPerFrameMetadata;
|
||||
HWC2_PFN_GET_PER_FRAME_METADATA_KEYS getPerFrameMetadataKeys;
|
||||
HWC2_PFN_SET_READBACK_BUFFER setReadbackBuffer;
|
||||
HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES getReadbackBufferAttributes;
|
||||
HWC2_PFN_GET_READBACK_BUFFER_FENCE getReadbackBufferFence;
|
||||
} mDispatch = {};
|
||||
|
||||
private:
|
||||
using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
|
||||
using BaseType2_1::mDevice;
|
||||
using BaseType2_1::setPowerMode;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
using HwcHal = detail::HwcHalImpl<hal::ComposerHal>;
|
||||
|
||||
} // namespace passthrough
|
||||
} // namespace V2_2
|
||||
} // namespace composer
|
||||
} // namespace graphics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 "HwcLoader.h included without LOG_TAG"
|
||||
#endif
|
||||
|
||||
#include <composer-hal/2.2/Composer.h>
|
||||
#include <composer-hal/2.2/ComposerHal.h>
|
||||
#include <composer-passthrough/2.1/HwcLoader.h>
|
||||
#include <composer-passthrough/2.2/HwcHal.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace graphics {
|
||||
namespace composer {
|
||||
namespace V2_2 {
|
||||
namespace passthrough {
|
||||
|
||||
class HwcLoader : public V2_1::passthrough::HwcLoader {
|
||||
public:
|
||||
static IComposer* load() {
|
||||
const hw_module_t* module = loadModule();
|
||||
if (!module) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto hal = createHalWithAdapter(module);
|
||||
if (!hal) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return createComposer(std::move(hal)).release();
|
||||
}
|
||||
|
||||
// create a ComposerHal instance
|
||||
static std::unique_ptr<hal::ComposerHal> createHal(const hw_module_t* module) {
|
||||
auto hal = std::make_unique<HwcHal>();
|
||||
return hal->initWithModule(module) ? std::move(hal) : nullptr;
|
||||
}
|
||||
|
||||
// create a ComposerHal instance, insert an adapter if necessary
|
||||
static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) {
|
||||
bool adapted;
|
||||
hwc2_device_t* device = openDeviceWithAdapter(module, &adapted);
|
||||
if (!device) {
|
||||
return nullptr;
|
||||
}
|
||||
auto hal = std::make_unique<HwcHal>();
|
||||
return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr;
|
||||
}
|
||||
|
||||
// create an IComposer instance
|
||||
static std::unique_ptr<IComposer> createComposer(std::unique_ptr<hal::ComposerHal> hal) {
|
||||
return hal::Composer::create(std::move(hal));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace passthrough
|
||||
} // namespace V2_2
|
||||
} // namespace composer
|
||||
} // namespace graphics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
Reference in New Issue
Block a user