drm_hwcomposer: Add hwc3 frontend stub
Adds a stub implementation of the HWC3 interface and service.
This is a barebones implementation of HWC3 interface that should contain
all the necessary code to build a HWC3 module but provides no
functionality.
The project [1] was used as a reference.
[1]: https://android.googlesource.com/platform/hardware/google/graphics/common/+/refs/tags/android-13.0.0_r18/hwc3/
Change-Id: I99754bb72f12183a94b24b7182cb7857173b31d2
Co-authored-by: Roman Stratiienko <r.stratiienko@gmail.com>
Signed-off-by: Dennis Tsiang <dennis.tsiang@arm.com>
Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
Signed-off-by: Normunds Rieksts <normunds.rieksts@arm.com>
Signed-off-by: Drew Davenport <ddavenport@google.com>
diff --git a/hwc3/Composer.cpp b/hwc3/Composer.cpp
new file mode 100644
index 0000000..5f90797
--- /dev/null
+++ b/hwc3/Composer.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+
+#include "Composer.h"
+
+#include <android-base/logging.h>
+#include <android/binder_ibinder_platform.h>
+
+#include "utils/log.h"
+
+namespace aidl::android::hardware::graphics::composer3::impl {
+
+// NOLINTNEXTLINE
+#define DEBUG_FUNC() ALOGV("%s", __func__)
+
+ndk::ScopedAStatus Composer::createClient(
+ std::shared_ptr<IComposerClient>* out_client) {
+ DEBUG_FUNC();
+
+ auto client = ndk::SharedRefBase::make<ComposerClient>();
+ if (!client) {
+ *out_client = nullptr;
+ return ndk::ScopedAStatus::fromServiceSpecificError(EX_NO_RESOURCES);
+ }
+
+ *out_client = client;
+
+ return ndk::ScopedAStatus::ok();
+}
+
+binder_status_t Composer::dump(int fd, const char** /*args*/,
+ uint32_t /*numArgs*/) {
+ auto output = std::string("hwc3-drm");
+ write(fd, output.c_str(), output.size());
+ return STATUS_OK;
+}
+
+ndk::ScopedAStatus Composer::getCapabilities(
+ std::vector<Capability>* /*caps*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+::ndk::SpAIBinder Composer::createBinder() {
+ auto binder = BnComposer::createBinder();
+ AIBinder_setInheritRt(binder.get(), true);
+ return binder;
+}
+
+} // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/Composer.h b/hwc3/Composer.h
new file mode 100644
index 0000000..b29d0cf
--- /dev/null
+++ b/hwc3/Composer.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/graphics/composer3/BnComposer.h>
+#include <utils/Mutex.h>
+
+#include "ComposerClient.h"
+
+namespace aidl::android::hardware::graphics::composer3::impl {
+
+class Composer : public BnComposer {
+ public:
+ Composer() = default;
+
+ binder_status_t dump(int fd, const char** args, uint32_t num_args) override;
+
+ // compser3 api
+ ndk::ScopedAStatus createClient(
+ std::shared_ptr<IComposerClient>* client) override;
+ ndk::ScopedAStatus getCapabilities(std::vector<Capability>* caps) override;
+
+ protected:
+ ::ndk::SpAIBinder createBinder() override;
+};
+
+} // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
new file mode 100644
index 0000000..9ebba31
--- /dev/null
+++ b/hwc3/ComposerClient.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+
+#include "ComposerClient.h"
+
+#include <android-base/logging.h>
+#include <android/binder_ibinder_platform.h>
+
+#include "utils/log.h"
+
+namespace aidl::android::hardware::graphics::composer3::impl {
+
+// NOLINTNEXTLINE
+#define DEBUG_FUNC() ALOGV("%s", __func__)
+
+ComposerClient::~ComposerClient() {
+ DEBUG_FUNC();
+
+ LOG(DEBUG) << "removed composer client";
+}
+
+// no need to check nullptr for output parameter, the aidl stub code won't pass
+// nullptr
+ndk::ScopedAStatus ComposerClient::createLayer(int64_t /*display*/,
+ int32_t /*bufferSlotCount*/,
+ int64_t* /*layer*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::createVirtualDisplay(
+ int32_t /*width*/, int32_t /*height*/, AidlPixelFormat /*formatHint*/,
+ int32_t /*outputBufferSlotCount*/, VirtualDisplay* /*display*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t /*display*/,
+ int64_t /*layer*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t /*display*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::executeCommands(
+ const std::vector<DisplayCommand>& /*commands*/,
+ std::vector<CommandResultPayload>* /*results*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t /*display*/,
+ int32_t* /*config*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getColorModes(
+ int64_t /*display*/, std::vector<ColorMode>* /*colorModes*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(
+ common::Dataspace /*dataspace*/, std::vector<float>* /*matrix*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayAttribute(
+ int64_t /*display*/, int32_t /*config*/, DisplayAttribute /*attribute*/,
+ int32_t* /*value*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(
+ int64_t /*display*/, std::vector<DisplayCapability>* /*caps*/) {
+ DEBUG_FUNC();
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayConfigs(
+ int64_t /*display*/, std::vector<int32_t>* /*configs*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(
+ int64_t /*display*/, DisplayConnectionType* /*type*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData(
+ int64_t /*display*/, DisplayIdentification* /*id*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t /*display*/,
+ std::string* /*name*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(
+ int64_t /*display*/, int32_t* /*vsyncPeriod*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(
+ int64_t /*display*/, int64_t /*maxFrames*/, int64_t /*timestamp*/,
+ DisplayContentSample* /*samples*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes(
+ int64_t /*display*/, DisplayContentSamplingAttributes* /*attrs*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(
+ int64_t /*display*/, common::Transform* /*orientation*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getHdrCapabilities(
+ int64_t /*display*/, HdrCapabilities* /*caps*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(
+ int32_t* /*count*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys(
+ int64_t /*display*/, std::vector<PerFrameMetadataKey>* /*keys*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes(
+ int64_t /*display*/, ReadbackBufferAttributes* /*attrs*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getReadbackBufferFence(
+ int64_t /*display*/, ndk::ScopedFileDescriptor* /*acquireFence*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getRenderIntents(
+ int64_t /*display*/, ColorMode /*mode*/,
+ std::vector<RenderIntent>* /*intents*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(
+ int64_t /*display*/, std::vector<ContentType>* /*types*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport(
+ int64_t /*display*/,
+ std::optional<common::DisplayDecorationSupport>* /*supportStruct*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::registerCallback(
+ const std::shared_ptr<IComposerCallback>& /*callback*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t /*display*/,
+ int32_t /*config*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints(
+ int64_t /*display*/, int32_t /*config*/,
+ const VsyncPeriodChangeConstraints& /*constraints*/,
+ VsyncPeriodChangeTimeline* /*timeline*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t /*display*/,
+ int32_t /*config*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(int64_t /*display*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(
+ int64_t /*display*/, int32_t* /*config*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t /*display*/,
+ bool /*on*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t /*display*/,
+ int32_t /*count*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setColorMode(int64_t /*display*/,
+ ColorMode /*mode*/,
+ RenderIntent /*intent*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setContentType(int64_t /*display*/,
+ ContentType /*type*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled(
+ int64_t /*display*/, bool /*enable*/,
+ FormatColorComponent /*componentMask*/, int64_t /*maxFrames*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t /*display*/,
+ PowerMode /*mode*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setReadbackBuffer(
+ int64_t /*display*/, const AidlNativeHandle& /*aidlBuffer*/,
+ const ndk::ScopedFileDescriptor& /*releaseFence*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t /*display*/,
+ bool /*enabled*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t /*display*/,
+ int32_t /*timeout*/) {
+ DEBUG_FUNC();
+ return ndk::ScopedAStatus::ok();
+}
+
+::ndk::SpAIBinder ComposerClient::createBinder() {
+ auto binder = BnComposerClient::createBinder();
+ AIBinder_setInheritRt(binder.get(), true);
+ return binder;
+}
+
+} // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/ComposerClient.h b/hwc3/ComposerClient.h
new file mode 100644
index 0000000..bdf4b0a
--- /dev/null
+++ b/hwc3/ComposerClient.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
+#include <aidl/android/hardware/graphics/composer3/BnComposerClient.h>
+#include <utils/Mutex.h>
+
+#include <memory>
+
+using AidlPixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
+using AidlNativeHandle = aidl::android::hardware::common::NativeHandle;
+
+namespace aidl::android::hardware::graphics::composer3::impl {
+
+class ComposerClient : public BnComposerClient {
+ public:
+ ComposerClient() = default;
+ ~ComposerClient() override;
+
+ // composer3 interface
+ ndk::ScopedAStatus createLayer(int64_t display, int32_t buffer_slot_count,
+ int64_t* layer) override;
+ ndk::ScopedAStatus createVirtualDisplay(int32_t width, int32_t height,
+ AidlPixelFormat format_hint,
+ int32_t output_buffer_slot_count,
+ VirtualDisplay* display) override;
+ ndk::ScopedAStatus destroyLayer(int64_t display, int64_t layer) override;
+ ndk::ScopedAStatus destroyVirtualDisplay(int64_t display) override;
+ ndk::ScopedAStatus executeCommands(
+ const std::vector<DisplayCommand>& commands,
+ std::vector<CommandResultPayload>* results) override;
+ ndk::ScopedAStatus getActiveConfig(int64_t display, int32_t* config) override;
+ ndk::ScopedAStatus getColorModes(
+ int64_t display, std::vector<ColorMode>* color_modes) override;
+ ndk::ScopedAStatus getDataspaceSaturationMatrix(
+ common::Dataspace dataspace, std::vector<float>* matrix) override;
+ ndk::ScopedAStatus getDisplayAttribute(int64_t display, int32_t config,
+ DisplayAttribute attribute,
+ int32_t* value) override;
+ ndk::ScopedAStatus getDisplayCapabilities(
+ int64_t display, std::vector<DisplayCapability>* caps) override;
+ ndk::ScopedAStatus getDisplayConfigs(int64_t display,
+ std::vector<int32_t>* configs) override;
+ ndk::ScopedAStatus getDisplayConnectionType(
+ int64_t display, DisplayConnectionType* type) override;
+ ndk::ScopedAStatus getDisplayIdentificationData(
+ int64_t display, DisplayIdentification* id) override;
+ ndk::ScopedAStatus getDisplayName(int64_t display,
+ std::string* name) override;
+ ndk::ScopedAStatus getDisplayVsyncPeriod(int64_t display,
+ int32_t* vsync_period) override;
+ ndk::ScopedAStatus getDisplayedContentSample(
+ int64_t display, int64_t max_frames, int64_t timestamp,
+ DisplayContentSample* samples) override;
+ ndk::ScopedAStatus getDisplayedContentSamplingAttributes(
+ int64_t display, DisplayContentSamplingAttributes* attrs) override;
+ ndk::ScopedAStatus getDisplayPhysicalOrientation(
+ int64_t display, common::Transform* orientation) override;
+ ndk::ScopedAStatus getHdrCapabilities(int64_t display,
+ HdrCapabilities* caps) override;
+ ndk::ScopedAStatus getMaxVirtualDisplayCount(int32_t* count) override;
+ ndk::ScopedAStatus getPerFrameMetadataKeys(
+ int64_t display, std::vector<PerFrameMetadataKey>* keys) override;
+ ndk::ScopedAStatus getReadbackBufferAttributes(
+ int64_t display, ReadbackBufferAttributes* attrs) override;
+ ndk::ScopedAStatus getReadbackBufferFence(
+ int64_t display, ndk::ScopedFileDescriptor* acquire_fence) override;
+ ndk::ScopedAStatus getRenderIntents(
+ int64_t display, ColorMode mode,
+ std::vector<RenderIntent>* intents) override;
+ ndk::ScopedAStatus getSupportedContentTypes(
+ int64_t display, std::vector<ContentType>* types) override;
+ ndk::ScopedAStatus getDisplayDecorationSupport(
+ int64_t display,
+ std::optional<common::DisplayDecorationSupport>* support) override;
+ ndk::ScopedAStatus registerCallback(
+ const std::shared_ptr<IComposerCallback>& callback) override;
+ ndk::ScopedAStatus setActiveConfig(int64_t display, int32_t config) override;
+ ndk::ScopedAStatus setActiveConfigWithConstraints(
+ int64_t display, int32_t config,
+ const VsyncPeriodChangeConstraints& constraints,
+ VsyncPeriodChangeTimeline* timeline) override;
+ ndk::ScopedAStatus setBootDisplayConfig(int64_t display,
+ int32_t config) override;
+ ndk::ScopedAStatus clearBootDisplayConfig(int64_t display) override;
+ ndk::ScopedAStatus getPreferredBootDisplayConfig(int64_t display,
+ int32_t* config) override;
+ ndk::ScopedAStatus setAutoLowLatencyMode(int64_t display, bool on) override;
+ ndk::ScopedAStatus setClientTargetSlotCount(int64_t display,
+ int32_t count) override;
+ ndk::ScopedAStatus setColorMode(int64_t display, ColorMode mode,
+ RenderIntent intent) override;
+ ndk::ScopedAStatus setContentType(int64_t display, ContentType type) override;
+ ndk::ScopedAStatus setDisplayedContentSamplingEnabled(
+ int64_t display, bool enable, FormatColorComponent component_mask,
+ int64_t max_frames) override;
+ ndk::ScopedAStatus setPowerMode(int64_t display, PowerMode mode) override;
+ ndk::ScopedAStatus setReadbackBuffer(
+ int64_t display, const AidlNativeHandle& buffer,
+ const ndk::ScopedFileDescriptor& release_fence) override;
+ ndk::ScopedAStatus setVsyncEnabled(int64_t display, bool enabled) override;
+ ndk::ScopedAStatus setIdleTimerEnabled(int64_t display,
+ int32_t timeout) override;
+
+ protected:
+ ::ndk::SpAIBinder createBinder() override;
+};
+
+} // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/hwc3-drm.rc b/hwc3/hwc3-drm.rc
new file mode 100644
index 0000000..a634b0b
--- /dev/null
+++ b/hwc3/hwc3-drm.rc
@@ -0,0 +1,7 @@
+service vendor.hwcomposer-3 /vendor/bin/hw/android.hardware.graphics.composer3-service
+ class hal animation
+ user system
+ group graphics drmrpc
+ capabilities SYS_NICE
+ onrestart restart surfaceflinger
+ task_profiles ServiceCapacityLow
diff --git a/hwc3/hwc3-drm.xml b/hwc3/hwc3-drm.xml
new file mode 100644
index 0000000..05a7c09
--- /dev/null
+++ b/hwc3/hwc3-drm.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.graphics.composer3</name>
+ <version>1</version>
+ <interface>
+ <name>IComposer</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/hwc3/meson.build b/hwc3/meson.build
new file mode 100644
index 0000000..f91ea3c
--- /dev/null
+++ b/hwc3/meson.build
@@ -0,0 +1,31 @@
+
+src_hwc3 = files(
+ 'ComposerClient.cpp',
+ 'Composer.cpp',
+ 'service.cpp',
+)
+
+executable(
+ 'android.hardware.composer.hwc3-service.drm',
+ src_hwc3,
+ cpp_args : common_cpp_flags,
+ dependencies : deps,
+ install : true,
+ link_with: drmhwc_common,
+ install_dir : get_option('bindir') / 'hw',
+ include_directories: inc_include,
+)
+
+configure_file(
+ input: 'hwc3-drm.rc',
+ output: '@PLAINNAME@',
+ copy: true,
+ install_dir: get_option('sysconfdir') / 'init',
+)
+
+configure_file(
+ input: 'hwc3-drm.xml',
+ output: '@PLAINNAME@',
+ copy: true,
+ install_dir: get_option('sysconfdir') / 'vintf' / 'manifest',
+)
diff --git a/hwc3/service.cpp b/hwc3/service.cpp
new file mode 100644
index 0000000..f7527b7
--- /dev/null
+++ b/hwc3/service.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2021-2022, 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 <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/ProcessState.h>
+#include <sched.h>
+
+#include "Composer.h"
+#include "utils/log.h"
+
+using aidl::android::hardware::graphics::composer3::impl::Composer;
+
+int main(int /*argc*/, char* argv[]) {
+ (void)argv;
+ ALOGI("hwc3-drm starting up");
+
+ // 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);
+ }
+
+ auto composer = ndk::SharedRefBase::make<Composer>();
+ if (!composer) {
+ ALOGE("Failed to create composer");
+ return -ENOMEM;
+ }
+
+ const std::string instance = std::string() + Composer::descriptor +
+ "/default";
+ ALOGI("HWC3 service name %s", instance.c_str());
+ auto status = AServiceManager_addServiceWithFlags(
+ composer->asBinder().get(), instance.c_str(),
+ AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED);
+ if (status != STATUS_OK) {
+ ALOGE("Failed to register service. Error %d", (int)status);
+ return -EINVAL;
+ }
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}