diff options
author | Jason Macnak <natsu@google.com> | 2022-07-18 19:06:57 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-07-18 19:06:57 +0000 |
commit | 2a888e2a38a4ce8b9f1e2a44d2a9c69961ec2063 (patch) | |
tree | 95e9376469c8a050eab2d7a036d75e3e35deaa64 | |
parent | ed464d78f39f2d8c4068f2896baa9fa12f1acdd0 (diff) | |
parent | c297cf92dbdb46260e89d9bccdb1e0b485e51c94 (diff) | |
download | goldfish-opengl-2a888e2a38a4ce8b9f1e2a44d2a9c69961ec2063.tar.gz |
Merge "Add client composition mode to RanchuHWC"
-rw-r--r-- | system/hwc2/Android.mk | 1 | ||||
-rw-r--r-- | system/hwc2/ClientComposer.cpp | 144 | ||||
-rw-r--r-- | system/hwc2/ClientComposer.h | 73 | ||||
-rw-r--r-- | system/hwc2/Common.cpp | 4 | ||||
-rw-r--r-- | system/hwc2/Common.h | 1 | ||||
-rw-r--r-- | system/hwc2/Device.cpp | 4 |
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()); |