diff --git a/hwc3/CommandResultWriter.h b/hwc3/CommandResultWriter.h
new file mode 100644
index 0000000..fa96f33
--- /dev/null
+++ b/hwc3/CommandResultWriter.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2024 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 <unordered_map>
+#include <vector>
+
+#include "Utils.h"
+#include "aidl/android/hardware/graphics/composer3/CommandError.h"
+#include "aidl/android/hardware/graphics/composer3/CommandResultPayload.h"
+#include "aidl/android/hardware/graphics/composer3/PresentFence.h"
+#include "aidl/android/hardware/graphics/composer3/PresentOrValidate.h"
+#include "aidl/android/hardware/graphics/composer3/ReleaseFences.h"
+
+namespace aidl::android::hardware::graphics::composer3 {
+
+struct DisplayChanges {
+  std::optional<ChangedCompositionTypes> composition_changes;
+  std::optional<DisplayRequest> display_request_changes;
+
+  void AddLayerCompositionChange(int64_t display_id, int64_t layer_id,
+                                 Composition layer_composition) {
+    if (!composition_changes) {
+      composition_changes.emplace();
+      composition_changes->display = display_id;
+    }
+
+    ChangedCompositionLayer composition_change;
+    composition_change.layer = layer_id;
+    composition_change.composition = layer_composition;
+    composition_changes->layers.emplace_back(composition_change);
+  }
+
+  void ClearLayerCompositionChanges() {
+    composition_changes.reset();
+  }
+
+  bool HasAnyChanges() const {
+    return composition_changes.has_value() ||
+           display_request_changes.has_value();
+  }
+
+  void Reset() {
+    composition_changes.reset();
+    display_request_changes.reset();
+  }
+};
+
+class CommandResultWriter {
+ public:
+  explicit CommandResultWriter(std::vector<CommandResultPayload>* results)
+      : results_(results) {
+  }
+
+  bool HasError() const {
+    return has_error_;
+  }
+
+  void IncrementCommand() {
+    index_++;
+    has_error_ = false;
+  }
+
+  void AddError(hwc3::Error error) {
+    CommandError command_error;
+    command_error.errorCode = static_cast<int32_t>(error);
+    command_error.commandIndex = static_cast<int32_t>(index_);
+
+    results_->emplace_back(command_error);
+    has_error_ = true;
+  }
+
+  void AddPresentFence(int64_t display_id, ::android::base::unique_fd fence) {
+    if (!fence.ok()) {
+      return;
+    }
+
+    PresentFence present_fence;
+    present_fence.fence = ::ndk::ScopedFileDescriptor(fence.release());
+    present_fence.display = display_id;
+    results_->emplace_back(std::move(present_fence));
+  }
+
+  void AddReleaseFence(
+      int64_t display_id,
+      std::unordered_map<int64_t, ::android::base::unique_fd>& layer_fences) {
+    ReleaseFences release_fences;
+    release_fences.display = display_id;
+    for (auto& [layer, fence] : layer_fences) {
+      if (!fence.ok()) {
+        continue;
+      }
+
+      ReleaseFences::Layer layer_result;
+      layer_result.layer = layer;
+      layer_result.fence = ::ndk::ScopedFileDescriptor(fence.release());
+
+      release_fences.layers.emplace_back(std::move(layer_result));
+    }
+
+    results_->emplace_back(std::move(release_fences));
+  }
+
+  void AddChanges(const DisplayChanges& changes) {
+    if (changes.composition_changes) {
+      results_->emplace_back(*changes.composition_changes);
+    }
+    if (changes.display_request_changes) {
+      results_->emplace_back(*changes.display_request_changes);
+    }
+  }
+
+  void AddPresentOrValidateResult(int64_t display_id,
+                                  const PresentOrValidate::Result& pov_result) {
+    PresentOrValidate pov_command;
+    pov_command.display = display_id;
+    pov_command.result = pov_result;
+
+    results_->emplace_back(pov_command);
+  }
+
+ private:
+  size_t index_{0};
+  bool has_error_{false};
+  std::vector<CommandResultPayload>* results_{nullptr};
+};
+};  // namespace aidl::android::hardware::graphics::composer3
\ No newline at end of file
diff --git a/hwc3/Composer.cpp b/hwc3/Composer.cpp
index 5f90797..2494488 100644
--- a/hwc3/Composer.cpp
+++ b/hwc3/Composer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "drmhwc"
 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
 
 #include "Composer.h"
@@ -21,38 +22,51 @@
 #include <android-base/logging.h>
 #include <android/binder_ibinder_platform.h>
 
+#include "hwc3/ComposerClient.h"
+#include "hwc3/Utils.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) {
+  if (!client || !client->Init()) {
     *out_client = nullptr;
-    return ndk::ScopedAStatus::fromServiceSpecificError(EX_NO_RESOURCES);
+    return ToBinderStatus(hwc3::Error::kNoResources);
   }
 
   *out_client = client;
+  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());
+  std::stringstream output;
+  output << "hwc3-drm\n\n";
+
+  auto client_instance = client_.lock();
+  if (!client_instance) {
+    return STATUS_OK;
+  }
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
+  auto* client = static_cast<ComposerClient*>(client_instance.get());
+  output << client->Dump();
+
+  auto output_str = output.str();
+  write(fd, output_str.c_str(), output_str.size());
   return STATUS_OK;
 }
 
-ndk::ScopedAStatus Composer::getCapabilities(
-    std::vector<Capability>* /*caps*/) {
+ndk::ScopedAStatus Composer::getCapabilities(std::vector<Capability>* caps) {
   DEBUG_FUNC();
+  /* No capabilities advertised */
+  caps->clear();
   return ndk::ScopedAStatus::ok();
 }
 
diff --git a/hwc3/Composer.h b/hwc3/Composer.h
index b29d0cf..f6c2536 100644
--- a/hwc3/Composer.h
+++ b/hwc3/Composer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -19,7 +19,7 @@
 #include <aidl/android/hardware/graphics/composer3/BnComposer.h>
 #include <utils/Mutex.h>
 
-#include "ComposerClient.h"
+#include <memory>
 
 namespace aidl::android::hardware::graphics::composer3::impl {
 
@@ -36,6 +36,9 @@
 
  protected:
   ::ndk::SpAIBinder createBinder() override;
+
+ private:
+  std::weak_ptr<IComposerClient> client_;
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index 9ebba31..6c03722 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -14,283 +14,910 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "drmhwc"
 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
 
 #include "ComposerClient.h"
 
+#include <aidlcommonsupport/NativeHandle.h>
 #include <android-base/logging.h>
 #include <android/binder_ibinder_platform.h>
+#include <hardware/hwcomposer2.h>
+
+#include <cinttypes>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "aidl/android/hardware/graphics/common/Transform.h"
+#include "aidl/android/hardware/graphics/composer3/ClientTarget.h"
+#include "aidl/android/hardware/graphics/composer3/Composition.h"
+#include "aidl/android/hardware/graphics/composer3/DisplayRequest.h"
+#include "aidl/android/hardware/graphics/composer3/IComposerClient.h"
+#include "aidl/android/hardware/graphics/composer3/PowerMode.h"
+#include "aidl/android/hardware/graphics/composer3/PresentOrValidate.h"
+#include "aidl/android/hardware/graphics/composer3/RenderIntent.h"
+#include "android/binder_auto_utils.h"
+#include "cutils/native_handle.h"
+#include "hardware/hwcomposer_defs.h"
+#include "hwc2_device/HwcDisplay.h"
+#include "hwc2_device/HwcLayer.h"
+#include "hwc3/DrmHwcThree.h"
+#include "hwc3/Utils.h"
+
+using ::android::HwcDisplay;
 
 #include "utils/log.h"
 
 namespace aidl::android::hardware::graphics::composer3::impl {
+namespace {
 
-// NOLINTNEXTLINE
-#define DEBUG_FUNC() ALOGV("%s", __func__)
+// clang-format off
+constexpr std::array<float, 16> kIdentityMatrix = {
+    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
 
+}  // namespace
+
+ComposerClient::ComposerClient() {
+  DEBUG_FUNC();
+}
+
+bool ComposerClient::Init() {
+  DEBUG_FUNC();
+  composer_resources_ = ComposerResources::Create();
+  if (composer_resources_) {
+    hwc_ = std::make_unique<DrmHwcThree>(composer_resources_.get());
+  }
+  return composer_resources_ != nullptr;
+}
+
+// NOLINTNEXTLINE(bugprone-exception-escape)
 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*/) {
+ndk::ScopedAStatus ComposerClient::createLayer(int64_t display_id,
+                                               int32_t buffer_slot_count,
+                                               int64_t* layer_id) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  hwc2_layer_t hwc2_layer_id = 0;
+  auto err = Hwc2toHwc3Error(display->CreateLayer(&hwc2_layer_id));
+  if (err != hwc3::Error::kNone) {
+    return ToBinderStatus(err);
+  }
+
+  const int64_t created_layer_id = Hwc2LayerToHwc3(hwc2_layer_id);
+  err = composer_resources_->AddLayer(display_id, created_layer_id,
+                                      buffer_slot_count);
+  if (err != hwc3::Error::kNone) {
+    destroyLayer(display_id, created_layer_id);
+    return ToBinderStatus(err);
+  }
+
+  *layer_id = created_layer_id;
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::createVirtualDisplay(
-    int32_t /*width*/, int32_t /*height*/, AidlPixelFormat /*formatHint*/,
-    int32_t /*outputBufferSlotCount*/, VirtualDisplay* /*display*/) {
+    int32_t width, int32_t height, AidlPixelFormat format_hint,
+    int32_t output_buffer_slot_count, VirtualDisplay* out_display) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+
+  hwc2_display_t hwc2_display_id = 0;
+  // TODO: Format is currently not used in drm_hwcomposer.
+  int32_t hwc2_format = 0;
+  auto err = Hwc2toHwc3Error(hwc_->CreateVirtualDisplay(width, height,
+                                                        &hwc2_format,
+                                                        &hwc2_display_id));
+  if (err != hwc3::Error::kNone) {
+    return ToBinderStatus(err);
+  }
+
+  const int64_t created_display_id = Hwc2DisplayToHwc3(hwc2_display_id);
+  err = composer_resources_->AddVirtualDisplay(hwc2_display_id,
+                                               output_buffer_slot_count);
+  if (err != hwc3::Error::kNone) {
+    hwc_->DestroyVirtualDisplay(hwc2_display_id);
+    return ToBinderStatus(err);
+  }
+
+  out_display->display = created_display_id;
+  out_display->format = format_hint;
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t /*display*/,
-                                                int64_t /*layer*/) {
+ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t display_id,
+                                                int64_t layer_id) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto err = Hwc2toHwc3Error(display->DestroyLayer(Hwc3LayerToHwc2(layer_id)));
+  if (err != hwc3::Error::kNone) {
+    return ToBinderStatus(err);
+  }
+
+  err = composer_resources_->RemoveLayer(display_id, layer_id);
+  return ToBinderStatus(err);
 }
 
-ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t /*display*/) {
+ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t display_id) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  auto err = Hwc2toHwc3Error(hwc_->DestroyVirtualDisplay(display_id));
+  return ToBinderStatus(err);
+}
+
+hwc3::Error ComposerClient::ValidateDisplayInternal(
+    HwcDisplay& display, std::vector<int64_t>* out_changed_layers,
+    std::vector<Composition>* out_composition_types,
+    int32_t* out_display_request_mask,
+    std::vector<int64_t>* out_requested_layers,
+    std::vector<int32_t>* out_request_masks,
+    ClientTargetProperty* /*out_client_target_property*/,
+    DimmingStage* /*out_dimming_stage*/) {
+  DEBUG_FUNC();
+
+  uint32_t num_types = 0;
+  uint32_t num_requests = 0;
+  const HWC2::Error hwc2_error = display.ValidateDisplay(&num_types,
+                                                         &num_requests);
+
+  /* Check if display has pending changes and no errors */
+  if (hwc2_error != HWC2::Error::None &&
+      hwc2_error != HWC2::Error::HasChanges) {
+    return Hwc2toHwc3Error(hwc2_error);
+  }
+
+  std::vector<hwc2_layer_t> hwc_changed_layers(num_types);
+  std::vector<int32_t> hwc_composition_types(num_types);
+  hwc3::Error error = Hwc2toHwc3Error(
+      display.GetChangedCompositionTypes(&num_types, hwc_changed_layers.data(),
+                                         hwc_composition_types.data()));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+
+  int32_t display_reqs = 0;
+  out_request_masks->resize(num_requests);
+  std::vector<hwc2_layer_t> hwc_requested_layers(num_requests);
+  error = Hwc2toHwc3Error(
+      display.GetDisplayRequests(&display_reqs, &num_requests,
+                                 hwc_requested_layers.data(),
+                                 out_request_masks->data()));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+
+  for (const auto& layer : hwc_changed_layers) {
+    out_changed_layers->emplace_back(Hwc2LayerToHwc3(layer));
+  }
+  for (const auto& type : hwc_composition_types) {
+    out_composition_types->emplace_back(Hwc2CompositionTypeToHwc3(type));
+  }
+  for (const auto& layer : hwc_requested_layers) {
+    out_requested_layers->emplace_back(Hwc2LayerToHwc3(layer));
+  }
+  *out_display_request_mask = display_reqs;
+
+  /* Client target property/dimming stage unsupported */
+  return hwc3::Error::kNone;
+}
+
+hwc3::Error ComposerClient::PresentDisplayInternal(
+    uint64_t display_id, ::android::base::unique_fd& out_display_fence,
+    std::unordered_map<int64_t, ::android::base::unique_fd>&
+        out_release_fences) {
+  DEBUG_FUNC();
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return hwc3::Error::kBadDisplay;
+  }
+
+  if (composer_resources_->MustValidateDisplay(display_id)) {
+    return hwc3::Error::kNotValidated;
+  }
+
+  int32_t present_fence = -1;
+  auto error = Hwc2toHwc3Error(display->PresentDisplay(&present_fence));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+  out_display_fence.reset(present_fence);
+
+  uint32_t release_fence_count = 0;
+  error = Hwc2toHwc3Error(
+      display->GetReleaseFences(&release_fence_count, nullptr, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+
+  std::vector<hwc2_layer_t> hwc_layers(release_fence_count);
+  std::vector<int32_t> hwc_fences(release_fence_count);
+  error = Hwc2toHwc3Error(display->GetReleaseFences(&release_fence_count,
+                                                    hwc_layers.data(),
+                                                    hwc_fences.data()));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+
+  for (size_t i = 0; i < hwc_layers.size(); i++) {
+    auto layer = Hwc2LayerToHwc3(hwc_layers[i]);
+    out_release_fences[layer] = ::android::base::unique_fd{hwc_fences[i]};
+  }
+
+  return hwc3::Error::kNone;
+}
+
+::android::HwcDisplay* ComposerClient::GetDisplay(uint64_t display_id) {
+  return hwc_->GetDisplay(display_id);
+}
+
+void ComposerClient::DispatchLayerCommand(int64_t display_id,
+                                          const LayerCommand& command) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  auto* layer = display->get_layer(command.layer);
+  if (layer == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadLayer);
+    return;
+  }
+
+  HwcLayerWrapper layer_wrapper{command.layer, layer};
+  if (command.buffer) {
+    ExecuteSetLayerBuffer(display_id, layer_wrapper, *command.buffer);
+  }
+  if (command.blendMode) {
+    ExecuteSetLayerBlendMode(display_id, layer_wrapper, *command.blendMode);
+  }
+  if (command.composition) {
+    ExecuteSetLayerComposition(display_id, layer_wrapper, *command.composition);
+  }
+  if (command.dataspace) {
+    ExecuteSetLayerDataspace(display_id, layer_wrapper, *command.dataspace);
+  }
+  if (command.displayFrame) {
+    ExecuteSetLayerDisplayFrame(display_id, layer_wrapper,
+                                *command.displayFrame);
+  }
+  if (command.planeAlpha) {
+    ExecuteSetLayerPlaneAlpha(display_id, layer_wrapper, *command.planeAlpha);
+  }
+  if (command.sourceCrop) {
+    ExecuteSetLayerSourceCrop(display_id, layer_wrapper, *command.sourceCrop);
+  }
+  if (command.transform) {
+    ExecuteSetLayerTransform(display_id, layer_wrapper, *command.transform);
+  }
+  if (command.z) {
+    ExecuteSetLayerZOrder(display_id, layer_wrapper, *command.z);
+  }
+  if (command.brightness) {
+    ExecuteSetLayerBrightness(display_id, layer_wrapper, *command.brightness);
+  }
+
+  // Some unsupported functionality returns kUnsupported, and others
+  // are just a no-op.
+  // TODO: Audit whether some of these should actually return kUnsupported
+  // instead.
+  if (command.sidebandStream) {
+    cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
+  }
+  // TODO: Blocking region handling missing.
+  // TODO: Layer surface damage.
+  // TODO: Layer visible region.
+  // TODO: Per-frame metadata.
+  // TODO: Layer color transform.
+  // TODO: Layer cursor position.
+  // TODO: Layer color.
+}
+
+void ComposerClient::ExecuteDisplayCommand(const DisplayCommand& command) {
+  const int64_t display_id = command.display;
+  if (hwc_->GetDisplay(display_id) == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  for (const auto& layer_cmd : command.layers) {
+    DispatchLayerCommand(command.display, layer_cmd);
+  }
+
+  if (command.brightness) {
+    ExecuteSetDisplayBrightness(command.display, *command.brightness);
+  }
+  if (command.colorTransformMatrix) {
+    ExecuteSetDisplayColorTransform(command.display,
+                                    *command.colorTransformMatrix);
+  }
+  if (command.clientTarget) {
+    ExecuteSetDisplayClientTarget(command.display, *command.clientTarget);
+  }
+  if (command.virtualDisplayOutputBuffer) {
+    ExecuteSetDisplayOutputBuffer(command.display,
+                                  *command.virtualDisplayOutputBuffer);
+  }
+  if (command.validateDisplay) {
+    ExecuteValidateDisplay(command.display, command.expectedPresentTime);
+  }
+  if (command.acceptDisplayChanges) {
+    ExecuteAcceptDisplayChanges(command.display);
+  }
+  if (command.presentDisplay) {
+    ExecutePresentDisplay(command.display);
+  }
+  if (command.presentOrValidateDisplay) {
+    ExecutePresentOrValidateDisplay(command.display,
+                                    command.expectedPresentTime);
+  }
 }
 
 ndk::ScopedAStatus ComposerClient::executeCommands(
-    const std::vector<DisplayCommand>& /*commands*/,
-    std::vector<CommandResultPayload>* /*results*/) {
-  DEBUG_FUNC();
+    const std::vector<DisplayCommand>& commands,
+    std::vector<CommandResultPayload>* results) {
+  cmd_result_writer_ = std::make_unique<CommandResultWriter>(results);
+  for (const auto& cmd : commands) {
+    ExecuteDisplayCommand(cmd);
+    cmd_result_writer_->IncrementCommand();
+  }
+  cmd_result_writer_.reset();
+
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t /*display*/,
-                                                   int32_t* /*config*/) {
+ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t display_id,
+                                                   int32_t* config) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t hwc2_config = 0;
+  const hwc3::Error error = Hwc2toHwc3Error(
+      display->GetActiveConfig(&hwc2_config));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+  *config = Hwc2ConfigIdToHwc3(hwc2_config);
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getColorModes(
-    int64_t /*display*/, std::vector<ColorMode>* /*colorModes*/) {
+    int64_t display_id, std::vector<ColorMode>* color_modes) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t num_modes = 0;
+  auto error = Hwc2toHwc3Error(display->GetColorModes(&num_modes, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<int32_t> hwc2_color_modes(num_modes);
+  error = Hwc2toHwc3Error(
+      display->GetColorModes(&num_modes, hwc2_color_modes.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  for (const auto& mode : hwc2_color_modes) {
+    color_modes->push_back(Hwc2ColorModeToHwc3(mode));
+  }
+
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(
-    common::Dataspace /*dataspace*/, std::vector<float>* /*matrix*/) {
+    common::Dataspace dataspace, std::vector<float>* matrix) {
   DEBUG_FUNC();
+  if (dataspace != common::Dataspace::SRGB_LINEAR) {
+    return ToBinderStatus(hwc3::Error::kBadParameter);
+  }
+
+  matrix->clear();
+  matrix->insert(matrix->begin(), kIdentityMatrix.begin(),
+                 kIdentityMatrix.end());
+
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayAttribute(
-    int64_t /*display*/, int32_t /*config*/, DisplayAttribute /*attribute*/,
-    int32_t* /*value*/) {
+    int64_t display_id, int32_t config, DisplayAttribute attribute,
+    int32_t* value) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  const hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayAttribute(Hwc3ConfigIdToHwc2(config),
+                                   Hwc3DisplayAttributeToHwc2(attribute),
+                                   value));
+  return ToBinderStatus(error);
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(
-    int64_t /*display*/, std::vector<DisplayCapability>* /*caps*/) {
+    int64_t display_id, std::vector<DisplayCapability>* caps) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
 
+  uint32_t num_capabilities = 0;
+  hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayCapabilities(&num_capabilities, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<uint32_t> out_caps(num_capabilities);
+  error = Hwc2toHwc3Error(
+      display->GetDisplayCapabilities(&num_capabilities, out_caps.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  caps->reserve(num_capabilities);
+  for (const auto cap : out_caps) {
+    caps->emplace_back(Hwc2DisplayCapabilityToHwc3(cap));
+  }
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayConfigs(
-    int64_t /*display*/, std::vector<int32_t>* /*configs*/) {
+    int64_t display_id, std::vector<int32_t>* configs) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t num_configs = 0;
+  hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayConfigs(&num_configs, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<hwc2_config_t> out_configs(num_configs);
+  error = Hwc2toHwc3Error(
+      display->GetDisplayConfigs(&num_configs, out_configs.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  configs->reserve(num_configs);
+  for (const auto config : out_configs) {
+    configs->emplace_back(Hwc2ConfigIdToHwc3(config));
+  }
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(
-    int64_t /*display*/, DisplayConnectionType* /*type*/) {
+    int64_t display_id, DisplayConnectionType* type) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t out_type = 0;
+  const hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayConnectionType(&out_type));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  *type = Hwc2DisplayConnectionTypeToHwc3(out_type);
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData(
-    int64_t /*display*/, DisplayIdentification* /*id*/) {
+    int64_t display_id, DisplayIdentification* id) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint8_t port = 0;
+  uint32_t data_size = 0;
+  hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayIdentificationData(&port, &data_size, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  id->data.resize(data_size);
+  error = Hwc2toHwc3Error(
+      display->GetDisplayIdentificationData(&port, &data_size,
+                                            id->data.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  id->port = static_cast<int8_t>(port);
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t /*display*/,
-                                                  std::string* /*name*/) {
+ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t display_id,
+                                                  std::string* name) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t size = 0;
+  auto error = Hwc2toHwc3Error(display->GetDisplayName(&size, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  name->resize(size);
+  error = Hwc2toHwc3Error(display->GetDisplayName(&size, name->data()));
+  return ToBinderStatus(error);
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(
-    int64_t /*display*/, int32_t* /*vsyncPeriod*/) {
+    int64_t display_id, int32_t* vsync_period) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t hwc2_vsync_period = 0;
+  auto error = Hwc2toHwc3Error(
+      display->GetDisplayVsyncPeriod(&hwc2_vsync_period));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  *vsync_period = static_cast<int32_t>(hwc2_vsync_period);
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(
-    int64_t /*display*/, int64_t /*maxFrames*/, int64_t /*timestamp*/,
+    int64_t /*display_id*/, int64_t /*max_frames*/, int64_t /*timestamp*/,
     DisplayContentSample* /*samples*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes(
-    int64_t /*display*/, DisplayContentSamplingAttributes* /*attrs*/) {
+    int64_t /*display_id*/, DisplayContentSamplingAttributes* /*attrs*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(
-    int64_t /*display*/, common::Transform* /*orientation*/) {
+    int64_t display_id, common::Transform* orientation) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  *orientation = common::Transform::NONE;
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::getHdrCapabilities(
-    int64_t /*display*/, HdrCapabilities* /*caps*/) {
+ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t display_id,
+                                                      HdrCapabilities* caps) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  /* No HDR capabilities */
+  caps->types.clear();
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(
-    int32_t* /*count*/) {
+ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* count) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  *count = static_cast<int32_t>(hwc_->GetMaxVirtualDisplayCount());
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys(
-    int64_t /*display*/, std::vector<PerFrameMetadataKey>* /*keys*/) {
+    int64_t /*display_id*/, std::vector<PerFrameMetadataKey>* /*keys*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes(
-    int64_t /*display*/, ReadbackBufferAttributes* /*attrs*/) {
+    int64_t /*display_id*/, ReadbackBufferAttributes* /*attrs*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getReadbackBufferFence(
-    int64_t /*display*/, ndk::ScopedFileDescriptor* /*acquireFence*/) {
+    int64_t /*display_id*/, ndk::ScopedFileDescriptor* /*acquireFence*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getRenderIntents(
-    int64_t /*display*/, ColorMode /*mode*/,
-    std::vector<RenderIntent>* /*intents*/) {
+    int64_t display_id, ColorMode mode, std::vector<RenderIntent>* intents) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  const int32_t hwc2_color_mode = Hwc3ColorModeToHwc2(mode);
+  uint32_t out_num_intents = 0;
+  auto error = Hwc2toHwc3Error(
+      display->GetRenderIntents(hwc2_color_mode, &out_num_intents, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<int32_t> out_intents(out_num_intents);
+  error = Hwc2toHwc3Error(display->GetRenderIntents(hwc2_color_mode,
+                                                    &out_num_intents,
+                                                    out_intents.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  intents->reserve(out_num_intents);
+  for (const auto intent : out_intents) {
+    intents->emplace_back(Hwc2RenderIntentToHwc3(intent));
+  }
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(
-    int64_t /*display*/, std::vector<ContentType>* /*types*/) {
+    int64_t display_id, std::vector<ContentType>* types) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t out_num_supported_types = 0;
+  auto error = Hwc2toHwc3Error(
+      display->GetSupportedContentTypes(&out_num_supported_types, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<uint32_t> out_supported_types(out_num_supported_types);
+  error = Hwc2toHwc3Error(
+      display->GetSupportedContentTypes(&out_num_supported_types,
+                                        out_supported_types.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  for (const auto type : out_supported_types) {
+    types->push_back(Hwc2ContentTypeToHwc3(type));
+  }
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport(
-    int64_t /*display*/,
-    std::optional<common::DisplayDecorationSupport>* /*supportStruct*/) {
+    int64_t /*display_id*/,
+    std::optional<common::DisplayDecorationSupport>* /*support_struct*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::registerCallback(
-    const std::shared_ptr<IComposerCallback>& /*callback*/) {
+    const std::shared_ptr<IComposerCallback>& callback) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  // This function is specified to be called exactly once.
+  hwc_->Init(callback);
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t /*display*/,
-                                                   int32_t /*config*/) {
+ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t display_id,
+                                                   int32_t config) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  return ToBinderStatus(Hwc2toHwc3Error(display->SetActiveConfig(config)));
 }
 
 ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints(
-    int64_t /*display*/, int32_t /*config*/,
-    const VsyncPeriodChangeConstraints& /*constraints*/,
-    VsyncPeriodChangeTimeline* /*timeline*/) {
+    int64_t display_id, int32_t config,
+    const VsyncPeriodChangeConstraints& constraints,
+    VsyncPeriodChangeTimeline* timeline) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  hwc_vsync_period_change_constraints_t hwc2_constraints;
+  hwc2_constraints.desiredTimeNanos = constraints.desiredTimeNanos;
+  hwc2_constraints.seamlessRequired = static_cast<uint8_t>(
+      constraints.seamlessRequired);
+
+  hwc_vsync_period_change_timeline_t hwc2_timeline{};
+  auto error = Hwc2toHwc3Error(
+      display->SetActiveConfigWithConstraints(config, &hwc2_constraints,
+                                              &hwc2_timeline));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  timeline->refreshTimeNanos = hwc2_timeline.refreshTimeNanos;
+  timeline->newVsyncAppliedTimeNanos = hwc2_timeline.newVsyncAppliedTimeNanos;
+  timeline->refreshRequired = static_cast<bool>(hwc2_timeline.refreshRequired);
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t /*display*/,
+ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t /*display_id*/,
                                                         int32_t /*config*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
-ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(int64_t /*display*/) {
+ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(
+    int64_t /*display_id*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(
-    int64_t /*display*/, int32_t* /*config*/) {
+    int64_t /*display_id*/, int32_t* /*config*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
-ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t /*display*/,
-                                                         bool /*on*/) {
+ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t display_id,
+                                                         bool on) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = Hwc2toHwc3Error(display->SetAutoLowLatencyMode(on));
+  return ToBinderStatus(error);
 }
 
-ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t /*display*/,
-                                                            int32_t /*count*/) {
+ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t display_id,
+                                                            int32_t count) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(
+      composer_resources_->SetDisplayClientTargetCacheSize(display_id, count));
 }
 
-ndk::ScopedAStatus ComposerClient::setColorMode(int64_t /*display*/,
-                                                ColorMode /*mode*/,
-                                                RenderIntent /*intent*/) {
+ndk::ScopedAStatus ComposerClient::setColorMode(int64_t display_id,
+                                                ColorMode mode,
+                                                RenderIntent intent) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = display->SetColorModeWithIntent(Hwc3ColorModeToHwc2(mode),
+                                               Hwc3RenderIntentToHwc2(intent));
+  return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
-ndk::ScopedAStatus ComposerClient::setContentType(int64_t /*display*/,
-                                                  ContentType /*type*/) {
+ndk::ScopedAStatus ComposerClient::setContentType(int64_t display_id,
+                                                  ContentType type) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = display->SetContentType(Hwc3ContentTypeToHwc2(type));
+  return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
 ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled(
-    int64_t /*display*/, bool /*enable*/,
+    int64_t /*display_id*/, bool /*enable*/,
     FormatColorComponent /*componentMask*/, int64_t /*maxFrames*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
-ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t /*display*/,
-                                                PowerMode /*mode*/) {
+ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t display_id,
+                                                PowerMode mode) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = display->SetPowerMode(Hwc3PowerModeToHwc2(mode));
+  return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
 ndk::ScopedAStatus ComposerClient::setReadbackBuffer(
-    int64_t /*display*/, const AidlNativeHandle& /*aidlBuffer*/,
+    int64_t /*display_id*/, const AidlNativeHandle& /*aidlBuffer*/,
     const ndk::ScopedFileDescriptor& /*releaseFence*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
-ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t /*display*/,
-                                                   bool /*enabled*/) {
+ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t display_id,
+                                                   bool enabled) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = display->SetVsyncEnabled(static_cast<int32_t>(enabled));
+  return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
-ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t /*display*/,
+ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t /*display_id*/,
                                                        int32_t /*timeout*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
+}
+
+std::string ComposerClient::Dump() {
+  uint32_t size = 0;
+  hwc_->Dump(&size, nullptr);
+
+  std::string buffer(size, '\0');
+  hwc_->Dump(&size, &buffer.front());
+  return buffer;
 }
 
 ::ndk::SpAIBinder ComposerClient::createBinder() {
@@ -299,4 +926,335 @@
   return binder;
 }
 
+void ComposerClient::ExecuteSetLayerBuffer(int64_t display_id,
+                                           HwcLayerWrapper& layer,
+                                           const Buffer& buffer) {
+  buffer_handle_t imported_buffer = nullptr;
+
+  auto releaser = composer_resources_->CreateResourceReleaser(true);
+  auto err = composer_resources_->GetLayerBuffer(display_id, layer.layer_id,
+                                                 buffer, &imported_buffer,
+                                                 releaser.get());
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+    return;
+  }
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
+  auto fence_fd = const_cast<ndk::ScopedFileDescriptor&>(buffer.fence)
+                      .release();
+  err = Hwc2toHwc3Error(layer.layer->SetLayerBuffer(imported_buffer, fence_fd));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerBlendMode(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const ParcelableBlendMode& blend_mode) {
+  auto err = Hwc2toHwc3Error(layer.layer->SetLayerBlendMode(
+      Hwc3BlendModeToHwc2(blend_mode.blendMode)));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerComposition(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const ParcelableComposition& composition) {
+  hwc3::Error error = hwc3::Error::kNone;
+  switch (composition.composition) {
+      // Unsupported composition types should set an error for the current
+      // DisplayCommand.
+    case Composition::DISPLAY_DECORATION:
+    case Composition::SIDEBAND:
+      error = hwc3::Error::kUnsupported;
+      break;
+    default:
+      error = Hwc2toHwc3Error(layer.layer->SetLayerCompositionType(
+          Hwc3CompositionToHwc2(composition.composition)));
+  }
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerDataspace(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const ParcelableDataspace& dataspace) {
+  auto err = Hwc2toHwc3Error(
+      layer.layer->SetLayerDataspace(Hwc3DataspaceToHwc2(dataspace.dataspace)));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerDisplayFrame(int64_t /*display_id*/,
+                                                 HwcLayerWrapper& layer,
+                                                 const common::Rect& rect) {
+  const hwc_rect_t hwc2_rect{rect.left, rect.top, rect.right, rect.bottom};
+  auto err = Hwc2toHwc3Error(layer.layer->SetLayerDisplayFrame(hwc2_rect));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+void ComposerClient::ExecuteSetLayerPlaneAlpha(int64_t /*display_id*/,
+                                               HwcLayerWrapper& layer,
+                                               const PlaneAlpha& plane_alpha) {
+  auto err = Hwc2toHwc3Error(
+      layer.layer->SetLayerPlaneAlpha(plane_alpha.alpha));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerSourceCrop(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const common::FRect& source_crop) {
+  const hwc_frect_t rect{source_crop.left, source_crop.top, source_crop.right,
+                         source_crop.bottom};
+  auto err = Hwc2toHwc3Error(layer.layer->SetLayerSourceCrop(rect));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+void ComposerClient::ExecuteSetLayerTransform(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const ParcelableTransform& transform) {
+  auto err = Hwc2toHwc3Error(
+      layer.layer->SetLayerTransform(Hwc3TransformToHwc2(transform.transform)));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+void ComposerClient::ExecuteSetLayerZOrder(int64_t /*display_id*/,
+                                           HwcLayerWrapper& layer,
+                                           const ZOrder& z_order) {
+  auto err = Hwc2toHwc3Error(layer.layer->SetLayerZOrder(z_order.z));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerBrightness(
+    int64_t /*display_id*/, HwcLayerWrapper& /*layer*/,
+    const LayerBrightness& brightness) {
+  if (std::signbit(brightness.brightness) ||
+      std::isnan(brightness.brightness)) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadParameter);
+  }
+}
+
+void ComposerClient::ExecuteSetDisplayBrightness(
+    uint64_t display_id, const DisplayBrightness& command) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  auto error = Hwc2toHwc3Error(
+      display->SetDisplayBrightness(command.brightness));
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+}
+void ComposerClient::ExecuteSetDisplayColorTransform(
+    uint64_t display_id, const std::vector<float>& matrix) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  auto almost_equal = [](auto a, auto b) {
+    const float epsilon = 0.001F;
+    return std::abs(a - b) < epsilon;
+  };
+  const bool is_identity = std::equal(matrix.begin(), matrix.end(),
+                                      kIdentityMatrix.begin(), almost_equal);
+
+  const int32_t hint = is_identity ? HAL_COLOR_TRANSFORM_IDENTITY
+                                   : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
+
+  auto error = Hwc2toHwc3Error(display->SetColorTransform(matrix.data(), hint));
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+}
+void ComposerClient::ExecuteSetDisplayClientTarget(
+    uint64_t display_id, const ClientTarget& command) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  hwc_region_t damage_regions;
+  damage_regions.numRects = command.damage.size();
+
+  std::vector<hwc_rect_t> regions(command.damage.size());
+  for (const auto& region : command.damage) {
+    regions.push_back({region.left, region.top, region.right, region.bottom});
+  }
+  damage_regions.rects = regions.data();
+
+  buffer_handle_t imported_buffer = nullptr;
+  auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
+
+  auto error = composer_resources_->GetDisplayClientTarget(display_id,
+                                                           command.buffer,
+                                                           &imported_buffer,
+                                                           buf_releaser.get());
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+    return;
+  }
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
+  auto fence = const_cast<::ndk::ScopedFileDescriptor&>(command.buffer.fence)
+                   .release();
+  error = Hwc2toHwc3Error(
+      display->SetClientTarget(imported_buffer, fence,
+                               Hwc3DataspaceToHwc2(command.dataspace),
+                               damage_regions));
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+}
+
+void ComposerClient::ExecuteSetDisplayOutputBuffer(uint64_t display_id,
+                                                   const Buffer& buffer) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  buffer_handle_t imported_buffer = nullptr;
+  auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
+
+  auto error = composer_resources_->GetDisplayOutputBuffer(display_id, buffer,
+                                                           &imported_buffer,
+                                                           buf_releaser.get());
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+    return;
+  }
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
+  auto fence = const_cast<::ndk::ScopedFileDescriptor&>(buffer.fence).release();
+  error = Hwc2toHwc3Error(display->SetOutputBuffer(imported_buffer, fence));
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+    return;
+  }
+}
+void ComposerClient::ExecuteValidateDisplay(
+    int64_t display_id,
+    std::optional<ClockMonotonicTimestamp> /*expected_present_time*/
+) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  /* TODO: Handle expectedPresentTime */
+
+  std::vector<int64_t> changed_layers;
+  std::vector<Composition> composition_types;
+  int32_t display_request_mask = 0;
+  std::vector<int64_t> requested_layers;
+  std::vector<int32_t> request_masks;
+
+  const hwc3::Error error = ValidateDisplayInternal(*display, &changed_layers,
+                                                    &composition_types,
+                                                    &display_request_mask,
+                                                    &requested_layers,
+                                                    &request_masks, nullptr,
+                                                    nullptr);
+
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+
+  // If a CommandError has been been set for the current DisplayCommand, then
+  // no other results should be returned besides the error.
+  if (cmd_result_writer_->HasError()) {
+    return;
+  }
+
+  DisplayChanges changes{};
+  for (size_t i = 0; i < composition_types.size(); i++) {
+    changes.AddLayerCompositionChange(display_id, changed_layers[i],
+                                      composition_types[i]);
+  }
+
+  std::vector<DisplayRequest::LayerRequest> layer_requests;
+  for (size_t i = 0; i < requested_layers.size(); i++) {
+    layer_requests.push_back({requested_layers[i], request_masks[i]});
+  }
+
+  const DisplayRequest request_changes{display_id, display_request_mask,
+                                       layer_requests};
+  changes.display_request_changes = request_changes;
+
+  cmd_result_writer_->AddChanges(changes);
+  composer_resources_->SetDisplayMustValidateState(display_id, false);
+}
+
+void ComposerClient::ExecuteAcceptDisplayChanges(int64_t display_id) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  auto error = Hwc2toHwc3Error(display->AcceptDisplayChanges());
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+    return;
+  }
+}
+
+void ComposerClient::ExecutePresentDisplay(int64_t display_id) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  ::android::base::unique_fd display_fence;
+  std::unordered_map<int64_t, ::android::base::unique_fd> release_fences;
+  auto error = PresentDisplayInternal(display_id, display_fence,
+                                      release_fences);
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+  if (cmd_result_writer_->HasError()) {
+    return;
+  }
+
+  cmd_result_writer_->AddPresentFence(display_id, std::move(display_fence));
+  cmd_result_writer_->AddReleaseFence(display_id, release_fences);
+}
+
+void ComposerClient::ExecutePresentOrValidateDisplay(
+    int64_t display_id,
+    std::optional<ClockMonotonicTimestamp> expected_present_time) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  /* TODO: Handle expectedPresentTime */
+  /* TODO: Add check if it's possible to skip display validation */
+  ExecuteValidateDisplay(display_id, expected_present_time);
+  cmd_result_writer_
+      ->AddPresentOrValidateResult(display_id,
+                                   PresentOrValidate::Result::Validated);
+}
+
 }  // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/ComposerClient.h b/hwc3/ComposerClient.h
index bdf4b0a..616f8aa 100644
--- a/hwc3/ComposerClient.h
+++ b/hwc3/ComposerClient.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -16,22 +16,42 @@
 
 #pragma once
 
-#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
-#include <aidl/android/hardware/graphics/composer3/BnComposerClient.h>
-#include <utils/Mutex.h>
-
 #include <memory>
 
+#include "aidl/android/hardware/graphics/composer3/BnComposerClient.h"
+#include "aidl/android/hardware/graphics/composer3/LayerCommand.h"
+#include "hwc3/CommandResultWriter.h"
+#include "hwc3/ComposerResources.h"
+#include "hwc3/Utils.h"
+#include "utils/Mutex.h"
+
 using AidlPixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
 using AidlNativeHandle = aidl::android::hardware::common::NativeHandle;
 
+namespace android {
+
+class HwcDisplay;
+class HwcLayer;
+
+}  // namespace android
+
 namespace aidl::android::hardware::graphics::composer3::impl {
 
+class DrmHwcThree;
+
+struct HwcLayerWrapper {
+  int64_t layer_id;
+  ::android::HwcLayer* layer;
+};
+
 class ComposerClient : public BnComposerClient {
  public:
-  ComposerClient() = default;
+  ComposerClient();
   ~ComposerClient() override;
 
+  bool Init();
+  std::string Dump();
+
   // composer3 interface
   ndk::ScopedAStatus createLayer(int64_t display, int32_t buffer_slot_count,
                                  int64_t* layer) override;
@@ -119,6 +139,71 @@
 
  protected:
   ::ndk::SpAIBinder createBinder() override;
+
+ private:
+  // Layer commands
+  void DispatchLayerCommand(int64_t display_id, const LayerCommand& command);
+  void ExecuteSetLayerBuffer(int64_t display_id, HwcLayerWrapper& layer_id,
+                             const Buffer& buffer);
+  void ExecuteSetLayerBlendMode(int64_t display_id, HwcLayerWrapper& layer,
+                                const ParcelableBlendMode& blend_mode);
+  void ExecuteSetLayerComposition(int64_t display_id, HwcLayerWrapper& layer,
+                                  const ParcelableComposition& composition);
+  void ExecuteSetLayerDataspace(int64_t display_id, HwcLayerWrapper& layer,
+                                const ParcelableDataspace& dataspace);
+  void ExecuteSetLayerDisplayFrame(int64_t display_id, HwcLayerWrapper& layer,
+                                   const common::Rect& rect);
+  void ExecuteSetLayerPlaneAlpha(int64_t display_id, HwcLayerWrapper& layer,
+                                 const PlaneAlpha& plane_alpha);
+  void ExecuteSetLayerSourceCrop(int64_t display_id, HwcLayerWrapper& layer,
+                                 const common::FRect& source_crop);
+  void ExecuteSetLayerTransform(int64_t display_id, HwcLayerWrapper& layer,
+                                const ParcelableTransform& transform);
+  void ExecuteSetLayerZOrder(int64_t display_id, HwcLayerWrapper& layer,
+                             const ZOrder& z_order);
+  void ExecuteSetLayerBrightness(int64_t display_id, HwcLayerWrapper& layer,
+                                 const LayerBrightness& brightness);
+
+  // Display commands
+  void ExecuteDisplayCommand(const DisplayCommand& command);
+  void ExecuteSetDisplayBrightness(uint64_t display_id,
+                                   const DisplayBrightness& command);
+  void ExecuteSetDisplayColorTransform(uint64_t display_id,
+                                       const std::vector<float>& matrix);
+  void ExecuteSetDisplayClientTarget(uint64_t display_id,
+                                     const ClientTarget& command);
+  void ExecuteSetDisplayOutputBuffer(uint64_t display_id, const Buffer& buffer);
+  void ExecuteValidateDisplay(
+      int64_t display_id,
+      std::optional<ClockMonotonicTimestamp> expected_present_time);
+  void ExecuteAcceptDisplayChanges(int64_t display_id);
+  void ExecutePresentDisplay(int64_t display_id);
+  void ExecutePresentOrValidateDisplay(
+      int64_t display_id,
+      std::optional<ClockMonotonicTimestamp> expected_present_time);
+
+  static hwc3::Error ValidateDisplayInternal(
+      ::android::HwcDisplay& display, std::vector<int64_t>* out_changed_layers,
+      std::vector<Composition>* out_composition_types,
+      int32_t* out_display_request_mask,
+      std::vector<int64_t>* out_requested_layers,
+      std::vector<int32_t>* out_request_masks,
+      ClientTargetProperty* out_client_target_property,
+      DimmingStage* out_dimming_stage);
+
+  hwc3::Error PresentDisplayInternal(
+      uint64_t display_id, ::android::base::unique_fd& out_display_fence,
+      std::unordered_map<int64_t, ::android::base::unique_fd>&
+          out_release_fences);
+
+  ::android::HwcDisplay* GetDisplay(uint64_t display_id);
+
+  std::unique_ptr<CommandResultWriter> cmd_result_writer_;
+
+  // Manages importing and caching gralloc buffers for displays and layers.
+  std::unique_ptr<ComposerResources> composer_resources_;
+
+  std::unique_ptr<DrmHwcThree> hwc_;
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/ComposerResources.cpp b/hwc3/ComposerResources.cpp
new file mode 100644
index 0000000..ae0edf4
--- /dev/null
+++ b/hwc3/ComposerResources.cpp
@@ -0,0 +1,202 @@
+
+/*
+ * Copyright (C) 2024 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 LOG_TAG "drmhwc"
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+
+#include "ComposerResources.h"
+
+#include <aidlcommonsupport/NativeHandle.h>
+
+#include "hardware/hwcomposer2.h"
+#include "hwc3/Utils.h"
+
+namespace aidl::android::hardware::graphics::composer3::impl {
+
+::android::hardware::graphics::composer::V2_1::Display ToHwc2Display(
+    uint64_t display_id) {
+  return static_cast<::android::hardware::graphics::composer::V2_1::Display>(
+      display_id);
+}
+
+::android::hardware::graphics::composer::V2_1::Layer ToHwc2Layer(
+    int64_t layer_id) {
+  return static_cast<::android::hardware::graphics::composer::V2_1::Layer>(
+      layer_id);
+}
+
+std::unique_ptr<ComposerResourceReleaser>
+ComposerResources::CreateResourceReleaser(bool is_buffer) {
+  return std::make_unique<ComposerResourceReleaser>(is_buffer);
+}
+
+std::unique_ptr<ComposerResources> ComposerResources::Create() {
+  auto instance = std::unique_ptr<ComposerResources>(new ComposerResources);
+  if (instance->resources_ == nullptr) {
+    ALOGE("%s: Failed to initialise ComposerResources", __func__);
+    return nullptr;
+  }
+
+  return instance;
+}
+
+hwc3::Error ComposerResources::GetLayerBuffer(
+    uint64_t display_id, int64_t layer_id, const Buffer& buffer,
+    buffer_handle_t* out_buffer_handle,
+    ComposerResourceReleaser* buf_releaser) {
+  auto display = ToHwc2Display(display_id);
+  auto layer = ToHwc2Layer(layer_id);
+
+  const bool use_cache = !buffer.handle.has_value();
+  buffer_handle_t buffer_handle = nullptr;
+  if (buffer.handle.has_value()) {
+    buffer_handle = ::android::makeFromAidl(*buffer.handle);
+  }
+
+  auto err = resources_->getLayerBuffer(display, layer, buffer.slot, use_cache,
+                                        buffer_handle, out_buffer_handle,
+                                        buf_releaser->GetReplacedHandle());
+
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::GetLayerSidebandStream(
+    uint64_t display_id, int64_t layer_id,
+    const aidl::android::hardware::common::NativeHandle& handle,
+    buffer_handle_t* out_handle, ComposerResourceReleaser* releaser) {
+  auto display = ToHwc2Display(display_id);
+  auto layer = ToHwc2Layer(layer_id);
+
+  auto err = resources_->getLayerSidebandStream(display, layer,
+                                                ::android::makeFromAidl(handle),
+                                                out_handle,
+                                                releaser->GetReplacedHandle());
+
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::AddLayer(uint64_t display_id, int64_t layer_id,
+                                        uint32_t buffer_cache_size) {
+  auto display = ToHwc2Display(display_id);
+  auto layer = ToHwc2Layer(layer_id);
+
+  auto err = resources_->addLayer(display, layer, buffer_cache_size);
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::RemoveLayer(uint64_t display_id,
+                                           int64_t layer_id) {
+  auto display = ToHwc2Display(display_id);
+  auto layer = ToHwc2Layer(layer_id);
+
+  auto err = resources_->removeLayer(display, layer);
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+bool ComposerResources::HasDisplay(uint64_t display_id) {
+  auto display = ToHwc2Display(display_id);
+  return resources_->hasDisplay(display);
+}
+
+hwc3::Error ComposerResources::AddPhysicalDisplay(uint64_t display_id) {
+  auto display = ToHwc2Display(display_id);
+  auto err = resources_->addPhysicalDisplay(display);
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::AddVirtualDisplay(
+    uint64_t display, uint32_t output_buffer_cache_size) {
+  auto err = resources_->addVirtualDisplay(display, output_buffer_cache_size);
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::RemoveDisplay(uint64_t display_id) {
+  auto display = ToHwc2Display(display_id);
+  auto err = resources_->removeDisplay(display);
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+void ComposerResources::SetDisplayMustValidateState(uint64_t display_id,
+                                                    bool must_validate) {
+  auto display = ToHwc2Display(display_id);
+  resources_->setDisplayMustValidateState(display, must_validate);
+}
+
+bool ComposerResources::MustValidateDisplay(uint64_t display_id) {
+  auto display = ToHwc2Display(display_id);
+  return resources_->mustValidateDisplay(display);
+}
+
+hwc3::Error ComposerResources::GetDisplayClientTarget(
+    uint64_t display_id, const Buffer& buffer, buffer_handle_t* out_handle,
+    ComposerResourceReleaser* releaser) {
+  auto display = ToHwc2Display(display_id);
+
+  const bool use_cache = !buffer.handle.has_value();
+  buffer_handle_t buffer_handle = nullptr;
+  if (buffer.handle.has_value()) {
+    buffer_handle = ::android::makeFromAidl(*buffer.handle);
+  }
+
+  auto err = resources_->getDisplayClientTarget(display, buffer.slot, use_cache,
+                                                buffer_handle, out_handle,
+                                                releaser->GetReplacedHandle());
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::SetDisplayClientTargetCacheSize(
+    uint64_t display_id, uint32_t client_target_cache_size) {
+  auto display = ToHwc2Display(display_id);
+  auto err = resources_
+                 ->setDisplayClientTargetCacheSize(display,
+                                                   client_target_cache_size);
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::GetDisplayClientTargetCacheSize(
+    uint64_t display_id, size_t* out_cache_size) {
+  auto display = ToHwc2Display(display_id);
+  auto err = resources_->getDisplayClientTargetCacheSize(display,
+                                                         out_cache_size);
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::GetDisplayOutputBufferCacheSize(
+    uint64_t display_id, size_t* out_cache_size) {
+  auto display = ToHwc2Display(display_id);
+  auto err = resources_->getDisplayOutputBufferCacheSize(display,
+                                                         out_cache_size);
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+
+hwc3::Error ComposerResources::GetDisplayOutputBuffer(
+    uint64_t display_id, const Buffer& buffer, buffer_handle_t* out_handle,
+    ComposerResourceReleaser* releaser) {
+  auto display = ToHwc2Display(display_id);
+  const bool use_cache = !buffer.handle.has_value();
+
+  buffer_handle_t buffer_handle = nullptr;
+  if (buffer.handle.has_value()) {
+    buffer_handle = ::android::makeFromAidl(*buffer.handle);
+  }
+
+  auto err = resources_->getDisplayOutputBuffer(display, buffer.slot, use_cache,
+                                                buffer_handle, out_handle,
+                                                releaser->GetReplacedHandle());
+  return Hwc2toHwc3Error(static_cast<HWC2::Error>(err));
+}
+}  // namespace aidl::android::hardware::graphics::composer3::impl
\ No newline at end of file
diff --git a/hwc3/ComposerResources.h b/hwc3/ComposerResources.h
new file mode 100644
index 0000000..6f4eee7
--- /dev/null
+++ b/hwc3/ComposerResources.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2024 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 <memory>
+
+#include "aidl/android/hardware/graphics/composer3/IComposerClient.h"
+#include "composer-resources/2.2/ComposerResources.h"
+#include "cutils/native_handle.h"
+#include "hwc3/Utils.h"
+
+namespace aidl::android::hardware::graphics::composer3::impl {
+
+class ComposerResourceReleaser {
+ public:
+  explicit ComposerResourceReleaser(bool is_buffer)
+      : replaced_handle_(is_buffer) {
+  }
+  virtual ~ComposerResourceReleaser() = default;
+
+  ::android::hardware::graphics::composer::V2_2::hal::ComposerResources::
+      ReplacedHandle*
+      GetReplacedHandle() {
+    return &replaced_handle_;
+  }
+
+ private:
+  ::android::hardware::graphics::composer::V2_2::hal::ComposerResources::
+      ReplacedHandle replaced_handle_;
+};
+
+class ComposerResources {
+ public:
+  static std::unique_ptr<ComposerResources> Create();
+  ~ComposerResources() = default;
+
+  hwc3::Error GetLayerBuffer(uint64_t display_id, int64_t layer_id,
+                             const Buffer& buffer,
+                             buffer_handle_t* out_buffer_handle,
+                             ComposerResourceReleaser* releaser);
+  hwc3::Error GetLayerSidebandStream(
+      uint64_t display_id, int64_t layer_id,
+      const aidl::android::hardware::common::NativeHandle& handle,
+      buffer_handle_t* out_handle, ComposerResourceReleaser* releaser);
+
+  hwc3::Error AddLayer(uint64_t display, int64_t layer,
+                       uint32_t buffer_cache_size);
+  hwc3::Error RemoveLayer(uint64_t display, int64_t layer);
+
+  bool HasDisplay(uint64_t display);
+  hwc3::Error AddPhysicalDisplay(uint64_t display);
+  hwc3::Error AddVirtualDisplay(uint64_t display,
+                                uint32_t output_buffer_cache_size);
+  hwc3::Error RemoveDisplay(uint64_t display);
+
+  void SetDisplayMustValidateState(uint64_t display_id, bool must_validate);
+  bool MustValidateDisplay(uint64_t display_id);
+
+  hwc3::Error GetDisplayClientTarget(uint64_t display_id, const Buffer& buffer,
+                                     buffer_handle_t* out_handle,
+                                     ComposerResourceReleaser* releaser);
+
+  hwc3::Error SetDisplayClientTargetCacheSize(
+      uint64_t display_id, uint32_t client_target_cache_size);
+  hwc3::Error GetDisplayClientTargetCacheSize(uint64_t display_id,
+                                              size_t* out_cache_size);
+  hwc3::Error GetDisplayOutputBufferCacheSize(uint64_t display,
+                                              size_t* out_cache_size);
+  hwc3::Error GetDisplayOutputBuffer(uint64_t display_id, const Buffer& buffer,
+                                     buffer_handle_t* out_handle,
+                                     ComposerResourceReleaser* releaser);
+
+  static std::unique_ptr<ComposerResourceReleaser> CreateResourceReleaser(
+      bool is_buffer);
+
+ private:
+  ComposerResources() = default;
+
+  std::unique_ptr<
+      ::android::hardware::graphics::composer::V2_2::hal::ComposerResources>
+      resources_ = ::android::hardware::graphics::composer::V2_2::hal::
+          ComposerResources::create();
+};
+
+}  // namespace aidl::android::hardware::graphics::composer3::impl
\ No newline at end of file
diff --git a/hwc3/DrmHwcThree.cpp b/hwc3/DrmHwcThree.cpp
index 62984b4..b39d834 100644
--- a/hwc3/DrmHwcThree.cpp
+++ b/hwc3/DrmHwcThree.cpp
@@ -18,8 +18,26 @@
 
 #include <cinttypes>
 
+#include "Utils.h"
+#include "aidl/android/hardware/graphics/common/Dataspace.h"
+
 namespace aidl::android::hardware::graphics::composer3::impl {
 
+using ::android::HwcDisplay;
+
+// NOLINTNEXTLINE(bugprone-exception-escape)
+DrmHwcThree::~DrmHwcThree() {
+  std::vector<uint64_t> display_ids;
+  display_ids.reserve(Displays().size());
+  for (auto& [display_id, display] : Displays()) {
+    display_ids.push_back(display_id);
+  }
+
+  for (auto display_id : display_ids) {
+    RemoveAndDestroyDisplay(display_id);
+  }
+}
+
 void DrmHwcThree::Init(std::shared_ptr<IComposerCallback> callback) {
   composer_callback_ = std::move(callback);
   GetResMan().Init();
@@ -38,6 +56,7 @@
 }
 
 void DrmHwcThree::SendRefreshEventToClient(uint64_t display_id) {
+  composer_resources_->SetDisplayMustValidateState(display_id, true);
   composer_callback_->onRefresh(static_cast<int64_t>(display_id));
 }
 
@@ -49,7 +68,83 @@
 
 void DrmHwcThree::SendHotplugEventToClient(hwc2_display_t display_id,
                                            bool connected) {
+  HandleDisplayHotplugEvent(static_cast<uint64_t>(display_id), connected);
   composer_callback_->onHotplug(static_cast<int64_t>(display_id), connected);
 }
 
+void DrmHwcThree::RemoveAndDestroyDisplay(uint64_t display_id) {
+  DEBUG_FUNC();
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return;
+  }
+
+  display->SetPowerMode(static_cast<int32_t>(HWC2::PowerMode::Off));
+  display->Deinit();
+
+  composer_resources_->RemoveDisplay(static_cast<int64_t>(display_id));
+  Displays().erase(display_id);
+}
+
+void DrmHwcThree::CleanDisplayResources(uint64_t display_id) {
+  DEBUG_FUNC();
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return;
+  }
+
+  display->SetPowerMode(static_cast<int32_t>(PowerMode::OFF));
+
+  size_t cache_size = 0;
+  auto err = composer_resources_->GetDisplayClientTargetCacheSize(display_id,
+                                                                  &cache_size);
+  if (err != hwc3::Error::kNone) {
+    ALOGE("%s: Could not clear target buffer cache for display: %" PRIu64,
+          __func__, display_id);
+    return;
+  }
+
+  for (size_t slot = 0; slot < cache_size; slot++) {
+    buffer_handle_t buffer_handle = nullptr;
+    auto buf_releaser = ComposerResources::CreateResourceReleaser(true);
+
+    Buffer buf{};
+    buf.slot = static_cast<int32_t>(slot);
+    err = composer_resources_->GetDisplayClientTarget(display_id, buf,
+                                                      &buffer_handle,
+                                                      buf_releaser.get());
+    if (err != hwc3::Error::kNone) {
+      continue;
+    }
+
+    err = Hwc2toHwc3Error(
+        display->SetClientTarget(buffer_handle, -1,
+                                 static_cast<int32_t>(
+                                     common::Dataspace::UNKNOWN),
+                                 {}));
+    if (err != hwc3::Error::kNone) {
+      ALOGE(
+          "%s: Could not clear slot %zu of the target buffer cache for "
+          "display %" PRIu64,
+          __func__, slot, display_id);
+    }
+  }
+}
+
+void DrmHwcThree::HandleDisplayHotplugEvent(uint64_t display_id,
+                                            bool connected) {
+  DEBUG_FUNC();
+  if (!connected) {
+    composer_resources_->RemoveDisplay(display_id);
+    return;
+  }
+
+  if (composer_resources_->HasDisplay(display_id)) {
+    /* Cleanup existing display resources */
+    CleanDisplayResources(display_id);
+    composer_resources_->RemoveDisplay(display_id);
+  }
+  composer_resources_->AddPhysicalDisplay(display_id);
+}
+
 }  // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/DrmHwcThree.h b/hwc3/DrmHwcThree.h
index c2d4119..90e5f32 100644
--- a/hwc3/DrmHwcThree.h
+++ b/hwc3/DrmHwcThree.h
@@ -19,13 +19,16 @@
 #include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
 
 #include "drm/DrmHwc.h"
+#include "hwc3/ComposerResources.h"
 
 namespace aidl::android::hardware::graphics::composer3::impl {
 
 class DrmHwcThree : public ::android::DrmHwc {
  public:
-  DrmHwcThree() = default;
-  ~DrmHwcThree() override = default;
+  explicit DrmHwcThree(ComposerResources* composer_resources)
+      : composer_resources_(composer_resources) {
+  }
+  ~DrmHwcThree() override;
 
   void Init(std::shared_ptr<IComposerCallback> callback);
 
@@ -39,6 +42,11 @@
                                 bool connected) override;
 
  private:
+  void RemoveAndDestroyDisplay(uint64_t display_id);
+  void CleanDisplayResources(uint64_t display_id);
+  void HandleDisplayHotplugEvent(uint64_t display_id, bool connected);
+
   std::shared_ptr<IComposerCallback> composer_callback_;
+  ComposerResources* composer_resources_;
 };
 }  // namespace aidl::android::hardware::graphics::composer3::impl
diff --git a/hwc3/Utils.cpp b/hwc3/Utils.cpp
new file mode 100644
index 0000000..adbd2fb
--- /dev/null
+++ b/hwc3/Utils.cpp
@@ -0,0 +1,58 @@
+
+/*
+ * Copyright (C) 2024 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 LOG_TAG "drmhwc"
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+
+#include "Utils.h"
+
+#include <hardware/hwcomposer2.h>
+
+#include "utils/log.h"
+
+namespace aidl::android::hardware::graphics::composer3 {
+
+hwc3::Error Hwc2toHwc3Error(HWC2::Error error) {
+  switch (error) {
+    case HWC2::Error::None:
+      return hwc3::Error::kNone;
+    case HWC2::Error::BadConfig:
+      return hwc3::Error::kBadConfig;
+    case HWC2::Error::BadDisplay:
+      return hwc3::Error::kBadDisplay;
+    case HWC2::Error::BadLayer:
+      return hwc3::Error::kBadLayer;
+    case HWC2::Error::BadParameter:
+      return hwc3::Error::kBadParameter;
+    case HWC2::Error::NoResources:
+      return hwc3::Error::kNoResources;
+    case HWC2::Error::NotValidated:
+      return hwc3::Error::kNotValidated;
+    case HWC2::Error::Unsupported:
+      return hwc3::Error::kUnsupported;
+    case HWC2::Error::SeamlessNotAllowed:
+      return hwc3::Error::kSeamlessNotAllowed;
+    case HWC2::Error::SeamlessNotPossible:
+      return hwc3::Error::kSeamlessNotPossible;
+    default:
+      ALOGE("Unknown HWC2 error. Could not translate to HWC3 error: %d",
+            static_cast<int32_t>(error));
+      return hwc3::Error::kUnsupported;
+  }
+}
+
+};  // namespace aidl::android::hardware::graphics::composer3
\ No newline at end of file
diff --git a/hwc3/Utils.h b/hwc3/Utils.h
new file mode 100644
index 0000000..23d6bdc
--- /dev/null
+++ b/hwc3/Utils.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2024 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/IComposerClient.h>
+#include <hardware/hwcomposer2.h>
+
+#include <cstdint>
+
+// NOLINTNEXTLINE
+#define DEBUG_FUNC() ALOGV("%s", __func__)
+
+namespace aidl::android::hardware::graphics::composer3 {
+
+namespace hwc3 {
+enum class Error : int32_t {
+  kNone = 0,
+  kBadConfig = IComposerClient::EX_BAD_CONFIG,
+  kBadDisplay = IComposerClient::EX_BAD_DISPLAY,
+  kBadLayer = IComposerClient::EX_BAD_LAYER,
+  kBadParameter = IComposerClient::EX_BAD_PARAMETER,
+  kNoResources = IComposerClient::EX_NO_RESOURCES,
+  kNotValidated = IComposerClient::EX_NOT_VALIDATED,
+  kUnsupported = IComposerClient::EX_UNSUPPORTED,
+  kSeamlessNotAllowed = IComposerClient::EX_SEAMLESS_NOT_ALLOWED,
+  kSeamlessNotPossible = IComposerClient::EX_SEAMLESS_NOT_POSSIBLE,
+};
+}  // namespace hwc3
+
+hwc3::Error Hwc2toHwc3Error(HWC2::Error error);
+
+inline ndk::ScopedAStatus ToBinderStatus(hwc3::Error error) {
+  if (error != hwc3::Error::kNone) {
+    return ndk::ScopedAStatus::fromServiceSpecificError(
+        static_cast<int32_t>(error));
+  }
+  return ndk::ScopedAStatus::ok();
+}
+
+inline ndk::ScopedAStatus ToBinderStatus(HWC2::Error error) {
+  return ToBinderStatus(Hwc2toHwc3Error(error));
+}
+
+// ID conversion. HWC2 uses typedef'd unsigned integer types while HWC3 uses
+// signed integer types. static_cast in between these.
+inline int64_t Hwc2LayerToHwc3(hwc2_layer_t layer) {
+  return static_cast<int64_t>(layer);
+}
+
+inline int64_t Hwc2DisplayToHwc3(hwc2_display_t display) {
+  return static_cast<int64_t>(display);
+}
+
+inline int32_t Hwc2ConfigIdToHwc3(hwc2_config_t config_id) {
+  return static_cast<int32_t>(config_id);
+}
+
+inline hwc2_layer_t Hwc3LayerToHwc2(int64_t layer) {
+  return static_cast<hwc2_layer_t>(layer);
+}
+
+inline hwc2_display_t Hwc3DisplayToHwc2(int64_t display) {
+  return static_cast<hwc2_display_t>(display);
+}
+
+inline hwc2_config_t Hwc3ConfigIdToHwc2(int32_t config_id) {
+  return static_cast<hwc2_config_t>(config_id);
+}
+
+// Values match up to HWC2_COMPOSITION_SIDEBAND, with HWC2 not supporting
+// newer values. static_cast in between shared values.
+// https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/libhardware/include_all/hardware/hwcomposer2.h;drc=d783cabd4d9bddb4b83f2dd38300b7598bb58b24;l=826
+inline Composition Hwc2CompositionTypeToHwc3(int32_t composition_type) {
+  if (composition_type < HWC2_COMPOSITION_INVALID ||
+      composition_type > HWC2_COMPOSITION_SIDEBAND) {
+    return Composition::INVALID;
+  }
+  return static_cast<Composition>(composition_type);
+}
+
+inline int32_t Hwc3CompositionToHwc2(Composition composition_type) {
+  if (composition_type > Composition::SIDEBAND) {
+    return HWC2_COMPOSITION_INVALID;
+  }
+  return static_cast<int32_t>(composition_type);
+}
+
+// Values for color modes match across HWC versions, so static cast is safe:
+// https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/graphics/composer/aidl/android/hardware/graphics/composer3/ColorMode.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:system/core/libsystem/include/system/graphics-base-v1.0.h;drc=7d940ae4afa450696afa25e07982f3a95e17e9b2;l=118
+// https://cs.android.com/android/platform/superproject/main/+/main:system/core/libsystem/include/system/graphics-base-v1.1.h;drc=7d940ae4afa450696afa25e07982f3a95e17e9b2;l=35
+inline ColorMode Hwc2ColorModeToHwc3(int32_t color_mode) {
+  return static_cast<ColorMode>(color_mode);
+}
+
+inline int32_t Hwc3ColorModeToHwc2(ColorMode color_mode) {
+  return static_cast<int32_t>(color_mode);
+}
+
+// Capabilities match up to DisplayCapability::AUTO_LOW_LATENCY_MODE, with hwc2
+// not defining capabilities beyond that.
+// https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl#28
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/libhardware/include_all/hardware/hwcomposer2.h;drc=1a0e4a1698c7b080d6763cef9e16592bce75967e;l=418
+inline DisplayCapability Hwc2DisplayCapabilityToHwc3(
+    uint32_t display_capability) {
+  if (display_capability > HWC2_DISPLAY_CAPABILITY_AUTO_LOW_LATENCY_MODE) {
+    return DisplayCapability::INVALID;
+  }
+  return static_cast<DisplayCapability>(display_capability);
+}
+
+// Values match between hwc versions, so static cast is safe.
+// https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConnectionType.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/libhardware/include_all/hardware/hwcomposer2.h;l=216;drc=d783cabd4d9bddb4b83f2dd38300b7598bb58b24;bpv=0;bpt=1
+inline DisplayConnectionType Hwc2DisplayConnectionTypeToHwc3(uint32_t type) {
+  if (type > HWC2_DISPLAY_CONNECTION_TYPE_EXTERNAL) {
+    // Arbitrarily return EXTERNAL in this case, which shouldn't happen.
+    // TODO: This will be cleaned up once hwc2<->hwc3 conversion is removed.
+    ALOGE("Unknown HWC2 connection type. Could not translate: %d", type);
+    return DisplayConnectionType::EXTERNAL;
+  }
+  return static_cast<DisplayConnectionType>(type);
+}
+
+// Values match, so static_cast is safe.
+// https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/graphics/composer/aidl/android/hardware/graphics/composer3/RenderIntent.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:system/core/libsystem/include/system/graphics-base-v1.1.h;drc=7d940ae4afa450696afa25e07982f3a95e17e9b2;l=37
+inline RenderIntent Hwc2RenderIntentToHwc3(int32_t intent) {
+  if (intent < HAL_RENDER_INTENT_COLORIMETRIC ||
+      intent > HAL_RENDER_INTENT_TONE_MAP_ENHANCE) {
+    ALOGE("Unknown HWC2 render intent. Could not translate: %d", intent);
+    return RenderIntent::COLORIMETRIC;
+  }
+  return static_cast<RenderIntent>(intent);
+}
+inline int32_t Hwc3RenderIntentToHwc2(RenderIntent render_intent) {
+  return static_cast<int32_t>(render_intent);
+}
+
+// Content type matches, so static_cast is safe.
+// https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/graphics/composer/aidl/android/hardware/graphics/composer3/ContentType.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/libhardware/include_all/hardware/hwcomposer2.h;l=350;drc=1a0e4a1698c7b080d6763cef9e16592bce75967e
+inline ContentType Hwc2ContentTypeToHwc3(uint32_t content_type) {
+  if (content_type > HWC2_CONTENT_TYPE_GAME) {
+    ALOGE("Unknown HWC2 content type. Could not translate: %d", content_type);
+    return ContentType::NONE;
+  }
+  return static_cast<ContentType>(content_type);
+}
+inline int32_t Hwc3ContentTypeToHwc2(ContentType content_type) {
+  return static_cast<int32_t>(content_type);
+}
+
+// Values match, so it's safe to do static_cast.
+// https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayAttribute.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/libhardware/include_all/hardware/hwcomposer2.h;l=58;drc=d783cabd4d9bddb4b83f2dd38300b7598bb58b24
+inline int32_t Hwc3DisplayAttributeToHwc2(DisplayAttribute display_attribute) {
+  return static_cast<int32_t>(display_attribute);
+}
+
+// Values match up to DOZE_SUSPEND.
+// https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/graphics/composer/aidl/android/hardware/graphics/composer3/PowerMode.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/libhardware/include_all/hardware/hwcomposer2.h;l=348;drc=d783cabd4d9bddb4b83f2dd38300b7598bb58b24
+inline int32_t Hwc3PowerModeToHwc2(PowerMode power_mode) {
+  if (power_mode > PowerMode::DOZE_SUSPEND) {
+    ALOGE("Unsupported HWC2 power mode. Could not translate: %d", power_mode);
+    return HWC2_POWER_MODE_ON;
+  }
+  return static_cast<int32_t>(power_mode);
+}
+
+// Values match, so static_cast is okay.
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/graphics/common/aidl/android/hardware/graphics/common/BlendMode.aidl;drc=bab1ba54ede32520a5042d616a3af46ad4f55d5f;l=25
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/libhardware/include_all/hardware/hwcomposer2.h;l=72;drc=1a0e4a1698c7b080d6763cef9e16592bce75967e
+inline int32_t Hwc3BlendModeToHwc2(common::BlendMode blend_mode) {
+  return static_cast<int32_t>(blend_mode);
+}
+
+// Values appear to match.
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:system/core/libsystem/include/system/graphics-base-v1.0.h;l=43
+// https://cs.android.com/android/platform/superproject/main/+/main:system/core/libsystem/include/system/graphics-base-v1.1.h;l=22;drc=7d940ae4afa450696afa25e07982f3a95e17e9b2
+inline int32_t Hwc3DataspaceToHwc2(common::Dataspace dataspace) {
+  return static_cast<int32_t>(dataspace);
+}
+
+// Values match, so static_cast is okay.
+// https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/graphics/common/aidl/android/hardware/graphics/common/Transform.aidl
+// https://cs.android.com/android/platform/superproject/main/+/main:system/core/libsystem/include/system/graphics-base-v1.0.h;l=41
+inline int32_t Hwc3TransformToHwc2(common::Transform transform) {
+  return static_cast<int32_t>(transform);
+}
+
+};  // namespace aidl::android::hardware::graphics::composer3
\ No newline at end of file
diff --git a/hwc3/hwc3-drm.rc b/hwc3/hwc3-drm.rc
index ef22730..425dd24 100644
--- a/hwc3/hwc3-drm.rc
+++ b/hwc3/hwc3-drm.rc
@@ -1,5 +1,6 @@
 service vendor.hwcomposer-3 /vendor/bin/hw/android.hardware.composer.hwc3-service.drm
     class hal animation
+    interface aidl android.hardware.graphics.composer3.IComposer/default
     user system
     group graphics drmrpc
     capabilities SYS_NICE
diff --git a/hwc3/meson.build b/hwc3/meson.build
index b1eb9c3..2486212 100644
--- a/hwc3/meson.build
+++ b/hwc3/meson.build
@@ -4,15 +4,17 @@
     'Composer.cpp',
     'DrmHwcThree.cpp',
     'service.cpp',
+    'ComposerResources.cpp',
+    'Utils.cpp',
 )
 
 executable(
     'android.hardware.composer.hwc3-service.drm',
     src_hwc3,
-    cpp_args : common_cpp_flags,
+    cpp_args : common_cpp_flags + hwc2_cpp_flags,
     dependencies : deps,
     install : true,
-    link_with: drmhwc_common,
+    link_with: [drmhwc_common, drmhwc_hwc2_common],
     install_dir : get_option('bindir') / 'hw',
     include_directories: inc_include,
 )
diff --git a/hwc3/service.cpp b/hwc3/service.cpp
index f7527b7..920260a 100644
--- a/hwc3/service.cpp
+++ b/hwc3/service.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021-2022, The Android Open Source Project
+ * Copyright 2024, 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.
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "drmhwc"
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
+
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <binder/ProcessState.h>
