LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_VENDOR_MODULE := true
LOCAL_INIT_RC := android.hardware.graphics.composer@2.1-service.drmfb.rc
+
LOCAL_CPP_STD := c++17
LOCAL_SRC_FILES := \
DrmComposer.cpp \
DrmDevice.cpp \
DrmDisplay.cpp \
- DrmFramebuffer.cpp
+ DrmFramebuffer.cpp \
+ DrmFramebufferLibDrm.cpp
LOCAL_HEADER_LIBRARIES := \
android.hardware.graphics.composer@2.1-hal
android.hardware.graphics.mapper@2.0 \
android.hardware.graphics.composer@2.1
+ifeq ($(strip $(BOARD_USES_MINIGBM)), true)
+LOCAL_CFLAGS += -DUSE_MINIGBM
+LOCAL_SRC_FILES += DrmFramebufferMinigbm.cpp
+LOCAL_C_INCLUDES += external/minigbm/cros_gralloc
+LOCAL_SHARED_LIBRARIES += libnativewindow # TODO: Remove
+endif
+
include $(BUILD_EXECUTABLE)
#define LOG_TAG "drmfb-framebuffer"
#include <android-base/logging.h>
-#include <drm/drm_fourcc.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-#include <system/graphics.h>
-#include <android/gralloc_handle.h>
-#include "DrmFramebuffer.h"
#include "DrmDevice.h"
+#include "DrmFramebuffer.h"
+#include "DrmFramebufferImporter.h"
namespace android {
namespace hardware {
namespace drmfb {
namespace {
-static uint32_t convertAndroidToDrmFbFormat(uint32_t format) {
- switch (format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- /* Avoid using alpha bits for the framebuffer.
- * They are not supported on older Intel GPUs for primary planes. */
- case HAL_PIXEL_FORMAT_RGBX_8888:
- return DRM_FORMAT_XBGR8888;
- case HAL_PIXEL_FORMAT_RGB_888:
- return DRM_FORMAT_BGR888;
- case HAL_PIXEL_FORMAT_RGB_565:
- return DRM_FORMAT_BGR565;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return DRM_FORMAT_ARGB8888;
- default:
- LOG(ERROR) << "Unsupported framebuffer format: " << format;
- return 0;
- }
-}
-
+// TODO: Add a proper importer interface
uint32_t addFramebuffer(int fd, buffer_handle_t buffer) {
- auto handle = gralloc_handle(buffer);
- if (!handle) {
- LOG(ERROR) << "Failed to add framebuffer for buffer " << buffer
- << ": Not a libdrm gralloc handle";
- return 0;
- }
-
- // Lookup the handle for the prime fd
- uint32_t id;
- if (drmPrimeFDToHandle(fd, handle->prime_fd, &id)) {
- PLOG(ERROR) << "Failed to add framebuffer for buffer " << buffer
- << ": Failed to get handle for prime fd " << handle->prime_fd;
- return 0;
- }
-
- // Add a new framebuffer
- uint32_t pitches[4] = { handle->stride, 0, 0, 0 };
- uint32_t offsets[4] = { 0, 0, 0, 0 };
- uint32_t handles[4] = { id, 0, 0, 0 };
-
- if (drmModeAddFB2(fd, handle->width, handle->height,
- convertAndroidToDrmFbFormat(handle->format),
- handles, pitches, offsets, &id, 0)) {
- PLOG(ERROR) << "drmModeAddFB2 failed for buffer " << buffer;
- return 0;
- }
-
- return id;
+ uint32_t id = 0;
+ if (libdrm::addFramebuffer(fd, buffer, &id))
+ return id;
+ if (minigbm::addFramebuffer(fd, buffer, &id))
+ return id;
+
+ LOG(ERROR) << "No importer available for buffer with "
+ << buffer->numFds << " FDs and " << buffer->numInts << " ints";
+ return 0;
}
}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (C) 2019 Stephan Gerhold
+
+#pragma once
+
+#include <cstdint>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace drmfb {
+
+namespace libdrm {
+ bool addFramebuffer(int fd, buffer_handle_t buffer, uint32_t* id);
+}
+
+namespace minigbm {
+#ifdef USE_MINIGBM
+ bool addFramebuffer(int fd, buffer_handle_t buffer, uint32_t* id);
+#else
+ constexpr bool addFramebuffer(int, buffer_handle_t, uint32_t*) {
+ return false;
+ }
+#endif
+}
+
+} // namespace drmfb
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (C) 2019 Stephan Gerhold
+
+#define LOG_TAG "drmfb-framebuffer-libdrm"
+
+#include <android-base/logging.h>
+#include <drm/drm_fourcc.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <system/graphics.h>
+
+#include <android/gralloc_handle.h>
+#include "DrmFramebufferImporter.h"
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace drmfb {
+namespace libdrm {
+
+namespace {
+static uint32_t convertAndroidToDrmFbFormat(uint32_t format) {
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ /* Avoid using alpha bits for the framebuffer.
+ * They are not supported on older Intel GPUs for primary planes. */
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ return DRM_FORMAT_XBGR8888;
+ case HAL_PIXEL_FORMAT_RGB_888:
+ return DRM_FORMAT_BGR888;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return DRM_FORMAT_BGR565;
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ return DRM_FORMAT_ARGB8888;
+ default:
+ LOG(ERROR) << "Unsupported framebuffer format: " << format;
+ return 0;
+ }
+}
+
+void addFramebuffer(int fd, struct gralloc_handle_t* handle, uint32_t* id) {
+ uint32_t handles[4] = {};
+ uint32_t pitches[4] = {handle->stride};
+ uint32_t offsets[4] = {};
+
+ if (drmPrimeFDToHandle(fd, handle->prime_fd, &handles[0])) {
+ PLOG(ERROR) << "Failed to get handle for prime fd " << handle->prime_fd;
+ return;
+ }
+
+ if (drmModeAddFB2(fd, handle->width, handle->height,
+ convertAndroidToDrmFbFormat(handle->format),
+ handles, pitches, offsets, id, 0)) {
+ PLOG(ERROR) << "drmModeAddFB2 failed";
+ }
+}
+}
+
+bool addFramebuffer(int fd, buffer_handle_t buffer, uint32_t* id) {
+ if (buffer->numFds != GRALLOC_HANDLE_NUM_FDS
+ || buffer->numInts < static_cast<int>(GRALLOC_HANDLE_NUM_INTS))
+ return false;
+
+ auto handle = gralloc_handle(buffer);
+ if (handle->magic != GRALLOC_HANDLE_MAGIC)
+ return false;
+
+ if (handle->version != GRALLOC_HANDLE_VERSION) {
+ LOG(ERROR) << "gralloc_handle_t version mismatch: expected "
+ << GRALLOC_HANDLE_VERSION << ", got " << handle->version;
+ return true;
+ }
+
+ addFramebuffer(fd, handle, id);
+ return true;
+}
+
+} // namespace libdrm
+} // namespace implementation
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (C) 2019 Stephan Gerhold
+
+#define LOG_TAG "drmfb-framebuffer-minigbm"
+
+#include <android-base/logging.h>
+#include <drm/drm_fourcc.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include <cros_gralloc_handle.h>
+#include <cros_gralloc_helpers.h>
+#include "DrmFramebufferImporter.h"
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace drmfb {
+namespace minigbm {
+
+namespace {
+void addFramebuffer(int fd, cros_gralloc_handle_t handle, int planes, uint32_t* id) {
+ uint32_t handles[DRV_MAX_PLANES] = {};
+ for (int i = 0; i < planes; ++i) {
+ if (drmPrimeFDToHandle(fd, handle->fds[i], &handles[i])) {
+ PLOG(ERROR) << "Failed to get handle for prime fd "
+ << handle->fds[i] << " (plane " << i << ")";
+ return;
+ }
+ }
+
+ /*
+ * Avoid using alpha bits for the framebuffer.
+ * They are not supported on older Intel GPUs for primary planes.
+ */
+ auto format = handle->format;
+ if (format == DRM_FORMAT_ABGR8888)
+ format = DRM_FORMAT_XBGR8888;
+
+ // TODO: Consider using drmModeAddFB2WithModifiers
+ if (drmModeAddFB2(fd, handle->width, handle->height,
+ format, handles, handle->strides, handle->offsets, id, 0)) {
+ PLOG(ERROR) << "drmModeAddFB2 failed";
+ }
+}
+}
+
+bool addFramebuffer(int fd, buffer_handle_t buffer, uint32_t* id) {
+ auto planes = buffer->numFds;
+ if (planes < 1 && planes > DRV_MAX_PLANES)
+ return false;
+ if ((buffer->numInts + planes) < static_cast<int>(handle_data_size))
+ return false;
+
+ auto handle = reinterpret_cast<cros_gralloc_handle_t>(buffer);
+ if (handle->magic != cros_gralloc_magic)
+ return false;
+
+ addFramebuffer(fd, handle, planes, id);
+ return true;
+}
+
+} // namespace minigbm
+} // namespace implementation
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android