CXXARGS="-fPIC -Wall -Werror -DPLATFORM_SDK_VERSION=30 -D__ANDROID_API__=30 -Wsign-promo -Wimplicit-fallthrough"
CXXARGS+=" -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -Wno-gnu-include-next "
-CXXARGS+=" -fvisibility-inlines-hidden -std=gnu++17 -DHWC2_USE_CPP11 -DHWC2_INCLUDE_STRINGIFICATION -fexceptions -fno-rtti"
+CXXARGS+=" -fvisibility-inlines-hidden -std=gnu++17 -DHWC2_USE_CPP11 -DHWC2_INCLUDE_STRINGIFICATION -fno-rtti"
BUILD_FILES=(
backend/BackendClient.cpp
drm/DrmDevice.cpp
drm/DrmEncoder.cpp
drm/DrmEventListener.cpp
-drm/DrmGenericImporter.cpp
+drm/DrmFbImporter.cpp
drm/DrmMode.cpp
drm/DrmPlane.cpp
drm/DrmProperty.cpp
"drm/DrmDevice.cpp",
"drm/DrmEncoder.cpp",
"drm/DrmEventListener.cpp",
- "drm/DrmGenericImporter.cpp",
+ "drm/DrmFbImporter.cpp",
"drm/DrmMode.cpp",
"drm/DrmPlane.cpp",
"drm/DrmProperty.cpp",
HWC2::Error DrmHwcTwo::CreateDisplay(hwc2_display_t displ,
HWC2::DisplayType type) {
DrmDevice *drm = resource_manager_.GetDrmDevice(displ);
- std::shared_ptr<Importer> importer = resource_manager_.GetImporter(displ);
- if (!drm || !importer) {
- ALOGE("Failed to get a valid drmresource and importer");
+ if (!drm) {
+ ALOGE("Failed to get a valid drmresource");
return HWC2::Error::NoResources;
}
displays_.emplace(std::piecewise_construct, std::forward_as_tuple(displ),
- std::forward_as_tuple(&resource_manager_, drm, importer,
- displ, type));
+ std::forward_as_tuple(&resource_manager_, drm, displ,
+ type));
DrmCrtc *crtc = drm->GetCrtcForDisplay(static_cast<int>(displ));
if (!crtc) {
}
DrmHwcTwo::HwcDisplay::HwcDisplay(ResourceManager *resource_manager,
- DrmDevice *drm,
- std::shared_ptr<Importer> importer,
- hwc2_display_t handle, HWC2::DisplayType type)
+ DrmDevice *drm, hwc2_display_t handle,
+ HWC2::DisplayType type)
: resource_manager_(resource_manager),
drm_(drm),
- importer_(std::move(importer)),
handle_(handle),
type_(type),
color_transform_hint_(HAL_COLOR_TRANSFORM_IDENTITY) {
for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
DrmHwcLayer layer;
l.second->PopulateDrmLayer(&layer);
- int ret = layer.ImportBuffer(importer_.get());
+ int ret = layer.ImportBuffer(drm_);
if (ret) {
ALOGE("Failed to import layer, ret=%d", ret);
return HWC2::Error::NoResources;
#include "compositor/DrmDisplayCompositor.h"
#include "compositor/Planner.h"
-#include "drm/DrmGenericImporter.h"
#include "drm/ResourceManager.h"
#include "drm/VSyncWorker.h"
#include "drmhwcomposer.h"
class HwcDisplay {
public:
HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm,
- std::shared_ptr<Importer> importer, hwc2_display_t handle,
- HWC2::DisplayType type);
+ hwc2_display_t handle, HWC2::DisplayType type);
HwcDisplay(const HwcDisplay &) = delete;
HWC2::Error Init(std::vector<DrmPlane *> *planes);
return connector_;
}
- const std::shared_ptr<Importer> &importer() const {
- return importer_;
- }
-
ResourceManager *resource_manager() const {
return resource_manager_;
}
ResourceManager *resource_manager_;
DrmDevice *drm_;
DrmDisplayCompositor compositor_;
- std::shared_ptr<Importer> importer_;
std::unique_ptr<Planner> planner_;
std::vector<DrmPlane *> primary_planes_;
ALOGE("Expected a valid framebuffer for pset");
break;
}
- fb_id = layer.buffer->fb_id;
+ fb_id = layer.buffer.FbIdHandle->GetFbId();
fence_fd = layer.acquire_fence.get();
display_frame = layer.display_frame;
source_crop = layer.source_crop;
}
DrmDevice::DrmDevice() : event_listener_(this) {
+ self.reset(this);
+ mDrmFbImporter = std::make_unique<DrmFbImporter>(self);
}
DrmDevice::~DrmDevice() {
}
#endif
+ uint64_t cap_value = 0;
+ if (drmGetCap(fd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value)) {
+ ALOGW("drmGetCap failed. Fallback to no modifier support.");
+ cap_value = 0;
+ }
+ HasAddFb2ModifiersSupport_ = cap_value != 0;
+
drmSetMaster(fd());
if (!drmIsMaster(fd())) {
ALOGE("DRM/KMS master access required");
#include "DrmCrtc.h"
#include "DrmEncoder.h"
#include "DrmEventListener.h"
+#include "DrmFbImporter.h"
#include "DrmPlane.h"
namespace android {
+class DrmFbImporter;
+class DrmPlane;
+
class DrmDevice {
public:
DrmDevice();
event_listener_.RegisterHotplugHandler(handler);
}
+ bool HasAddFb2ModifiersSupport() const {
+ return HasAddFb2ModifiersSupport_;
+ }
+
+ DrmFbImporter &GetDrmFbImporter() {
+ return *mDrmFbImporter.get();
+ }
+
private:
int TryEncoderForDisplay(int display, DrmEncoder *enc);
int GetProperty(uint32_t obj_id, uint32_t obj_type, const char *prop_name,
std::pair<uint32_t, uint32_t> min_resolution_;
std::pair<uint32_t, uint32_t> max_resolution_;
std::map<int, int> displays_;
+
+ bool HasAddFb2ModifiersSupport_{};
+
+ std::shared_ptr<DrmDevice> self;
+
+ std::unique_ptr<DrmFbImporter> mDrmFbImporter;
};
} // namespace android
--- /dev/null
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
+#define LOG_TAG "hwc-platform-drm-generic"
+
+#include "DrmFbImporter.h"
+
+#include <gralloc_handle.h>
+#include <hardware/gralloc.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include <cinttypes>
+#include <system_error>
+
+#include "utils/log.h"
+#include "utils/properties.h"
+
+namespace android {
+
+auto DrmFbIdHandle::CreateInstance(hwc_drm_bo_t *bo, GemHandle first_gem_handle,
+ const std::shared_ptr<DrmDevice> &drm)
+ -> std::shared_ptr<DrmFbIdHandle> {
+ // NOLINTNEXTLINE(cppcoreguidelines-owning-memory): priv. constructor usage
+ std::shared_ptr<DrmFbIdHandle> local(new DrmFbIdHandle(drm));
+
+ local->gem_handles_[0] = first_gem_handle;
+ int32_t err = 0;
+
+ /* Framebuffer object creation require gem handle for every used plane */
+ for (int i = 1; i < local->gem_handles_.size(); i++) {
+ if (bo->prime_fds[i] > 0) {
+ if (bo->prime_fds[i] != bo->prime_fds[0]) {
+ err = drmPrimeFDToHandle(drm->fd(), bo->prime_fds[i],
+ &local->gem_handles_.at(i));
+ if (err != 0) {
+ ALOGE("failed to import prime fd %d errno=%d", bo->prime_fds[i],
+ errno);
+ }
+ } else {
+ local->gem_handles_.at(i) = local->gem_handles_[0];
+ }
+ }
+ }
+
+ bool has_modifiers = bo->modifiers[0] != DRM_FORMAT_MOD_NONE &&
+ bo->modifiers[0] != DRM_FORMAT_MOD_INVALID;
+
+ if (!drm->HasAddFb2ModifiersSupport() && has_modifiers) {
+ ALOGE("No ADDFB2 with modifier support. Can't import modifier %" PRIu64,
+ bo->modifiers[0]);
+ local.reset();
+ return local;
+ }
+
+ /* Create framebuffer object */
+ if (!has_modifiers) {
+ err = drmModeAddFB2(drm->fd(), bo->width, bo->height, bo->format,
+ &local->gem_handles_[0], &bo->pitches[0],
+ &bo->offsets[0], &local->fb_id_, 0);
+ } else {
+ err = drmModeAddFB2WithModifiers(drm->fd(), bo->width, bo->height,
+ bo->format, &local->gem_handles_[0],
+ &bo->pitches[0], &bo->offsets[0],
+ &bo->modifiers[0], &local->fb_id_,
+ DRM_MODE_FB_MODIFIERS);
+ }
+ if (err != 0) {
+ ALOGE("could not create drm fb %d", err);
+ local.reset();
+ }
+
+ return local;
+}
+
+DrmFbIdHandle::~DrmFbIdHandle() {
+ /* Destroy framebuffer object */
+ if (drmModeRmFB(drm_->fd(), fb_id_) != 0) {
+ ALOGE("Failed to rm fb");
+ }
+
+ /* Close GEM handles.
+ *
+ * WARNING: TODO(nobody):
+ * From Linux side libweston relies on libgbm to get KMS handle and never
+ * closes it (handle is closed by libgbm on buffer destruction)
+ * Probably we should offer similar approach to users (at least on user
+ * request via system properties)
+ */
+ struct drm_gem_close gem_close {};
+ for (unsigned int gem_handle : gem_handles_) {
+ if (gem_handle == 0) {
+ continue;
+ }
+ gem_close.handle = gem_handle;
+ int32_t err = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
+ if (err != 0) {
+ ALOGE("Failed to close gem handle %d, errno: %d", gem_handle, errno);
+ }
+ }
+}
+
+auto DrmFbImporter::GetOrCreateFbId(hwc_drm_bo_t *bo)
+ -> std::shared_ptr<DrmFbIdHandle> {
+ /* Lookup DrmFbIdHandle in cache first. First handle serves as a cache key. */
+ GemHandle first_handle = 0;
+ int32_t err = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[0], &first_handle);
+
+ if (err != 0) {
+ ALOGE("Failed to import prime fd %d ret=%d", bo->prime_fds[0], err);
+ return std::shared_ptr<DrmFbIdHandle>();
+ }
+
+ auto drm_fb_id_cached = drm_fb_id_handle_cache_.find(first_handle);
+
+ if (drm_fb_id_cached != drm_fb_id_handle_cache_.end()) {
+ if (auto drm_fb_id_handle_shared = drm_fb_id_cached->second.lock()) {
+ return drm_fb_id_handle_shared;
+ }
+ drm_fb_id_handle_cache_.erase(drm_fb_id_cached);
+ }
+
+ /* Cleanup cached empty weak pointers */
+ const int minimal_cleanup_size = 128;
+ if (drm_fb_id_handle_cache_.size() > minimal_cleanup_size) {
+ CleanupEmptyCacheElements();
+ }
+
+ /* No DrmFbIdHandle found in cache, create framebuffer object */
+ auto fb_id_handle = DrmFbIdHandle::CreateInstance(bo, first_handle, drm_);
+ if (fb_id_handle) {
+ drm_fb_id_handle_cache_[first_handle] = fb_id_handle;
+ }
+
+ return fb_id_handle;
+}
+
+} // namespace android
--- /dev/null
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DRM_DRMFBIMPORTER_H_
+#define DRM_DRMFBIMPORTER_H_
+
+#include <drm/drm_fourcc.h>
+#include <hardware/gralloc.h>
+
+#include <array>
+#include <map>
+
+#include "drm/DrmDevice.h"
+#include "drmhwcgralloc.h"
+
+#ifndef DRM_FORMAT_INVALID
+#define DRM_FORMAT_INVALID 0
+#endif
+
+using GemHandle = uint32_t;
+
+namespace android {
+
+class DrmFbIdHandle {
+ public:
+ static auto CreateInstance(hwc_drm_bo_t *bo, GemHandle first_gem_handle,
+ const std::shared_ptr<DrmDevice> &drm)
+ -> std::shared_ptr<DrmFbIdHandle>;
+
+ ~DrmFbIdHandle();
+ DrmFbIdHandle(DrmFbIdHandle &&) = delete;
+ DrmFbIdHandle(const DrmFbIdHandle &) = delete;
+ auto operator=(const DrmFbIdHandle &) = delete;
+ auto operator=(DrmFbIdHandle &&) = delete;
+
+ auto GetFbId [[nodiscard]] () const -> uint32_t {
+ return fb_id_;
+ }
+
+ private:
+ explicit DrmFbIdHandle(std::shared_ptr<DrmDevice> drm)
+ : drm_(std::move(drm)){};
+
+ const std::shared_ptr<DrmDevice> drm_;
+
+ uint32_t fb_id_{};
+ std::array<GemHandle, HWC_DRM_BO_MAX_PLANES> gem_handles_{};
+};
+
+class DrmFbImporter {
+ public:
+ explicit DrmFbImporter(std::shared_ptr<DrmDevice> drm)
+ : drm_(std::move(drm)){};
+ ~DrmFbImporter() = default;
+ DrmFbImporter(const DrmFbImporter &) = delete;
+ DrmFbImporter(DrmFbImporter &&) = delete;
+ auto operator=(const DrmFbImporter &) = delete;
+ auto operator=(DrmFbImporter &&) = delete;
+
+ auto GetOrCreateFbId(hwc_drm_bo_t *bo) -> std::shared_ptr<DrmFbIdHandle>;
+
+ private:
+ void CleanupEmptyCacheElements() {
+ for (auto it = drm_fb_id_handle_cache_.begin();
+ it != drm_fb_id_handle_cache_.end();) {
+ if (it->second.expired()) {
+ it = drm_fb_id_handle_cache_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ const std::shared_ptr<DrmDevice> drm_;
+
+ std::map<GemHandle, std::weak_ptr<DrmFbIdHandle>> drm_fb_id_handle_cache_;
+};
+
+} // namespace android
+
+#endif
+++ /dev/null
-/*
- * Copyright (C) 2020 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 "hwc-platform-drm-generic"
-
-#include "DrmGenericImporter.h"
-
-#include <gralloc_handle.h>
-#include <hardware/gralloc.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include <cinttypes>
-
-#include "utils/log.h"
-#include "utils/properties.h"
-
-namespace android {
-
-DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
- uint64_t cap_value = 0;
- if (drmGetCap(drm_->fd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value)) {
- ALOGE("drmGetCap failed. Fallback to no modifier support.");
- cap_value = 0;
- }
- has_modifier_support_ = cap_value != 0;
-}
-
-int DrmGenericImporter::ImportBuffer(hwc_drm_bo_t *bo) {
- int ret = 0;
-
- for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
- if (bo->prime_fds[i] > 0) {
- if (i == 0 || bo->prime_fds[i] != bo->prime_fds[0]) {
- ret = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[i],
- &bo->gem_handles[i]);
- if (ret) {
- ALOGE("failed to import prime fd %d ret=%d", bo->prime_fds[i], ret);
- return ret;
- }
- } else {
- bo->gem_handles[i] = bo->gem_handles[0];
- }
- }
- }
-
- bool has_modifiers = bo->modifiers[0] != DRM_FORMAT_MOD_NONE &&
- bo->modifiers[0] != DRM_FORMAT_MOD_INVALID;
-
- if (!has_modifier_support_ && has_modifiers) {
- ALOGE("No ADDFB2 with modifier support. Can't import modifier %" PRIu64,
- bo->modifiers[0]);
- return -EINVAL;
- }
-
- if (!has_modifiers)
- ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
- bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id,
- 0);
- else
- ret = drmModeAddFB2WithModifiers(drm_->fd(), bo->width, bo->height,
- bo->format, bo->gem_handles, bo->pitches,
- bo->offsets, bo->modifiers, &bo->fb_id,
- DRM_MODE_FB_MODIFIERS);
-
- if (ret) {
- ALOGE("could not create drm fb %d", ret);
- return ret;
- }
-
- for (unsigned int gem_handle : bo->gem_handles) {
- if (!gem_handle)
- continue;
-
- ImportHandle(gem_handle);
- }
-
- return ret;
-}
-
-int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
- if (bo->fb_id)
- if (drmModeRmFB(drm_->fd(), bo->fb_id))
- ALOGE("Failed to rm fb");
-
- for (unsigned int &gem_handle : bo->gem_handles) {
- if (!gem_handle)
- continue;
-
- if (ReleaseHandle(gem_handle))
- ALOGE("Failed to release gem handle %d", gem_handle);
- else
- gem_handle = 0;
- }
- return 0;
-}
-
-int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
- gem_refcount_[gem_handle]++;
-
- return 0;
-}
-
-int DrmGenericImporter::ReleaseHandle(uint32_t gem_handle) {
- if (--gem_refcount_[gem_handle])
- return 0;
-
- gem_refcount_.erase(gem_handle);
-
- return CloseHandle(gem_handle);
-}
-
-int DrmGenericImporter::CloseHandle(uint32_t gem_handle) {
- struct drm_gem_close gem_close {};
- gem_close.handle = gem_handle;
- int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
- if (ret)
- ALOGE("Failed to close gem handle %d %d", gem_handle, ret);
-
- return ret;
-}
-} // namespace android
+++ /dev/null
-/*
- * Copyright (C) 2020 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_PLATFORM_DRM_GENERIC_H_
-#define ANDROID_PLATFORM_DRM_GENERIC_H_
-
-#include <drm/drm_fourcc.h>
-#include <hardware/gralloc.h>
-
-#include <map>
-
-#include "drm/DrmDevice.h"
-#include "drmhwcgralloc.h"
-
-#ifndef DRM_FORMAT_INVALID
-#define DRM_FORMAT_INVALID 0
-#endif
-
-namespace android {
-
-class Importer {
- public:
- virtual ~Importer() = default;
-
- // Imports the buffer referred to by handle into bo.
- //
- // Note: This can be called from a different thread than ReleaseBuffer. The
- // implementation is responsible for ensuring thread safety.
- virtual int ImportBuffer(hwc_drm_bo_t *bo) = 0;
-
- // Releases the buffer object (ie: does the inverse of ImportBuffer)
- //
- // Note: This can be called from a different thread than ImportBuffer. The
- // implementation is responsible for ensuring thread safety.
- virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
-};
-
-class DrmGenericImporter : public Importer {
- public:
- DrmGenericImporter(DrmDevice *drm);
- ~DrmGenericImporter() override = default;
-
- int ImportBuffer(hwc_drm_bo_t *bo) override;
- int ReleaseBuffer(hwc_drm_bo_t *bo) override;
- int ImportHandle(uint32_t gem_handle);
- int ReleaseHandle(uint32_t gem_handle);
-
- protected:
- DrmDevice *drm_;
-
- private:
- int CloseHandle(uint32_t gem_handle);
- std::map<uint32_t, int> gem_refcount_;
- bool has_modifier_support_;
-};
-
-} // namespace android
-
-#endif
(const hw_module_t **)&gralloc_);
}
-int ResourceManager::AddDrmDevice(std::string const &path) {
- std::unique_ptr<DrmDevice> drm = std::make_unique<DrmDevice>();
+int ResourceManager::AddDrmDevice(const std::string &path) {
+ auto drm = std::make_unique<DrmDevice>();
int displays_added = 0;
int ret = 0;
std::tie(ret, displays_added) = drm->Init(path.c_str(), num_displays_);
- if (ret)
- return ret;
- std::shared_ptr<Importer> importer;
- importer = std::make_shared<DrmGenericImporter>(drm.get());
- if (!importer) {
- ALOGE("Failed to create importer instance");
- return -ENODEV;
- }
- importers_.push_back(importer);
drms_.push_back(std::move(drm));
num_displays_ += displays_added;
return ret;
return nullptr;
}
-std::shared_ptr<Importer> ResourceManager::GetImporter(int display) {
- for (unsigned int i = 0; i < drms_.size(); i++) {
- if (drms_[i]->HandlesDisplay(display))
- return importers_[i];
- }
- return nullptr;
-}
-
const gralloc_module_t *ResourceManager::gralloc() {
return gralloc_;
}
#include <string.h>
#include "DrmDevice.h"
-#include "DrmGenericImporter.h"
+#include "DrmFbImporter.h"
namespace android {
ResourceManager &operator=(const ResourceManager &) = delete;
int Init();
DrmDevice *GetDrmDevice(int display);
- std::shared_ptr<Importer> GetImporter(int display);
const gralloc_module_t *gralloc();
DrmConnector *AvailableWritebackConnector(int display);
const std::vector<std::unique_ptr<DrmDevice>> &getDrmDevices() const {
int num_displays_;
std::vector<std::unique_ptr<DrmDevice>> drms_;
- std::vector<std::shared_ptr<Importer>> importers_;
const gralloc_module_t *gralloc_;
bool scale_with_gpu_{};
uint32_t pitches[HWC_DRM_BO_MAX_PLANES];
uint32_t offsets[HWC_DRM_BO_MAX_PLANES];
uint32_t prime_fds[HWC_DRM_BO_MAX_PLANES];
- uint32_t gem_handles[HWC_DRM_BO_MAX_PLANES];
uint64_t modifiers[HWC_DRM_BO_MAX_PLANES];
- uint32_t fb_id;
int acquire_fence_fd;
- void *priv;
} hwc_drm_bo_t;
#endif // ANDROID_DRMHWCGRALLOC_H_
#ifndef ANDROID_DRM_HWCOMPOSER_H_
#define ANDROID_DRM_HWCOMPOSER_H_
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
#include <stdbool.h>
#include <stdint.h>
#include <vector>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
#include "autofd.h"
+#include "drm/DrmFbImporter.h"
#include "drmhwcgralloc.h"
+class DrmFbIdHandle;
struct hwc_import_context;
int hwc_import_init(struct hwc_import_context **ctx);
namespace android {
-class Importer;
-
class DrmHwcBuffer {
public:
DrmHwcBuffer() = default;
- DrmHwcBuffer(const hwc_drm_bo &bo, Importer *importer)
- : bo_(bo), importer_(importer) {
+ DrmHwcBuffer(const hwc_drm_bo &bo, DrmDevice *drmDevice)
+ : bo_(bo), mDrmDevice(drmDevice) {
}
- DrmHwcBuffer(DrmHwcBuffer &&rhs) : bo_(rhs.bo_), importer_(rhs.importer_) {
- rhs.importer_ = NULL;
+ DrmHwcBuffer(DrmHwcBuffer &&rhs) : bo_(rhs.bo_), mDrmDevice(rhs.mDrmDevice) {
+ rhs.mDrmDevice = nullptr;
+ FbIdHandle.swap(rhs.FbIdHandle);
}
~DrmHwcBuffer() {
- Clear();
}
DrmHwcBuffer &operator=(DrmHwcBuffer &&rhs) {
- Clear();
- importer_ = rhs.importer_;
- rhs.importer_ = NULL;
+ FbIdHandle.swap(rhs.FbIdHandle);
+ mDrmDevice = rhs.mDrmDevice;
+ rhs.mDrmDevice = nullptr;
bo_ = rhs.bo_;
return *this;
}
operator bool() const {
- return importer_ != NULL;
+ return mDrmDevice != NULL;
}
const hwc_drm_bo *operator->() const;
void Clear();
- int ImportBuffer(buffer_handle_t handle, Importer *importer);
+ std::shared_ptr<DrmFbIdHandle> FbIdHandle;
+
+ int ImportBuffer(buffer_handle_t handle, DrmDevice *drmDevice);
private:
hwc_drm_bo bo_;
- Importer *importer_ = NULL;
+ DrmDevice *mDrmDevice;
};
class DrmHwcNativeHandle {
UniqueFd acquire_fence;
OutputFd release_fence;
- int ImportBuffer(Importer *importer);
- int InitFromDrmHwcLayer(DrmHwcLayer *layer, Importer *importer);
+ int ImportBuffer(DrmDevice *drmDevice);
+ int InitFromDrmHwcLayer(DrmHwcLayer *layer, DrmDevice *drmDevice);
void SetTransform(int32_t sf_transform);
#include <ui/GraphicBufferMapper.h>
#include "bufferinfo/BufferInfoGetter.h"
-#include "drm/DrmGenericImporter.h"
+#include "drm/DrmFbImporter.h"
#include "drmhwcomposer.h"
#define UNUSED(x) (void)(x)
namespace android {
const hwc_drm_bo *DrmHwcBuffer::operator->() const {
- if (importer_ == nullptr) {
+ if (mDrmDevice == nullptr) {
ALOGE("Access of non-existent BO");
exit(1);
return nullptr;
}
void DrmHwcBuffer::Clear() {
- if (importer_ != nullptr) {
- importer_->ReleaseBuffer(&bo_);
- importer_ = nullptr;
- }
+ FbIdHandle.reset();
+ mDrmDevice = nullptr;
}
-int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) {
+int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, DrmDevice *drmDevice) {
hwc_drm_bo tmp_bo{};
int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(handle, &tmp_bo);
return ret;
}
- ret = importer->ImportBuffer(&tmp_bo);
- if (ret) {
- ALOGE("Failed to import buffer %d", ret);
- return ret;
- }
-
- if (importer_ != nullptr) {
- importer_->ReleaseBuffer(&bo_);
+ FbIdHandle = drmDevice->GetDrmFbImporter().GetOrCreateFbId(&tmp_bo);
+ if (!FbIdHandle) {
+ ALOGE("Failed to import buffer");
+ return -EINVAL;
}
- importer_ = importer;
-
+ mDrmDevice = drmDevice;
bo_ = tmp_bo;
return 0;
}
}
-int DrmHwcLayer::ImportBuffer(Importer *importer) {
- int ret = buffer.ImportBuffer(sf_handle, importer);
+int DrmHwcLayer::ImportBuffer(DrmDevice *drmDevice) {
+ int ret = buffer.ImportBuffer(sf_handle, drmDevice);
if (ret)
return ret;
}
int DrmHwcLayer::InitFromDrmHwcLayer(DrmHwcLayer *src_layer,
- Importer *importer) {
+ DrmDevice *drmDevice) {
blending = src_layer->blending;
sf_handle = src_layer->sf_handle;
acquire_fence = -1;
alpha = src_layer->alpha;
source_crop = src_layer->source_crop;
transform = src_layer->transform;
- return ImportBuffer(importer);
+ return ImportBuffer(drmDevice);
}
void DrmHwcLayer::SetTransform(int32_t sf_transform) {