diff options
author | Sean Paul <seanpaul@chromium.org> | 2015-04-30 15:31:06 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2015-05-11 06:52:44 -0700 |
commit | 6a55e9fb8e16c63c2e42bde31814f963205f722d (patch) | |
tree | c8d9f44abd75ce7ddea57499cf73cd6dc11fc6c9 /hwcomposer.cpp | |
parent | ef8f1f9905dbd1f49735f6df47f3128ecbc71c1e (diff) | |
download | drm_hwcomposer-6a55e9fb8e16c63c2e42bde31814f963205f722d.tar.gz |
drm_hwcomposer: Wrap libdrm ops (minus modeset/flip) in C++ classes
This allows us to compartmentalize a bunch of code/logic from
hwcomposer.cpp into drm classes.
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Change-Id: Id3f912126f1fdcd44d32c3eb4fba646f77590278
Diffstat (limited to 'hwcomposer.cpp')
-rw-r--r-- | hwcomposer.cpp | 533 |
1 files changed, 126 insertions, 407 deletions
diff --git a/hwcomposer.cpp b/hwcomposer.cpp index f2e04b4..628d343 100644 --- a/hwcomposer.cpp +++ b/hwcomposer.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "hwcomposer-drm" #include "drm_hwcomposer.h" +#include "drmresources.h" #include <errno.h> #include <fcntl.h> @@ -36,13 +37,10 @@ #define ARRAY_SIZE(arr) (int)(sizeof(arr) / sizeof((arr)[0])) -#define HWCOMPOSER_DRM_DEVICE "/dev/dri/card0" #define MAX_NUM_DISPLAYS 3 #define UM_PER_INCH 25400 -static const uint32_t panel_types[] = { - DRM_MODE_CONNECTOR_LVDS, DRM_MODE_CONNECTOR_eDP, DRM_MODE_CONNECTOR_DSI, -}; +namespace android { struct hwc_worker { pthread_t thread; @@ -55,15 +53,7 @@ struct hwc_drm_display { struct hwc_context_t *ctx; int display; - uint32_t connector_id; - - drmModeModeInfoPtr configs; - uint32_t num_configs; - - drmModeModeInfo active_mode; - uint32_t active_crtc; - int active_pipe; - bool initial_modeset_required; + std::vector<uint32_t> config_ids; struct hwc_worker set_worker; @@ -82,8 +72,6 @@ struct hwc_drm_display { struct hwc_context_t { hwc_composer_device_1_t device; - int fd; - hwc_procs_t const *procs; struct hwc_import_context *import_ctx; @@ -91,6 +79,8 @@ struct hwc_context_t { int num_displays; struct hwc_worker event_worker; + + DrmResources drm; }; static int hwc_get_drm_display(struct hwc_context_t *ctx, int display, @@ -160,22 +150,23 @@ static int hwc_prepare(hwc_composer_device_1_t * /* dev */, size_t num_displays, } static int hwc_queue_vblank_event(struct hwc_drm_display *hd) { - if (hd->active_pipe == -1) { - ALOGE("Active pipe is -1 disp=%d", hd->display); - return -EINVAL; + DrmCrtc *crtc = hd->ctx->drm.GetCrtcForDisplay(hd->display); + if (!crtc) { + ALOGE("Failed to get crtc for display"); + return -ENODEV; } drmVBlank vblank; memset(&vblank, 0, sizeof(vblank)); - uint32_t high_crtc = (hd->active_pipe << DRM_VBLANK_HIGH_CRTC_SHIFT); + uint32_t high_crtc = (crtc->pipe() << DRM_VBLANK_HIGH_CRTC_SHIFT); vblank.request.type = (drmVBlankSeqType)( DRM_VBLANK_ABSOLUTE | DRM_VBLANK_NEXTONMISS | DRM_VBLANK_EVENT | (high_crtc & DRM_VBLANK_HIGH_CRTC_MASK)); vblank.request.signal = (unsigned long)hd; vblank.request.sequence = hd->vsync_sequence + 1; - int ret = drmWaitVBlank(hd->ctx->fd, &vblank); + int ret = drmWaitVBlank(hd->ctx->drm.fd(), &vblank); if (ret) { ALOGE("Failed to wait for vblank %d", ret); return ret; @@ -239,7 +230,7 @@ static void *hwc_event_worker(void *arg) { do { fd_set fds; FD_ZERO(&fds); - FD_SET(ctx->fd, &fds); + FD_SET(ctx->drm.fd(), &fds); drmEventContext event_context; event_context.version = DRM_EVENT_CONTEXT_VERSION; @@ -248,7 +239,7 @@ static void *hwc_event_worker(void *arg) { int ret; do { - ret = select(ctx->fd + 1, &fds, NULL, NULL, NULL); + ret = select(ctx->drm.fd() + 1, &fds, NULL, NULL, NULL); } while (ret == -1 && errno == EINTR); if (ret != 1) { @@ -256,7 +247,7 @@ static void *hwc_event_worker(void *arg) { continue; } - drmHandleEvent(ctx->fd, &event_context); + drmHandleEvent(ctx->drm.fd(), &event_context); } while (true); return NULL; @@ -273,56 +264,37 @@ static bool hwc_mode_is_equal(drmModeModeInfoPtr a, drmModeModeInfoPtr b) { !strcmp(a->name, b->name); } -static int hwc_modeset_required(struct hwc_drm_display *hd, - bool *modeset_required) { - if (hd->initial_modeset_required) { - *modeset_required = true; - hd->initial_modeset_required = false; - return 0; - } - - drmModeCrtcPtr crtc; - crtc = drmModeGetCrtc(hd->ctx->fd, hd->active_crtc); +static int hwc_flip(struct hwc_drm_display *hd, struct hwc_drm_bo *buf) { + DrmCrtc *crtc = hd->ctx->drm.GetCrtcForDisplay(hd->display); if (!crtc) { ALOGE("Failed to get crtc for display %d", hd->display); return -ENODEV; } - drmModeModeInfoPtr m; - m = &hd->active_mode; - - /* Do a modeset if we haven't done one, or the mode has changed */ - if (!crtc->mode_valid || !hwc_mode_is_equal(m, &crtc->mode)) - *modeset_required = true; - else - *modeset_required = false; - - drmModeFreeCrtc(crtc); - - return 0; -} - -static int hwc_flip(struct hwc_drm_display *hd, struct hwc_drm_bo *buf) { - bool modeset_required; - int ret = hwc_modeset_required(hd, &modeset_required); - if (ret) { - ALOGE("Failed to determine if modeset is required %d", ret); - return ret; + DrmConnector *connector = hd->ctx->drm.GetConnectorForDisplay(hd->display); + if (!connector) { + ALOGE("Failed to get connector for display %d", hd->display); + return -ENODEV; } - if (modeset_required) { - ret = drmModeSetCrtc(hd->ctx->fd, hd->active_crtc, buf->fb_id, 0, 0, - &hd->connector_id, 1, &hd->active_mode); + + int ret; + if (crtc->requires_modeset()) { + drmModeModeInfo drm_mode; + connector->active_mode().ToModeModeInfo(&drm_mode); + uint32_t connector_id = connector->id(); + ret = drmModeSetCrtc(hd->ctx->drm.fd(), crtc->id(), buf->fb_id, 0, 0, + &connector_id, 1, &drm_mode); if (ret) { - ALOGE("Modeset failed for crtc %d", hd->active_crtc); + ALOGE("Modeset failed for crtc %d", crtc->id()); return ret; } return 0; } - ret = drmModePageFlip(hd->ctx->fd, hd->active_crtc, buf->fb_id, + ret = drmModePageFlip(hd->ctx->drm.fd(), crtc->id(), buf->fb_id, DRM_MODE_PAGE_FLIP_EVENT, hd); if (ret) { - ALOGE("Failed to flip buffer for crtc %d", hd->active_crtc); + ALOGE("Failed to flip buffer for crtc %d", crtc->id()); return ret; } @@ -354,7 +326,8 @@ static int hwc_wait_and_set(struct hwc_drm_display *hd, return ret; } - if (hwc_import_bo_release(hd->ctx->fd, hd->ctx->import_ctx, &hd->front)) { + if (hwc_import_bo_release(hd->ctx->drm.fd(), hd->ctx->import_ctx, + &hd->front)) { struct drm_gem_close args; memset(&args, 0, sizeof(args)); for (int i = 0; i < ARRAY_SIZE(hd->front.gem_handles); ++i) { @@ -381,7 +354,7 @@ static int hwc_wait_and_set(struct hwc_drm_display *hd, if (!found) { args.handle = hd->front.gem_handles[i]; - drmIoctl(hd->ctx->fd, DRM_IOCTL_GEM_CLOSE, &args); + drmIoctl(hd->ctx->drm.fd(), DRM_IOCTL_GEM_CLOSE, &args); } if (pthread_mutex_unlock(&hd->set_worker.lock)) ALOGE("Failed to unlock set lock in wait_and_set() %d", ret); @@ -474,7 +447,8 @@ static int hwc_set_display(hwc_context_t *ctx, int display, return ret; } - if (!hd->active_crtc) { + DrmCrtc *crtc = hd->ctx->drm.GetCrtcForDisplay(display); + if (!crtc) { ALOGE("There is no active crtc for display %d", display); hwc_close_fences(display_contents); return -ENOENT; @@ -510,7 +484,8 @@ static int hwc_set_display(hwc_context_t *ctx, int display, struct hwc_drm_bo buf; memset(&buf, 0, sizeof(buf)); - ret = hwc_import_bo_create(ctx->fd, ctx->import_ctx, layer->handle, &buf); + ret = + hwc_import_bo_create(ctx->drm.fd(), ctx->import_ctx, layer->handle, &buf); if (ret) { ALOGE("Failed to import handle to drm bo %d", ret); hwc_close_fences(display_contents); @@ -566,8 +541,9 @@ static int hwc_event_control(struct hwc_composer_device_1 *dev, int display, if (event != HWC_EVENT_VSYNC || (enabled != 0 && enabled != 1)) return -EINVAL; - if (hd->active_pipe == -1) { - ALOGD("Can't service events for display %d, no pipe", display); + DrmCrtc *crtc = ctx->drm.GetCrtcForDisplay(display); + if (!crtc) { + ALOGD("Can't service events for display %d, no crtc", display); return -EINVAL; } @@ -596,60 +572,20 @@ static int hwc_set_power_mode(struct hwc_composer_device_1 *dev, int display, int mode) { struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - struct hwc_drm_display *hd = NULL; - int ret = hwc_get_drm_display(ctx, display, &hd); - if (ret) - return ret; - - drmModeConnectorPtr c = drmModeGetConnector(ctx->fd, hd->connector_id); - if (!c) { - ALOGE("Failed to get connector %d", display); - return -ENODEV; - } - - uint32_t dpms_prop = 0; - for (int i = 0; !dpms_prop && i < c->count_props; ++i) { - drmModePropertyPtr p; - - p = drmModeGetProperty(ctx->fd, c->props[i]); - if (!p) - continue; - - if (!strcmp(p->name, "DPMS")) - dpms_prop = c->props[i]; - - drmModeFreeProperty(p); - } - if (!dpms_prop) { - ALOGE("Failed to get DPMS property from display %d", display); - drmModeFreeConnector(c); - return -ENOENT; - } - - uint64_t dpms_value = 0; + uint64_t dpmsValue = 0; switch (mode) { case HWC_POWER_MODE_OFF: - dpms_value = DRM_MODE_DPMS_OFF; + dpmsValue = DRM_MODE_DPMS_OFF; break; /* We can't support dozing right now, so go full on */ case HWC_POWER_MODE_DOZE: case HWC_POWER_MODE_DOZE_SUSPEND: case HWC_POWER_MODE_NORMAL: - dpms_value = DRM_MODE_DPMS_ON; + dpmsValue = DRM_MODE_DPMS_ON; break; }; - - ret = drmModeConnectorSetProperty(ctx->fd, c->connector_id, dpms_prop, - dpms_value); - if (ret) { - ALOGE("Failed to set DPMS property for display %d", display); - drmModeFreeConnector(c); - return ret; - } - - drmModeFreeConnector(c); - return 0; + return ctx->drm.SetDpmsMode(display, dpmsValue); } static int hwc_query(struct hwc_composer_device_1 * /* dev */, int what, @@ -678,8 +614,8 @@ static void hwc_register_procs(struct hwc_composer_device_1 *dev, static int hwc_get_display_configs(struct hwc_composer_device_1 *dev, int display, uint32_t *configs, - size_t *numConfigs) { - if (!*numConfigs) + size_t *num_configs) { + if (!*num_configs) return 0; struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; @@ -688,67 +624,30 @@ static int hwc_get_display_configs(struct hwc_composer_device_1 *dev, if (ret) return ret; - drmModeConnectorPtr c = drmModeGetConnector(ctx->fd, hd->connector_id); - if (!c) { - ALOGE("Failed to get connector %d", display); - return -ENODEV; - } - - if (hd->configs) { - free(hd->configs); - hd->configs = NULL; - } + hd->config_ids.clear(); - if (c->connection == DRM_MODE_DISCONNECTED) { - drmModeFreeConnector(c); + DrmConnector *connector = ctx->drm.GetConnectorForDisplay(display); + if (!connector) { + ALOGE("Failed to get connector for display %d", display); return -ENODEV; } - hd->configs = - (drmModeModeInfoPtr)calloc(c->count_modes, sizeof(*hd->configs)); - if (!hd->configs) { - ALOGE("Failed to allocate config list for display %d", display); - hd->num_configs = 0; - drmModeFreeConnector(c); - return -ENOMEM; - } - - for (int i = 0; i < c->count_modes; ++i) { - drmModeModeInfoPtr m = &hd->configs[i]; - - memcpy(m, &c->modes[i], sizeof(*m)); - - if (i < (int)*numConfigs) - configs[i] = i; - } - - hd->num_configs = c->count_modes; - *numConfigs = MIN(c->count_modes, *numConfigs); - - drmModeFreeConnector(c); - return 0; -} - -static int hwc_check_config_valid(struct hwc_context_t *ctx, - drmModeConnectorPtr connector, int display, - int config_idx) { - struct hwc_drm_display *hd = NULL; - int ret = hwc_get_drm_display(ctx, display, &hd); - if (ret) + ret = connector->UpdateModes(); + if (ret) { + ALOGE("Failed to update display modes %d", ret); return ret; + } - /* Make sure the requested config is still valid for the display */ - drmModeModeInfoPtr m = NULL; - for (int i = 0; i < connector->count_modes; ++i) { - if (hwc_mode_is_equal(&connector->modes[i], &hd->configs[config_idx])) { - m = &hd->configs[config_idx]; + for (DrmConnector::ModeIter iter = connector->begin_modes(); + iter != connector->end_modes(); ++iter) { + size_t idx = hd->config_ids.size(); + if (idx == *num_configs) break; - } + hd->config_ids.push_back(iter->id()); + configs[idx] = iter->id(); } - if (!m) - return -ENOENT; - - return 0; + *num_configs = hd->config_ids.size(); + return *num_configs == 0 ? -1 : 0; } static int hwc_get_display_attributes(struct hwc_composer_device_1 *dev, @@ -756,53 +655,48 @@ static int hwc_get_display_attributes(struct hwc_composer_device_1 *dev, const uint32_t *attributes, int32_t *values) { struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - struct hwc_drm_display *hd = NULL; - int ret = hwc_get_drm_display(ctx, display, &hd); - if (ret) - return ret; - - if (config >= hd->num_configs) { - ALOGE("Requested config is out-of-bounds %d %d", config, hd->num_configs); - return -EINVAL; - } - - drmModeConnectorPtr c = drmModeGetConnector(ctx->fd, hd->connector_id); + DrmConnector *c = ctx->drm.GetConnectorForDisplay(display); if (!c) { - ALOGE("Failed to get connector %d", display); + ALOGE("Failed to get DrmConnector for display %d", display); return -ENODEV; } - - ret = hwc_check_config_valid(ctx, c, display, (int)config); - if (ret) { - ALOGE("Provided config is no longer valid %u", config); - drmModeFreeConnector(c); - return ret; + DrmMode mode; + for (DrmConnector::ModeIter iter = c->begin_modes(); iter != c->end_modes(); + ++iter) { + if (iter->id() == config) { + mode = *iter; + break; + } + } + if (mode.id() == 0) { + ALOGE("Failed to find active mode for display %d", display); + return -ENOENT; } - drmModeModeInfoPtr m = &hd->configs[config]; + uint32_t mm_width = c->mm_width(); + uint32_t mm_height = c->mm_height(); for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; ++i) { switch (attributes[i]) { case HWC_DISPLAY_VSYNC_PERIOD: - values[i] = 1000 * 1000 * 1000 / m->vrefresh; + values[i] = 1000 * 1000 * 1000 / mode.v_refresh(); break; case HWC_DISPLAY_WIDTH: - values[i] = m->hdisplay; + values[i] = mode.h_display(); break; case HWC_DISPLAY_HEIGHT: - values[i] = m->vdisplay; + values[i] = mode.v_display(); break; case HWC_DISPLAY_DPI_X: /* Dots per 1000 inches */ - values[i] = c->mmWidth ? (m->hdisplay * UM_PER_INCH) / c->mmWidth : 0; + values[i] = mm_width ? (mode.h_display() * UM_PER_INCH) / mm_width : 0; break; case HWC_DISPLAY_DPI_Y: /* Dots per 1000 inches */ - values[i] = c->mmHeight ? (m->vdisplay * UM_PER_INCH) / c->mmHeight : 0; + values[i] = + mm_height ? (mode.v_display() * UM_PER_INCH) / mm_height : 0; break; } } - - drmModeFreeConnector(c); return 0; } @@ -814,62 +708,18 @@ static int hwc_get_active_config(struct hwc_composer_device_1 *dev, if (ret) return ret; - /* Find the current mode in the config list */ - int index = -1; - for (int i = 0; i < (int)hd->num_configs; ++i) { - if (hwc_mode_is_equal(&hd->configs[i], &hd->active_mode)) { - index = i; - break; - } - } - return index; -} - -static bool hwc_crtc_is_bound(struct hwc_context_t *ctx, uint32_t crtc_id) { - for (int i = 0; i < MAX_NUM_DISPLAYS; ++i) { - if (ctx->displays[i].active_crtc == crtc_id) - return true; - } - return false; -} - -static int hwc_try_encoder(struct hwc_context_t *ctx, drmModeResPtr r, - uint32_t encoder_id, uint32_t *crtc_id) { - drmModeEncoderPtr e = drmModeGetEncoder(ctx->fd, encoder_id); - if (!e) { - ALOGE("Failed to get encoder for connector %d", encoder_id); + DrmConnector *c = ctx->drm.GetConnectorForDisplay(display); + if (!c) { + ALOGE("Failed to get DrmConnector for display %d", display); return -ENODEV; } - /* First try to use the currently-bound crtc */ - int ret = 0; - if (e->crtc_id) { - if (!hwc_crtc_is_bound(ctx, e->crtc_id)) { - *crtc_id = e->crtc_id; - drmModeFreeEncoder(e); - return 0; - } - } - - /* Try to find a possible crtc which will work */ - for (int i = 0; i < r->count_crtcs; ++i) { - if (!(e->possible_crtcs & (1 << i))) - continue; - - /* We've already tried this earlier */ - if (e->crtc_id == r->crtcs[i]) - continue; - - if (!hwc_crtc_is_bound(ctx, r->crtcs[i])) { - *crtc_id = r->crtcs[i]; - drmModeFreeEncoder(e); - return 0; - } + DrmMode mode = c->active_mode(); + for (size_t i = 0; i < hd->config_ids.size(); ++i) { + if (hd->config_ids[i] == mode.id()) + return i; } - - /* We can't use the encoder, but nothing went wrong, try another one */ - drmModeFreeEncoder(e); - return -EAGAIN; + return -1; } static int hwc_set_active_config(struct hwc_composer_device_1 *dev, int display, @@ -880,90 +730,19 @@ static int hwc_set_active_config(struct hwc_composer_device_1 *dev, int display, if (ret) return ret; - drmModeConnectorPtr c = drmModeGetConnector(ctx->fd, hd->connector_id); - if (!c) { - ALOGE("Failed to get connector %d", display); - return -ENODEV; - } - - if (c->connection == DRM_MODE_DISCONNECTED) { - ALOGE("Tried to configure a disconnected display %d", display); - drmModeFreeConnector(c); - return -ENODEV; - } - - if (index >= c->count_modes) { - ALOGE("Index is out-of-bounds %d/%d", index, c->count_modes); - drmModeFreeConnector(c); - return -ENOENT; - } - - drmModeResPtr r = drmModeGetResources(ctx->fd); - if (!r) { - ALOGE("Failed to get drm resources"); - drmModeFreeResources(r); - drmModeFreeConnector(c); - return -ENODEV; - } - - /* We no longer have an active_crtc */ - hd->active_crtc = 0; - hd->active_pipe = -1; - - /* First, try to use the currently-connected encoder */ - uint32_t crtc_id = 0; - if (c->encoder_id) { - ret = hwc_try_encoder(ctx, r, c->encoder_id, &crtc_id); - if (ret && ret != -EAGAIN) { - ALOGE("Encoder try failed %d", ret); - drmModeFreeResources(r); - drmModeFreeConnector(c); - return ret; - } - } - - /* We couldn't find a crtc with the attached encoder, try the others */ - if (!crtc_id) { - for (int i = 0; i < c->count_encoders; ++i) { - ret = hwc_try_encoder(ctx, r, c->encoders[i], &crtc_id); - if (!ret) { - break; - } else if (ret != -EAGAIN) { - ALOGE("Encoder try failed %d", ret); - drmModeFreeResources(r); - drmModeFreeConnector(c); - return ret; - } - } - if (!crtc_id) { - ALOGE("Couldn't find valid crtc to modeset"); - drmModeFreeConnector(c); - drmModeFreeResources(r); - return -EINVAL; - } + if (index >= (int)hd->config_ids.size()) { + ALOGE("Invalid config index %d passed in", index); + return -EINVAL; } - drmModeFreeConnector(c); - - hd->active_crtc = crtc_id; - memcpy(&hd->active_mode, &hd->configs[index], sizeof(hd->active_mode)); - /* Find the pipe corresponding to the crtc_id */ - for (int i = 0; i < r->count_crtcs; ++i) { - /* We've already tried this earlier */ - if (r->crtcs[i] == crtc_id) { - hd->active_pipe = i; - break; - } - } - drmModeFreeResources(r); - /* This should never happen... hehehe */ - if (hd->active_pipe == -1) { - ALOGE("Active crtc was not found in resources!!"); - return -ENODEV; + ret = + ctx->drm.SetDisplayActiveMode(display, hd->config_ids[index]); + if (ret) { + ALOGE("Failed to set config for display %d", display); + return ret; } - /* TODO: Once we have atomic, set the crtc timing info here */ - return 0; + return ret; } static int hwc_destroy_worker(struct hwc_worker *worker) { @@ -1004,8 +783,6 @@ static int hwc_device_close(struct hw_device_t *dev) { if (hwc_destroy_worker(&ctx->event_worker)) ALOGE("Destroy event worker failed"); - drmClose(ctx->fd); - int ret = hwc_import_destroy(ctx->import_ctx); if (ret) ALOGE("Could not destroy import %d", ret); @@ -1064,8 +841,7 @@ static int hwc_set_initial_config(struct hwc_drm_display *hd) { return ret; } -static int hwc_initialize_display(struct hwc_context_t *ctx, int display, - uint32_t connector_id) { +static int hwc_initialize_display(struct hwc_context_t *ctx, int display) { struct hwc_drm_display *hd = NULL; int ret = hwc_get_drm_display(ctx, display, &hd); if (ret) @@ -1073,9 +849,6 @@ static int hwc_initialize_display(struct hwc_context_t *ctx, int display, hd->ctx = ctx; hd->display = display; - hd->active_pipe = -1; - hd->initial_modeset_required = true; - hd->connector_id = connector_id; hd->enable_vsync_events = false; hd->vsync_sequence = 0; @@ -1139,74 +912,14 @@ static void hwc_free_conn_list(drmModeConnectorPtr *conn_list, int num_conn) { } static int hwc_enumerate_displays(struct hwc_context_t *ctx) { - drmModeResPtr res = drmModeGetResources(ctx->fd); - if (!res) { - ALOGE("Failed to get drm resources"); - return -ENODEV; - } - int num_connectors = res->count_connectors; - - drmModeConnectorPtr *conn_list = - (drmModeConnector **)calloc(num_connectors, sizeof(*conn_list)); - if (!conn_list) { - ALOGE("Failed to allocate connector list"); - drmModeFreeResources(res); - return -ENOMEM; - } - - for (int i = 0; i < num_connectors; ++i) { - conn_list[i] = drmModeGetConnector(ctx->fd, res->connectors[i]); - if (!conn_list[i]) { - ALOGE("Failed to get connector %d", res->connectors[i]); - drmModeFreeResources(res); - return -ENODEV; - } - } - drmModeFreeResources(res); - - ctx->num_displays = 0; - - /* Find a connected, panel type connector for display 0 */ - for (int i = 0; i < num_connectors; ++i) { - drmModeConnectorPtr c = conn_list[i]; - - int j; - for (j = 0; j < ARRAY_SIZE(panel_types); ++j) { - if (c->connector_type == panel_types[j] && - c->connection == DRM_MODE_CONNECTED) - break; + int ret; + for (DrmResources::ConnectorIter c = ctx->drm.begin_connectors(); + c != ctx->drm.end_connectors(); ++c) { + ret = hwc_initialize_display(ctx, (*c)->display()); + if (ret) { + ALOGE("Failed to initialize display %d", (*c)->display()); + return ret; } - if (j == ARRAY_SIZE(panel_types)) - continue; - - hwc_initialize_display(ctx, ctx->num_displays, c->connector_id); - ++ctx->num_displays; - break; - } - - struct hwc_drm_display *panel_hd; - int ret = hwc_get_drm_display(ctx, 0, &panel_hd); - if (ret) { - hwc_free_conn_list(conn_list, num_connectors); - return ret; - } - - /* Fill in the other displays */ - for (int i = 0; i < num_connectors; ++i) { - drmModeConnectorPtr c = conn_list[i]; - - if (panel_hd->connector_id == c->connector_id) - continue; - - hwc_initialize_display(ctx, ctx->num_displays, c->connector_id); - ++ctx->num_displays; - } - hwc_free_conn_list(conn_list, num_connectors); - - ret = hwc_initialize_worker(&ctx->event_worker, hwc_event_worker, ctx); - if (ret) { - ALOGE("Failed to create event worker %d\n", ret); - return ret; } return 0; @@ -1225,27 +938,30 @@ static int hwc_device_open(const struct hw_module_t *module, const char *name, return -ENOMEM; } - int ret = hwc_import_init(&ctx->import_ctx); + int ret = ctx->drm.Init(); if (ret) { - ALOGE("Failed to initialize import context"); + ALOGE("Can't initialize Drm object %d", ret); delete ctx; return ret; } - char path[PROPERTY_VALUE_MAX]; - property_get("hwc.drm.device", path, HWCOMPOSER_DRM_DEVICE); - /* TODO: Use drmOpenControl here instead */ - ctx->fd = open(path, O_RDWR); - if (ctx->fd < 0) { - ALOGE("Failed to open dri- %s", strerror(-errno)); + ret = hwc_import_init(&ctx->import_ctx); + if (ret) { + ALOGE("Failed to initialize import context"); delete ctx; - return -ENOENT; + return ret; } ret = hwc_enumerate_displays(ctx); if (ret) { ALOGE("Failed to enumerate displays: %s", strerror(ret)); - close(ctx->fd); + delete ctx; + return ret; + } + + ret = hwc_initialize_worker(&ctx->event_worker, hwc_event_worker, ctx); + if (ret) { + ALOGE("Failed to create event worker %d\n", ret); delete ctx; return ret; } @@ -1271,8 +987,11 @@ static int hwc_device_open(const struct hw_module_t *module, const char *name, return 0; } +} -static struct hw_module_methods_t hwc_module_methods = {open : hwc_device_open}; +static struct hw_module_methods_t hwc_module_methods = { + open : android::hwc_device_open +}; hwc_module_t HAL_MODULE_INFO_SYM = { common : { |