aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Macnak <natsu@google.com>2022-07-18 19:06:57 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-07-18 19:06:57 +0000
commit2a888e2a38a4ce8b9f1e2a44d2a9c69961ec2063 (patch)
tree95e9376469c8a050eab2d7a036d75e3e35deaa64
parented464d78f39f2d8c4068f2896baa9fa12f1acdd0 (diff)
parentc297cf92dbdb46260e89d9bccdb1e0b485e51c94 (diff)
downloadgoldfish-opengl-2a888e2a38a4ce8b9f1e2a44d2a9c69961ec2063.tar.gz
Merge "Add client composition mode to RanchuHWC"
-rw-r--r--system/hwc2/Android.mk1
-rw-r--r--system/hwc2/ClientComposer.cpp144
-rw-r--r--system/hwc2/ClientComposer.h73
-rw-r--r--system/hwc2/Common.cpp4
-rw-r--r--system/hwc2/Common.h1
-rw-r--r--system/hwc2/Device.cpp4
6 files changed, 227 insertions, 0 deletions
diff --git a/system/hwc2/Android.mk b/system/hwc2/Android.mk
index b53456ce..f2c4f25b 100644
--- a/system/hwc2/Android.mk
+++ b/system/hwc2/Android.mk
@@ -58,6 +58,7 @@ emulator_hwcomposer_c_includes += \
emulator_hwcomposer_relative_path := hw
emulator_hwcomposer2_src_files := \
+ ClientComposer.cpp \
Common.cpp \
Device.cpp \
Display.cpp \
diff --git a/system/hwc2/ClientComposer.cpp b/system/hwc2/ClientComposer.cpp
new file mode 100644
index 00000000..211667b0
--- /dev/null
+++ b/system/hwc2/ClientComposer.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ClientComposer.h"
+
+#include "Device.h"
+#include "Display.h"
+#include "Drm.h"
+#include "Layer.h"
+
+namespace android {
+
+ClientComposer::ClientComposer(DrmPresenter* drmPresenter)
+ : mDrmPresenter(drmPresenter) {}
+
+HWC2::Error ClientComposer::init() {
+ DEBUG_LOG("%s", __FUNCTION__);
+
+ return HWC2::Error::None;
+}
+
+HWC2::Error ClientComposer::onDisplayCreate(Display* display) {
+ const auto displayId = display->getId();
+ DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
+
+ // Ensure created.
+ mDisplayInfos.emplace(displayId, DisplayInfo{});
+
+ return HWC2::Error::None;
+}
+
+HWC2::Error ClientComposer::onDisplayDestroy(Display* display) {
+ const auto displayId = display->getId();
+ DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
+
+ auto it = mDisplayInfos.find(displayId);
+ if (it == mDisplayInfos.end()) {
+ ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__,
+ displayId);
+ return HWC2::Error::BadDisplay;
+ }
+
+ mDisplayInfos.erase(it);
+
+ return HWC2::Error::None;
+}
+
+HWC2::Error ClientComposer::onDisplayClientTargetSet(Display* display) {
+ const auto displayId = display->getId();
+ DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
+
+ auto it = mDisplayInfos.find(displayId);
+ if (it == mDisplayInfos.end()) {
+ ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__,
+ displayId);
+ return HWC2::Error::BadDisplay;
+ }
+
+ DisplayInfo& displayInfo = it->second;
+
+ auto clientTargetNativeBuffer = display->getClientTarget().getBuffer();
+ auto clientTargetDrmBuffer =
+ std::make_unique<DrmBuffer>(clientTargetNativeBuffer, mDrmPresenter);
+ if (!clientTargetDrmBuffer) {
+ ALOGE("%s: display:%" PRIu64 " failed to create client target drm buffer",
+ __FUNCTION__, displayId);
+ return HWC2::Error::NoResources;
+ }
+
+ displayInfo.clientTargetDrmBuffer = std::move(clientTargetDrmBuffer);
+
+ return HWC2::Error::None;
+}
+
+HWC2::Error ClientComposer::onActiveConfigChange(Display*) {
+ DEBUG_LOG("%s", __FUNCTION__);
+
+ return HWC2::Error::None;
+};
+
+HWC2::Error ClientComposer::validateDisplay(
+ Display* display, std::unordered_map<hwc2_layer_t, HWC2::Composition>* changes) {
+ const auto displayId = display->getId();
+ DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
+ (void)displayId;
+
+ const std::vector<Layer*>& layers = display->getOrderedLayers();
+
+ for (Layer* layer : layers) {
+ const auto layerId = layer->getId();
+ const auto layerCompositionType = layer->getCompositionType();
+
+ if (layerCompositionType != HWC2::Composition::Client) {
+ (*changes)[layerId] = HWC2::Composition::Client;
+ }
+ }
+
+ return HWC2::Error::None;
+}
+
+std::tuple<HWC2::Error, base::unique_fd> ClientComposer::presentDisplay(
+ Display* display) {
+ ATRACE_CALL();
+
+ const auto displayId = display->getId();
+ DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
+
+ auto displayInfoIt = mDisplayInfos.find(displayId);
+ if (displayInfoIt == mDisplayInfos.end()) {
+ ALOGE("%s: failed to find display buffers for display:%" PRIu64,
+ __FUNCTION__, displayId);
+ return std::make_tuple(HWC2::Error::BadDisplay, base::unique_fd());
+ }
+
+ DisplayInfo& displayInfo = displayInfoIt->second;
+
+ auto clientTargetFence = display->getClientTarget().getFence();
+
+ auto [error, presentFence] =
+ displayInfo.clientTargetDrmBuffer->flushToDisplay(
+ static_cast<int>(displayId), clientTargetFence);
+ if (error != HWC2::Error::None) {
+ ALOGE("%s: display:%" PRIu64 " failed to flush drm buffer" PRIu64,
+ __FUNCTION__, displayId);
+ return std::make_tuple(error, base::unique_fd());
+ }
+
+ return std::make_tuple(HWC2::Error::None, std::move(presentFence));
+}
+
+} // namespace android \ No newline at end of file
diff --git a/system/hwc2/ClientComposer.h b/system/hwc2/ClientComposer.h
new file mode 100644
index 00000000..58d4cceb
--- /dev/null
+++ b/system/hwc2/ClientComposer.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWC_CLIENTCOMPOSER_H
+#define ANDROID_HWC_CLIENTCOMPOSER_H
+
+#include <unordered_map>
+
+#include "Common.h"
+#include "Composer.h"
+#include "Display.h"
+#include "DrmPresenter.h"
+#include "Layer.h"
+
+namespace android {
+
+class ClientComposer : public Composer {
+ public:
+ ClientComposer(DrmPresenter* drmPresenter);
+
+ ClientComposer(const ClientComposer&) = delete;
+ ClientComposer& operator=(const ClientComposer&) = delete;
+
+ ClientComposer(ClientComposer&&) = delete;
+ ClientComposer& operator=(ClientComposer&&) = delete;
+
+ HWC2::Error init() override;
+
+ HWC2::Error onDisplayCreate(Display*) override;
+
+ HWC2::Error onDisplayDestroy(Display*) override;
+
+ HWC2::Error onDisplayClientTargetSet(Display*) override;
+
+ HWC2::Error onActiveConfigChange(Display*) override;
+
+ // Determines if this composer can compose the given layers on the given
+ // display and requests changes for layers that can't not be composed.
+ HWC2::Error validateDisplay(
+ Display* display, std::unordered_map<hwc2_layer_t, HWC2::Composition>*
+ outLayerCompositionChanges) override;
+
+ // Performs the actual composition of layers and presents the composed result
+ // to the display.
+ std::tuple<HWC2::Error, base::unique_fd> presentDisplay(
+ Display* display) override;
+
+ private:
+ struct DisplayInfo {
+ std::unique_ptr<DrmBuffer> clientTargetDrmBuffer;
+ };
+
+ std::unordered_map<int64_t, DisplayInfo> mDisplayInfos;
+
+ DrmPresenter* mDrmPresenter = nullptr;
+};
+
+} // namespace android
+
+#endif \ No newline at end of file
diff --git a/system/hwc2/Common.cpp b/system/hwc2/Common.cpp
index 3e465c22..021d0322 100644
--- a/system/hwc2/Common.cpp
+++ b/system/hwc2/Common.cpp
@@ -31,3 +31,7 @@ bool IsCuttlefishFoldable() {
bool IsNoOpMode() {
return android::base::GetProperty("ro.vendor.hwcomposer.mode", "") == "noop";
}
+
+bool IsClientCompositionMode() {
+ return android::base::GetProperty("ro.vendor.hwcomposer.mode", "") == "client";
+}
diff --git a/system/hwc2/Common.h b/system/hwc2/Common.h
index b0e07700..f13553b7 100644
--- a/system/hwc2/Common.h
+++ b/system/hwc2/Common.h
@@ -45,5 +45,6 @@
bool IsCuttlefish();
bool IsCuttlefishFoldable();
bool IsNoOpMode();
+bool IsClientCompositionMode();
#endif
diff --git a/system/hwc2/Device.cpp b/system/hwc2/Device.cpp
index 1be15b3d..f49905df 100644
--- a/system/hwc2/Device.cpp
+++ b/system/hwc2/Device.cpp
@@ -18,6 +18,7 @@
#include <android-base/properties.h>
+#include "ClientComposer.h"
#include "DisplayFinder.h"
#include "GuestComposer.h"
#include "HostComposer.h"
@@ -78,6 +79,9 @@ HWC2::Error Device::init() {
if (IsNoOpMode()) {
DEBUG_LOG("%s: using NoOpComposer", __FUNCTION__);
mComposer = std::make_unique<NoOpComposer>();
+ } else if (IsClientCompositionMode()) {
+ DEBUG_LOG("%s: using ClientComposer", __FUNCTION__);
+ mComposer = std::make_unique<ClientComposer>(mDrmPresenter.get());
} else if (ShouldUseGuestComposer()) {
DEBUG_LOG("%s: using GuestComposer", __FUNCTION__);
mComposer = std::make_unique<GuestComposer>(mDrmPresenter.get());