drm_hwcomposer: Split gralloc out into an importer
Add the concept of an importer so we can plug in different
sources of bo.
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Change-Id: I4f741ef4fa7c44e9cb31db61a146aed273854a69
diff --git a/hwcomposer.cpp b/hwcomposer.cpp
index 175e573..022fa62 100644
--- a/hwcomposer.cpp
+++ b/hwcomposer.cpp
@@ -26,16 +26,13 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
-#include <drm/drm_fourcc.h>
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include <sync/sync.h>
-#include <gralloc_drm.h>
-#include <gralloc_drm_priv.h>
-#include <gralloc_drm_handle.h>
+#include "drm_hwcomposer.h"
#define ARRAY_SIZE(arr) (int)(sizeof(arr) / sizeof((arr)[0]))
@@ -49,18 +46,6 @@
DRM_MODE_CONNECTOR_DSI,
};
-struct hwc_drm_bo {
- int fd; /* TODO: This is bad voodoo, remove it */
- uint32_t width;
- uint32_t height;
- uint32_t format;
- uint32_t pitches[4];
- uint32_t offsets[4];
- uint32_t gem_handles[4];
- uint32_t fb_id;
- int acquire_fence_fd;
-};
-
struct hwc_worker {
pthread_t thread;
pthread_mutex_t lock;
@@ -90,9 +75,9 @@
hwc_composer_device_1_t device;
int fd;
- struct drm_module_t *gralloc_module; /* TODO: NUKE THIS */
hwc_procs_t const *procs;
+ struct hwc_import_context *import_ctx;
struct hwc_drm_display displays[MAX_NUM_DISPLAYS];
int num_displays;
@@ -167,6 +152,20 @@
return ret;
}
+/*
+ * TODO: This hack allows us to use the importer's fd to drm to add and remove
+ * framebuffers. The reason it exists is because gralloc doesn't export its
+ * bo's, so we have to use its file descriptor to drm for some operations. Once
+ * gralloc behaves, we can remove this.
+ */
+static int hwc_get_fd_for_bo(struct hwc_context_t *ctx, struct hwc_drm_bo *bo)
+{
+ if (bo->importer_fd >= 0)
+ return bo->importer_fd;
+
+ return ctx->fd;
+}
+
static bool hwc_mode_is_equal(drmModeModeInfoPtr a, drmModeModeInfoPtr b)
{
return a->clock == b->clock &&
@@ -272,9 +271,10 @@
{
int ret;
- ret = drmModeAddFB2(hd->back.fd, hd->back.width, hd->back.height,
- hd->back.format, hd->back.gem_handles, hd->back.pitches,
- hd->back.offsets, &hd->back.fb_id, 0);
+ ret = drmModeAddFB2(hwc_get_fd_for_bo(hd->ctx, &hd->back),
+ hd->back.width, hd->back.height, hd->back.format,
+ hd->back.gem_handles, hd->back.pitches, hd->back.offsets,
+ &hd->back.fb_id, 0);
if (ret) {
ALOGE("could not create drm fb %d", ret);
return ret;
@@ -295,7 +295,8 @@
}
if (hd->front.fb_id) {
- ret = drmModeRmFB(hd->front.fd, hd->front.fb_id);
+ ret = drmModeRmFB(hwc_get_fd_for_bo(hd->ctx, &hd->front),
+ hd->front.fb_id);
if (ret) {
ALOGE("Failed to rm fb from front %d", ret);
return ret;
@@ -346,53 +347,6 @@
return NULL;
}
-static uint32_t hwc_convert_hal_format_to_drm_format(uint32_t hal_format)
-{
- switch(hal_format) {
- case HAL_PIXEL_FORMAT_RGB_888:
- return DRM_FORMAT_BGR888;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return DRM_FORMAT_ARGB8888;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- return DRM_FORMAT_XBGR8888;
- case HAL_PIXEL_FORMAT_RGBA_8888:
- return DRM_FORMAT_ABGR8888;
- case HAL_PIXEL_FORMAT_RGB_565:
- return DRM_FORMAT_BGR565;
- case HAL_PIXEL_FORMAT_YV12:
- return DRM_FORMAT_YVU420;
- default:
- ALOGE("Cannot convert hal format to drm format %u", hal_format);
- return -EINVAL;
- }
-}
-
-/* TODO: NUKE THIS */
-static int hwc_convert_gralloc_handle_to_drm_bo(hwc_context_t *ctx,
- buffer_handle_t handle, struct hwc_drm_bo *bo)
-{
- gralloc_drm_t *drm = ctx->gralloc_module->drm;
- gralloc_drm_handle_t *gr_handle;
- struct gralloc_drm_bo_t *gralloc_bo;
-
- gr_handle = (gralloc_drm_handle_t *)handle;
-
- gralloc_bo = gr_handle->data;
- if (!gralloc_bo) {
- ALOGE("Could not get drm bo from handle");
- return -EINVAL;
- }
-
- bo->fd = drm->fd;
- bo->width = gr_handle->width;
- bo->height = gr_handle->height;
- bo->format = hwc_convert_hal_format_to_drm_format(gr_handle->format);
- bo->pitches[0] = gr_handle->stride;
- bo->gem_handles[0] = gralloc_bo->fb_handle;
-
- return 0;
-}
-
static int hwc_set_display(hwc_context_t *ctx, int display,
hwc_display_contents_1_t* display_contents)
{
@@ -442,10 +396,10 @@
goto out;
}
- ret = hwc_convert_gralloc_handle_to_drm_bo(ctx, layer->handle,
- &hd->back);
+ ret = hwc_create_bo_from_import(ctx->fd, ctx->import_ctx, layer->handle,
+ &hd->back);
if (ret) {
- ALOGE("Failed to convert gralloc handle to drm bo %d", ret);
+ ALOGE("Failed to import handle to drm bo %d", ret);
goto out;
}
@@ -938,12 +892,17 @@
static int hwc_device_close(struct hw_device_t *dev)
{
struct hwc_context_t *ctx = (struct hwc_context_t *)dev;
- int i;
+ int ret, i;
for (i = 0; i < MAX_NUM_DISPLAYS; i++)
hwc_destroy_display(&ctx->displays[i]);
drmClose(ctx->fd);
+
+ ret = hwc_import_destroy(ctx->import_ctx);
+ if (ret)
+ ALOGE("Could not destroy import %d", ret);
+
free(ctx);
return 0;
@@ -1100,11 +1059,9 @@
return -ENOMEM;
}
- /* TODO: NUKE THIS */
- ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
- (const hw_module_t **)&ctx->gralloc_module);
+ ret = hwc_import_init(&ctx->import_ctx);
if (ret) {
- ALOGE("Failed to open gralloc module");
+ ALOGE("Failed to initialize import context");
goto out;
}