From ef8f1f9905dbd1f49735f6df47f3128ecbc71c1e Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Wed, 29 Apr 2015 16:05:23 -0400 Subject: [PATCH] drm_hwcomposer: Update style to conform with Google Style Guide Change-Id: I9b1a7dbcb9b8c6b0a6eb3c6416b5e4898a5097d8 Signed-off-by: Sean Paul --- drm_hwcomposer.h | 74 +- hwcomposer.cpp | 2127 ++++++++++++++--------------- hwcomposer_import_drm_gralloc.cpp | 163 +-- hwcomposer_import_nv_gralloc.cpp | 211 ++- 4 files changed, 1207 insertions(+), 1368 deletions(-) diff --git a/drm_hwcomposer.h b/drm_hwcomposer.h index 172b15b..c82506c 100644 --- a/drm_hwcomposer.h +++ b/drm_hwcomposer.h @@ -14,52 +14,60 @@ * limitations under the License. */ +#ifndef ANDROID_DRM_HWCOMPOSER_H_ +#define ANDROID_DRM_HWCOMPOSER_H_ + #include #include +#include +#include + struct hwc_import_context; enum { - /* perform(const struct gralloc_module_t *mod, - * int op, - * int drm_fd, - * buffer_handle_t buffer, - * struct hwc_drm_bo *bo); - */ - GRALLOC_MODULE_PERFORM_DRM_IMPORT = 0xffeeff00, + /* perform(const struct gralloc_module_t *mod, + * int op, + * int drm_fd, + * buffer_handle_t buffer, + * struct hwc_drm_bo *bo); + */ + GRALLOC_MODULE_PERFORM_DRM_IMPORT = 0xffeeff00, - /* perform(const struct gralloc_module_t *mod, - * int op, - * buffer_handle_t buffer, - * void (*free_callback)(void *), - * void *priv); - */ - GRALLOC_MODULE_PERFORM_SET_IMPORTER_PRIVATE = 0xffeeff01, + /* perform(const struct gralloc_module_t *mod, + * int op, + * buffer_handle_t buffer, + * void (*free_callback)(void *), + * void *priv); + */ + GRALLOC_MODULE_PERFORM_SET_IMPORTER_PRIVATE = 0xffeeff01, - /* perform(const struct gralloc_module_t *mod, - * int op, - * buffer_handle_t buffer, - * void (*free_callback)(void *), - * void **priv); - */ - GRALLOC_MODULE_PERFORM_GET_IMPORTER_PRIVATE = 0xffeeff02, + /* perform(const struct gralloc_module_t *mod, + * int op, + * buffer_handle_t buffer, + * void (*free_callback)(void *), + * void **priv); + */ + GRALLOC_MODULE_PERFORM_GET_IMPORTER_PRIVATE = 0xffeeff02, }; -struct hwc_drm_bo { - uint32_t width; - uint32_t height; - uint32_t format; /* DRM_FORMAT_* from drm_fourcc.h */ - uint32_t pitches[4]; - uint32_t offsets[4]; - uint32_t gem_handles[4]; - uint32_t fb_id; - int acquire_fence_fd; -}; +typedef struct hwc_drm_bo { + uint32_t width; + uint32_t height; + uint32_t format; /* DRM_FORMAT_* from drm_fourcc.h */ + uint32_t pitches[4]; + uint32_t offsets[4]; + uint32_t gem_handles[4]; + uint32_t fb_id; + int acquire_fence_fd; +} hwc_drm_bo_t; int hwc_import_init(struct hwc_import_context **ctx); int hwc_import_destroy(struct hwc_import_context *ctx); int hwc_import_bo_create(int fd, struct hwc_import_context *ctx, - buffer_handle_t buf, struct hwc_drm_bo *bo); + buffer_handle_t buf, struct hwc_drm_bo *bo); bool hwc_import_bo_release(int fd, struct hwc_import_context *ctx, - struct hwc_drm_bo *bo); + struct hwc_drm_bo *bo); + +#endif diff --git a/hwcomposer.cpp b/hwcomposer.cpp index c5534e2..f2e04b4 100644 --- a/hwcomposer.cpp +++ b/hwcomposer.cpp @@ -16,26 +16,23 @@ #define LOG_TAG "hwcomposer-drm" -#include +#include "drm_hwcomposer.h" + #include +#include #include +#include #include #include -#include - -#include - #include #include +#include +#include #include #include - -#include -#include #include - -#include "drm_hwcomposer.h" +#include #define ARRAY_SIZE(arr) (int)(sizeof(arr) / sizeof((arr)[0])) @@ -44,1113 +41,1005 @@ #define UM_PER_INCH 25400 static const uint32_t panel_types[] = { - DRM_MODE_CONNECTOR_LVDS, - DRM_MODE_CONNECTOR_eDP, - DRM_MODE_CONNECTOR_DSI, + DRM_MODE_CONNECTOR_LVDS, DRM_MODE_CONNECTOR_eDP, DRM_MODE_CONNECTOR_DSI, }; struct hwc_worker { - pthread_t thread; - pthread_mutex_t lock; - pthread_cond_t cond; - bool exit; + pthread_t thread; + pthread_mutex_t lock; + pthread_cond_t cond; + bool exit; }; struct hwc_drm_display { - struct hwc_context_t *ctx; - int display; + struct hwc_context_t *ctx; + int display; - uint32_t connector_id; + uint32_t connector_id; - drmModeModeInfoPtr configs; - uint32_t num_configs; + drmModeModeInfoPtr configs; + uint32_t num_configs; - drmModeModeInfo active_mode; - uint32_t active_crtc; - int active_pipe; - bool initial_modeset_required; + drmModeModeInfo active_mode; + uint32_t active_crtc; + int active_pipe; + bool initial_modeset_required; - struct hwc_worker set_worker; + struct hwc_worker set_worker; - std::list buf_queue; - struct hwc_drm_bo front; - pthread_mutex_t flip_lock; - pthread_cond_t flip_cond; + std::list buf_queue; + struct hwc_drm_bo front; + pthread_mutex_t flip_lock; + pthread_cond_t flip_cond; - int timeline_fd; - unsigned timeline_next; + int timeline_fd; + unsigned timeline_next; - bool enable_vsync_events; - unsigned int vsync_sequence; + bool enable_vsync_events; + unsigned int vsync_sequence; }; struct hwc_context_t { - hwc_composer_device_1_t device; + hwc_composer_device_1_t device; - int fd; + int fd; - hwc_procs_t const *procs; - struct hwc_import_context *import_ctx; + hwc_procs_t const *procs; + struct hwc_import_context *import_ctx; - struct hwc_drm_display displays[MAX_NUM_DISPLAYS]; - int num_displays; + struct hwc_drm_display displays[MAX_NUM_DISPLAYS]; + int num_displays; - struct hwc_worker event_worker; + struct hwc_worker event_worker; }; static int hwc_get_drm_display(struct hwc_context_t *ctx, int display, - struct hwc_drm_display **hd) -{ - if (display >= MAX_NUM_DISPLAYS) { - ALOGE("Requested display is out-of-bounds %d %d", display, - MAX_NUM_DISPLAYS); - return -EINVAL; - } - *hd = &ctx->displays[display]; - return 0; + struct hwc_drm_display **hd) { + if (display >= MAX_NUM_DISPLAYS) { + ALOGE("Requested display is out-of-bounds %d %d", display, + MAX_NUM_DISPLAYS); + return -EINVAL; + } + *hd = &ctx->displays[display]; + return 0; } -static int hwc_prepare_layer(hwc_layer_1_t *layer) -{ - /* TODO: We can't handle background right now, defer to sufaceFlinger */ - if (layer->compositionType == HWC_BACKGROUND) { - layer->compositionType = HWC_FRAMEBUFFER; - ALOGV("Can't handle background layers yet"); +static int hwc_prepare_layer(hwc_layer_1_t *layer) { + /* TODO: We can't handle background right now, defer to sufaceFlinger */ + if (layer->compositionType == HWC_BACKGROUND) { + layer->compositionType = HWC_FRAMEBUFFER; + ALOGV("Can't handle background layers yet"); - /* TODO: Support sideband compositions */ - } else if (layer->compositionType == HWC_SIDEBAND) { - layer->compositionType = HWC_FRAMEBUFFER; - ALOGV("Can't handle sideband content yet"); - } + /* TODO: Support sideband compositions */ + } else if (layer->compositionType == HWC_SIDEBAND) { + layer->compositionType = HWC_FRAMEBUFFER; + ALOGV("Can't handle sideband content yet"); + } - layer->hints = 0; + layer->hints = 0; - /* TODO: Handle cursor by setting compositionType=HWC_CURSOR_OVERLAY */ - if (layer->flags & HWC_IS_CURSOR_LAYER) { - ALOGV("Can't handle async cursors yet"); - } + /* TODO: Handle cursor by setting compositionType=HWC_CURSOR_OVERLAY */ + if (layer->flags & HWC_IS_CURSOR_LAYER) { + ALOGV("Can't handle async cursors yet"); + } - /* TODO: Handle transformations */ - if (layer->transform) { - ALOGV("Can't handle transformations yet"); - } + /* TODO: Handle transformations */ + if (layer->transform) { + ALOGV("Can't handle transformations yet"); + } - /* TODO: Handle blending & plane alpha*/ - if (layer->blending == HWC_BLENDING_PREMULT || - layer->blending == HWC_BLENDING_COVERAGE) { - ALOGV("Can't handle blending yet"); - } + /* TODO: Handle blending & plane alpha*/ + if (layer->blending == HWC_BLENDING_PREMULT || + layer->blending == HWC_BLENDING_COVERAGE) { + ALOGV("Can't handle blending yet"); + } - /* TODO: Handle cropping & scaling */ + /* TODO: Handle cropping & scaling */ - return 0; + return 0; } -static int hwc_prepare(hwc_composer_device_1_t */* dev */, size_t num_displays, - hwc_display_contents_1_t** display_contents) -{ - int ret = 0, i, j; +static int hwc_prepare(hwc_composer_device_1_t * /* dev */, size_t num_displays, + hwc_display_contents_1_t **display_contents) { + /* TODO: Check flags for HWC_GEOMETRY_CHANGED */ - /* TODO: Check flags for HWC_GEOMETRY_CHANGED */ + for (int i = 0; i < (int)num_displays && i < MAX_NUM_DISPLAYS; ++i) { + if (!display_contents[i]) + continue; - for (i = 0; i < (int)num_displays && i < MAX_NUM_DISPLAYS; i++) { + for (int j = 0; j < (int)display_contents[i]->numHwLayers; ++j) { + int ret = hwc_prepare_layer(&display_contents[i]->hwLayers[j]); + if (ret) { + ALOGE("Failed to prepare layer %d:%d", j, i); + return ret; + } + } + } - if (!display_contents[i]) - continue; - - for (j = 0; j < (int)display_contents[i]->numHwLayers; j++) { - ret = hwc_prepare_layer( - &display_contents[i]->hwLayers[j]); - if (ret) { - ALOGE("Failed to prepare layer %d:%d", j, i); - return ret; - } - } - } - - return ret; + return 0; } -static int hwc_queue_vblank_event(struct hwc_drm_display *hd) -{ - drmVBlank vblank; - int ret; - uint32_t high_crtc; - int64_t timestamp; +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; + } - if (hd->active_pipe == -1) { - ALOGE("Active pipe is -1 disp=%d", hd->display); - return -EINVAL; - } + drmVBlank vblank; + memset(&vblank, 0, sizeof(vblank)); - memset(&vblank, 0, sizeof(vblank)); + uint32_t high_crtc = (hd->active_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; - high_crtc = (hd->active_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); + if (ret) { + ALOGE("Failed to wait for vblank %d", ret); + return ret; + } - ret = drmWaitVBlank(hd->ctx->fd, &vblank); - if (ret) { - ALOGE("Failed to wait for vblank %d", ret); - return ret; - } - - return 0; + return 0; } static void hwc_vblank_event_handler(int /* fd */, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data) -{ - struct hwc_drm_display *hd = (struct hwc_drm_display *)user_data; - int64_t timestamp; - int ret; + unsigned int tv_sec, unsigned int tv_usec, + void *user_data) { + struct hwc_drm_display *hd = (struct hwc_drm_display *)user_data; - if (!hd->enable_vsync_events || !hd->ctx->procs->vsync) - return; + if (!hd->enable_vsync_events || !hd->ctx->procs->vsync) + return; - /* - * Discard duplicate vsync (can happen when enabling vsync events while - * already processing vsyncs). - */ - if (sequence <= hd->vsync_sequence) - return; + /* + * Discard duplicate vsync (can happen when enabling vsync events while + * already processing vsyncs). + */ + if (sequence <= hd->vsync_sequence) + return; - hd->vsync_sequence = sequence; - ret = hwc_queue_vblank_event(hd); - if (ret) - ALOGE("Failed to queue vblank event ret=%d", ret); + hd->vsync_sequence = sequence; + int ret = hwc_queue_vblank_event(hd); + if (ret) + ALOGE("Failed to queue vblank event ret=%d", ret); - timestamp = (int64_t)tv_sec * 1000 * 1000 * 1000 + - (int64_t)tv_usec * 1000; - hd->ctx->procs->vsync(hd->ctx->procs, hd->display, timestamp); + int64_t timestamp = + (int64_t)tv_sec * 1000 * 1000 * 1000 + (int64_t)tv_usec * 1000; + hd->ctx->procs->vsync(hd->ctx->procs, hd->display, timestamp); } static void hwc_flip_event_handler(int /* fd */, unsigned int /* sequence */, - unsigned int /* tv_sec */, unsigned int /* tv_usec */, - void *user_data) -{ - struct hwc_drm_display *hd = (struct hwc_drm_display *)user_data; - int ret; - int64_t timestamp; + unsigned int /* tv_sec */, + unsigned int /* tv_usec */, + void *user_data) { + struct hwc_drm_display *hd = (struct hwc_drm_display *)user_data; - ret = pthread_mutex_lock(&hd->flip_lock); - if (ret) { - ALOGE("Failed to lock flip lock ret=%d", ret); - return; - } + int ret = pthread_mutex_lock(&hd->flip_lock); + if (ret) { + ALOGE("Failed to lock flip lock ret=%d", ret); + return; + } - ret = pthread_cond_signal(&hd->flip_cond); - if (ret) { - ALOGE("Failed to signal flip condition ret=%d", ret); - goto out; - } + ret = pthread_cond_signal(&hd->flip_cond); + if (ret) + ALOGE("Failed to signal flip condition ret=%d", ret); -out: - ret = pthread_mutex_unlock(&hd->flip_lock); - if (ret) { - ALOGE("Failed to unlock flip lock ret=%d", ret); - return; - } + ret = pthread_mutex_unlock(&hd->flip_lock); + if (ret) { + ALOGE("Failed to unlock flip lock ret=%d", ret); + return; + } } -static void *hwc_event_worker(void *arg) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)arg; - int ret; - fd_set fds; - drmEventContext event_context; +static void *hwc_event_worker(void *arg) { + setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); - setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); + struct hwc_context_t *ctx = (struct hwc_context_t *)arg; + do { + fd_set fds; + FD_ZERO(&fds); + FD_SET(ctx->fd, &fds); - do { - FD_ZERO(&fds); - FD_SET(ctx->fd, &fds); + drmEventContext event_context; + event_context.version = DRM_EVENT_CONTEXT_VERSION; + event_context.page_flip_handler = hwc_flip_event_handler; + event_context.vblank_handler = hwc_vblank_event_handler; - event_context.version = DRM_EVENT_CONTEXT_VERSION; - event_context.page_flip_handler = hwc_flip_event_handler; - event_context.vblank_handler = hwc_vblank_event_handler; + int ret; + do { + ret = select(ctx->fd + 1, &fds, NULL, NULL, NULL); + } while (ret == -1 && errno == EINTR); - do { - ret = select(ctx->fd + 1, &fds, NULL, NULL, NULL); - } while (ret == -1 && errno == EINTR); + if (ret != 1) { + ALOGE("Failed waiting for drm event\n"); + continue; + } - if (ret != 1) { - ALOGE("Failed waiting for drm event\n"); - continue; - } + drmHandleEvent(ctx->fd, &event_context); + } while (true); - drmHandleEvent(ctx->fd, &event_context); - } while (true); - - return NULL; + return NULL; } -static bool hwc_mode_is_equal(drmModeModeInfoPtr a, drmModeModeInfoPtr b) -{ - return a->clock == b->clock && - a->hdisplay == b->hdisplay && - a->hsync_start == b->hsync_start && - a->hsync_end == b->hsync_end && - a->htotal == b->htotal && - a->hskew == b->hskew && - a->vdisplay == b->vdisplay && - a->vsync_start == b->vsync_start && - a->vsync_end == b->vsync_end && - a->vtotal == b->vtotal && - a->vscan == b->vscan && - a->vrefresh == b->vrefresh && - a->flags == b->flags && - a->type == b->type && - !strcmp(a->name, b->name); +static bool hwc_mode_is_equal(drmModeModeInfoPtr a, drmModeModeInfoPtr b) { + return a->clock == b->clock && a->hdisplay == b->hdisplay && + a->hsync_start == b->hsync_start && a->hsync_end == b->hsync_end && + a->htotal == b->htotal && a->hskew == b->hskew && + a->vdisplay == b->vdisplay && a->vsync_start == b->vsync_start && + a->vsync_end == b->vsync_end && a->vtotal == b->vtotal && + a->vscan == b->vscan && a->vrefresh == b->vrefresh && + a->flags == b->flags && a->type == b->type && + !strcmp(a->name, b->name); } static int hwc_modeset_required(struct hwc_drm_display *hd, - bool *modeset_required) -{ - drmModeCrtcPtr crtc; - drmModeModeInfoPtr m; + bool *modeset_required) { + if (hd->initial_modeset_required) { + *modeset_required = true; + hd->initial_modeset_required = false; + return 0; + } - 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); + if (!crtc) { + ALOGE("Failed to get crtc for display %d", hd->display); + return -ENODEV; + } - crtc = drmModeGetCrtc(hd->ctx->fd, hd->active_crtc); - if (!crtc) { - ALOGE("Failed to get crtc for display %d", hd->display); - return -ENODEV; - } + drmModeModeInfoPtr m; + m = &hd->active_mode; - 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; - /* 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); - drmModeFreeCrtc(crtc); - - return 0; + return 0; } -static int hwc_flip(struct hwc_drm_display *hd, struct hwc_drm_bo *buf) -{ - int ret; - bool modeset_required; +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; + } + if (modeset_required) { + ret = drmModeSetCrtc(hd->ctx->fd, hd->active_crtc, buf->fb_id, 0, 0, + &hd->connector_id, 1, &hd->active_mode); + if (ret) { + ALOGE("Modeset failed for crtc %d", hd->active_crtc); + return ret; + } + return 0; + } - ret = hwc_modeset_required(hd, &modeset_required); - if (ret) { - ALOGE("Failed to determine if modeset is required %d", ret); - return ret; - } - if (modeset_required) { - ret = drmModeSetCrtc(hd->ctx->fd, hd->active_crtc, buf->fb_id, - 0, 0, &hd->connector_id, 1, - &hd->active_mode); - if (ret) { - ALOGE("Modeset failed for crtc %d", - hd->active_crtc); - return ret; - } - return 0; - } + ret = drmModePageFlip(hd->ctx->fd, hd->active_crtc, buf->fb_id, + DRM_MODE_PAGE_FLIP_EVENT, hd); + if (ret) { + ALOGE("Failed to flip buffer for crtc %d", hd->active_crtc); + return ret; + } - ret = drmModePageFlip(hd->ctx->fd, hd->active_crtc, buf->fb_id, - DRM_MODE_PAGE_FLIP_EVENT, hd); - if (ret) { - ALOGE("Failed to flip buffer for crtc %d", - hd->active_crtc); - return ret; - } + ret = pthread_cond_wait(&hd->flip_cond, &hd->flip_lock); + if (ret) { + ALOGE("Failed to wait on condition %d", ret); + return ret; + } - ret = pthread_cond_wait(&hd->flip_cond, &hd->flip_lock); - if (ret) { - ALOGE("Failed to wait on condition %d", ret); - return ret; - } - - return 0; + return 0; } static int hwc_wait_and_set(struct hwc_drm_display *hd, - struct hwc_drm_bo *buf) -{ - struct drm_gem_close args; - int ret, i; + struct hwc_drm_bo *buf) { + int ret; + if (buf->acquire_fence_fd >= 0) { + ret = sync_wait(buf->acquire_fence_fd, -1); + close(buf->acquire_fence_fd); + buf->acquire_fence_fd = -1; + if (ret) { + ALOGE("Failed to wait for acquire %d", ret); + return ret; + } + } - if (buf->acquire_fence_fd >= 0) { - ret = sync_wait(buf->acquire_fence_fd, -1); - close(buf->acquire_fence_fd); - buf->acquire_fence_fd = -1; - if (ret) { - ALOGE("Failed to wait for acquire %d", ret); - return ret; - } - } + ret = hwc_flip(hd, buf); + if (ret) { + ALOGE("Failed to perform flip\n"); + return ret; + } - ret = hwc_flip(hd, buf); - if (ret) { - ALOGE("Failed to perform flip\n"); - return ret; - } + if (hwc_import_bo_release(hd->ctx->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) { + if (!hd->front.gem_handles[i]) + continue; - if (hwc_import_bo_release(hd->ctx->fd, hd->ctx->import_ctx, &hd->front)) { - memset(&args, 0, sizeof(args)); - for (i = 0; i < ARRAY_SIZE(hd->front.gem_handles); i++) { - if (!hd->front.gem_handles[i]) - continue; + ret = pthread_mutex_lock(&hd->set_worker.lock); + if (ret) { + ALOGE("Failed to lock set lock in wait_and_set() %d", ret); + continue; + } - /* check for duplicate handle in buf_queue */ - bool found; + /* check for duplicate handle in buf_queue */ + bool found = false; + for (std::list::iterator bi = hd->buf_queue.begin(); + bi != hd->buf_queue.end(); ++bi) + for (int j = 0; j < ARRAY_SIZE(bi->gem_handles); ++j) + if (hd->front.gem_handles[i] == bi->gem_handles[j]) + found = true; - ret = pthread_mutex_lock(&hd->set_worker.lock); - if (ret) { - ALOGE("Failed to lock set lock in wait_and_set() %d", ret); - continue; - } + for (int j = 0; j < ARRAY_SIZE(buf->gem_handles); ++j) + if (hd->front.gem_handles[i] == buf->gem_handles[j]) + found = true; - found = false; - for (std::list::iterator bi = hd->buf_queue.begin(); - bi != hd->buf_queue.end(); - ++bi) - for (int j = 0; j < ARRAY_SIZE(bi->gem_handles); j++) - if (hd->front.gem_handles[i] == bi->gem_handles[j] ) - found = true; + if (!found) { + args.handle = hd->front.gem_handles[i]; + drmIoctl(hd->ctx->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); + } + } - for (int j = 0; j < ARRAY_SIZE(buf->gem_handles); j++) - if (hd->front.gem_handles[i] == buf->gem_handles[j]) - found = true; + hd->front = *buf; - if (!found) { - args.handle = hd->front.gem_handles[i]; - drmIoctl(hd->ctx->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); - } - } - - hd->front = *buf; - - return ret; + return ret; } -static void *hwc_set_worker(void *arg) -{ - struct hwc_drm_display *hd = (struct hwc_drm_display *)arg; - int ret; +static void *hwc_set_worker(void *arg) { + setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); - setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); + struct hwc_drm_display *hd = (struct hwc_drm_display *)arg; + int ret = pthread_mutex_lock(&hd->flip_lock); + if (ret) { + ALOGE("Failed to lock flip lock ret=%d", ret); + return NULL; + } - ret = pthread_mutex_lock(&hd->flip_lock); - if (ret) { - ALOGE("Failed to lock flip lock ret=%d", ret); - return NULL; - } + do { + ret = pthread_mutex_lock(&hd->set_worker.lock); + if (ret) { + ALOGE("Failed to lock set lock %d", ret); + return NULL; + } - do { - struct hwc_drm_bo buf; + if (hd->set_worker.exit) + break; - ret = pthread_mutex_lock(&hd->set_worker.lock); - if (ret) { - ALOGE("Failed to lock set lock %d", ret); - return NULL; - } + if (hd->buf_queue.empty()) { + ret = pthread_cond_wait(&hd->set_worker.cond, &hd->set_worker.lock); + if (ret) { + ALOGE("Failed to wait on condition %d", ret); + break; + } + } - if (hd->set_worker.exit) - goto out; + struct hwc_drm_bo buf; + buf = hd->buf_queue.front(); + hd->buf_queue.pop_front(); - if (hd->buf_queue.empty()) { - ret = pthread_cond_wait(&hd->set_worker.cond, - &hd->set_worker.lock); - if (ret) { - ALOGE("Failed to wait on condition %d", ret); - goto out; - } - } + ret = pthread_mutex_unlock(&hd->set_worker.lock); + if (ret) { + ALOGE("Failed to unlock set lock %d", ret); + return NULL; + } - buf = hd->buf_queue.front(); - hd->buf_queue.pop_front(); + ret = hwc_wait_and_set(hd, &buf); + if (ret) + ALOGE("Failed to wait and set %d", ret); - ret = pthread_mutex_unlock(&hd->set_worker.lock); - if (ret) { - ALOGE("Failed to unlock set lock %d", ret); - return NULL; - } + ret = sw_sync_timeline_inc(hd->timeline_fd, 1); + if (ret) + ALOGE("Failed to increment sync timeline %d", ret); + } while (true); - ret = hwc_wait_and_set(hd, &buf); - if (ret) - ALOGE("Failed to wait and set %d", ret); + ret = pthread_mutex_unlock(&hd->set_worker.lock); + if (ret) + ALOGE("Failed to unlock set lock while exiting %d", ret); - ret = sw_sync_timeline_inc(hd->timeline_fd, 1); - if (ret) - ALOGE("Failed to increment sync timeline %d", ret); - } while (true); + ret = pthread_mutex_unlock(&hd->flip_lock); + if (ret) + ALOGE("Failed to unlock flip lock ret=%d", ret); -out: - ret = pthread_mutex_unlock(&hd->set_worker.lock); - if (ret) - ALOGE("Failed to unlock set lock while exiting %d", ret); + return NULL; +} - ret = pthread_mutex_unlock(&hd->flip_lock); - if (ret) - ALOGE("Failed to unlock flip lock ret=%d", ret); - - - return NULL; +static void hwc_close_fences(hwc_display_contents_1_t *display_contents) { + for (int i = 0; i < (int)display_contents->numHwLayers; ++i) { + hwc_layer_1_t *layer = &display_contents->hwLayers[i]; + if (layer->acquireFenceFd >= 0) { + close(layer->acquireFenceFd); + layer->acquireFenceFd = -1; + } + } + if (display_contents->outbufAcquireFenceFd >= 0) { + close(display_contents->outbufAcquireFenceFd); + display_contents->outbufAcquireFenceFd = -1; + } } static int hwc_set_display(hwc_context_t *ctx, int display, - hwc_display_contents_1_t* display_contents) -{ - struct hwc_drm_display *hd = NULL; - hwc_layer_1_t *layer = NULL; - struct hwc_drm_bo buf; - int ret, i; - uint32_t fb_id; + hwc_display_contents_1_t *display_contents) { + struct hwc_drm_display *hd = NULL; + int ret = hwc_get_drm_display(ctx, display, &hd); + if (ret) { + hwc_close_fences(display_contents); + return ret; + } - memset(&buf, 0, sizeof(buf)); + if (!hd->active_crtc) { + ALOGE("There is no active crtc for display %d", display); + hwc_close_fences(display_contents); + return -ENOENT; + } - ret = hwc_get_drm_display(ctx, display, &hd); - if (ret) - goto out; + /* + * TODO: We can only support one hw layer atm, so choose either the + * first one or the framebuffer target. + */ + hwc_layer_1_t *layer = NULL; + if (!display_contents->numHwLayers) { + return 0; + } else if (display_contents->numHwLayers == 1) { + layer = &display_contents->hwLayers[0]; + } else { + int i; + for (i = 0; i < (int)display_contents->numHwLayers; ++i) { + layer = &display_contents->hwLayers[i]; + if (layer->compositionType == HWC_FRAMEBUFFER_TARGET) + break; + } + if (i == (int)display_contents->numHwLayers) { + ALOGE("Could not find a suitable layer for display %d", display); + } + } - if (!hd->active_crtc) { - ALOGE("There is no active crtc for display %d", display); - ret = -ENOENT; - goto out; - } + ret = pthread_mutex_lock(&hd->set_worker.lock); + if (ret) { + ALOGE("Failed to lock set lock in set() %d", ret); + hwc_close_fences(display_contents); + return ret; + } - /* - * TODO: We can only support one hw layer atm, so choose either the - * first one or the framebuffer target. - */ - if (!display_contents->numHwLayers) { - return 0; - } else if (display_contents->numHwLayers == 1) { - layer = &display_contents->hwLayers[0]; - } else { - for (i = 0; i < (int)display_contents->numHwLayers; i++) { - layer = &display_contents->hwLayers[i]; - if (layer->compositionType == HWC_FRAMEBUFFER_TARGET) - break; - } - if (i == (int)display_contents->numHwLayers) { - ALOGE("Could not find a suitable layer for display %d", - display); - } - } + struct hwc_drm_bo buf; + memset(&buf, 0, sizeof(buf)); + ret = hwc_import_bo_create(ctx->fd, ctx->import_ctx, layer->handle, &buf); + if (ret) { + ALOGE("Failed to import handle to drm bo %d", ret); + hwc_close_fences(display_contents); + return ret; + } + buf.acquire_fence_fd = layer->acquireFenceFd; + layer->acquireFenceFd = -1; + /* + * TODO: Retire and release can use the same sync point here b/c hwc is + * restricted to one layer. Once that is no longer true, this will need + * to change + */ + ++hd->timeline_next; + display_contents->retireFenceFd = sw_sync_fence_create( + hd->timeline_fd, "drm_hwc_retire", hd->timeline_next); + layer->releaseFenceFd = sw_sync_fence_create( + hd->timeline_fd, "drm_hwc_release", hd->timeline_next); + hd->buf_queue.push_back(buf); - ret = pthread_mutex_lock(&hd->set_worker.lock); - if (ret) { - ALOGE("Failed to lock set lock in set() %d", ret); - goto out; - } + ret = pthread_cond_signal(&hd->set_worker.cond); + if (ret) + ALOGE("Failed to signal set worker %d", ret); - ret = hwc_import_bo_create(ctx->fd, ctx->import_ctx, layer->handle, - &buf); - if (ret) { - ALOGE("Failed to import handle to drm bo %d", ret); - goto out; - } - buf.acquire_fence_fd = layer->acquireFenceFd; - layer->acquireFenceFd = -1; + if (pthread_mutex_unlock(&hd->set_worker.lock)) + ALOGE("Failed to unlock set lock in set()"); - /* - * TODO: Retire and release can use the same sync point here b/c hwc is - * restricted to one layer. Once that is no longer true, this will need - * to change - */ - hd->timeline_next++; - display_contents->retireFenceFd = sw_sync_fence_create(hd->timeline_fd, - "drm_hwc_retire", hd->timeline_next); - layer->releaseFenceFd = sw_sync_fence_create(hd->timeline_fd, - "drm_hwc_release", hd->timeline_next); - hd->buf_queue.push_back(buf); - - ret = pthread_cond_signal(&hd->set_worker.cond); - if (ret) - ALOGE("Failed to signal set worker %d", ret); - - if (pthread_mutex_unlock(&hd->set_worker.lock)) - ALOGE("Failed to unlock set lock in set()"); - -out: - /* Close input fences. */ - for (i = 0; i < (int)display_contents->numHwLayers; i++) { - layer = &display_contents->hwLayers[i]; - if (layer->acquireFenceFd >= 0) { - close(layer->acquireFenceFd); - layer->acquireFenceFd = -1; - } - } - if (display_contents->outbufAcquireFenceFd >= 0) { - close(display_contents->outbufAcquireFenceFd); - display_contents->outbufAcquireFenceFd = -1; - } - - return ret; + hwc_close_fences(display_contents); + return ret; } static int hwc_set(hwc_composer_device_1_t *dev, size_t num_displays, - hwc_display_contents_1_t** display_contents) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - int ret = 0, i; + hwc_display_contents_1_t **display_contents) { + struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - for (i = 0; i < (int)num_displays && i < MAX_NUM_DISPLAYS; i++) { - if (display_contents[i]) - ret = hwc_set_display(ctx, i, display_contents[i]); - } + int ret = 0; + for (int i = 0; i < (int)num_displays && i < MAX_NUM_DISPLAYS; ++i) { + if (display_contents[i]) + ret = hwc_set_display(ctx, i, display_contents[i]); + } - return ret; + return ret; } -static int hwc_event_control(struct hwc_composer_device_1* dev, int display, - int event, int enabled) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - struct hwc_drm_display *hd = NULL; - int ret; +static int hwc_event_control(struct hwc_composer_device_1 *dev, int display, + int event, int enabled) { + 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; - ret = hwc_get_drm_display(ctx, display, &hd); - if (ret) - return ret; + if (event != HWC_EVENT_VSYNC || (enabled != 0 && enabled != 1)) + return -EINVAL; - 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); + return -EINVAL; + } - if (hd->active_pipe == -1) { - ALOGD("Can't service events for display %d, no pipe", display); - return -EINVAL; - } + hd->enable_vsync_events = !!enabled; - hd->enable_vsync_events = !!enabled; + if (!hd->enable_vsync_events) + return 0; - if (!hd->enable_vsync_events) - return 0; + /* + * Note that it's possible that the event worker is already waiting for + * a vsync, and this will be a duplicate request. In that event, we'll + * end up firing the event handler twice, and it will discard the second + * event. Not ideal, but not worth introducing a bunch of additional + * logic/locks/state for. + */ + ret = hwc_queue_vblank_event(hd); + if (ret) { + ALOGE("Failed to queue vblank event ret=%d", ret); + return ret; + } - /* - * Note that it's possible that the event worker is already waiting for - * a vsync, and this will be a duplicate request. In that event, we'll - * end up firing the event handler twice, and it will discard the second - * event. Not ideal, but not worth introducing a bunch of additional - * logic/locks/state for. - */ - ret = hwc_queue_vblank_event(hd); - if (ret) { - ALOGE("Failed to queue vblank event ret=%d", ret); - return ret; - } - - return 0; + return 0; } -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; - drmModeConnectorPtr c; - int ret, i; - uint32_t dpms_prop = 0; - uint64_t dpms_value = 0; +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; - ret = hwc_get_drm_display(ctx, display, &hd); - if (ret) - return ret; + struct hwc_drm_display *hd = NULL; + int ret = hwc_get_drm_display(ctx, display, &hd); + if (ret) + return ret; - c = drmModeGetConnector(ctx->fd, hd->connector_id); - if (!c) { - ALOGE("Failed to get connector %d", display); - return -ENODEV; - } + drmModeConnectorPtr c = drmModeGetConnector(ctx->fd, hd->connector_id); + if (!c) { + ALOGE("Failed to get connector %d", display); + return -ENODEV; + } - for (i = 0; !dpms_prop && i < c->count_props; i++) { - drmModePropertyPtr p; + 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; + p = drmModeGetProperty(ctx->fd, c->props[i]); + if (!p) + continue; - if (!strcmp(p->name, "DPMS")) - dpms_prop = c->props[i]; + 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); - ret = -ENOENT; - goto out; - } + drmModeFreeProperty(p); + } + if (!dpms_prop) { + ALOGE("Failed to get DPMS property from display %d", display); + drmModeFreeConnector(c); + return -ENOENT; + } - switch(mode) { - case HWC_POWER_MODE_OFF: - dpms_value = DRM_MODE_DPMS_OFF; - break; + uint64_t dpms_value = 0; + switch (mode) { + case HWC_POWER_MODE_OFF: + dpms_value = 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; - 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; + break; + }; - ret = drmModeConnectorSetProperty(ctx->fd, c->connector_id, - dpms_prop, dpms_value); - if (ret) { - ALOGE("Failed to set DPMS property for display %d", display); - goto out; - } + 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; + } -out: - drmModeFreeConnector(c); - return ret; + drmModeFreeConnector(c); + return 0; } -static int hwc_query(struct hwc_composer_device_1 */* dev */, int what, - int *value) -{ - switch(what) { - case HWC_BACKGROUND_LAYER_SUPPORTED: - *value = 0; /* TODO: We should do this */ - break; - case HWC_VSYNC_PERIOD: - ALOGW("Query for deprecated vsync value, returning 60Hz"); - *value = 1000 * 1000 * 1000 / 60; - break; - case HWC_DISPLAY_TYPES_SUPPORTED: - *value = HWC_DISPLAY_PRIMARY | HWC_DISPLAY_EXTERNAL; - break; - } - return 0; +static int hwc_query(struct hwc_composer_device_1 * /* dev */, int what, + int *value) { + switch (what) { + case HWC_BACKGROUND_LAYER_SUPPORTED: + *value = 0; /* TODO: We should do this */ + break; + case HWC_VSYNC_PERIOD: + ALOGW("Query for deprecated vsync value, returning 60Hz"); + *value = 1000 * 1000 * 1000 / 60; + break; + case HWC_DISPLAY_TYPES_SUPPORTED: + *value = HWC_DISPLAY_PRIMARY | HWC_DISPLAY_EXTERNAL; + break; + } + return 0; } -static void hwc_register_procs(struct hwc_composer_device_1* dev, - hwc_procs_t const* procs) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; +static void hwc_register_procs(struct hwc_composer_device_1 *dev, + hwc_procs_t const *procs) { + struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - ctx->procs = procs; + ctx->procs = procs; } -static int hwc_get_display_configs(struct hwc_composer_device_1* dev, - int display, uint32_t* configs, size_t* numConfigs) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - struct hwc_drm_display *hd = NULL; - drmModeConnectorPtr c; - int ret = 0, i; +static int hwc_get_display_configs(struct hwc_composer_device_1 *dev, + int display, uint32_t *configs, + size_t *numConfigs) { + if (!*numConfigs) + return 0; - if (!*numConfigs) - return 0; + 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; - 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; + } - 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; + } - if (hd->configs) { - free(hd->configs); - hd->configs = NULL; - } + if (c->connection == DRM_MODE_DISCONNECTED) { + drmModeFreeConnector(c); + return -ENODEV; + } - if (c->connection == DRM_MODE_DISCONNECTED) { - ret = -ENODEV; - goto out; - } + 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; + } - hd->configs = (drmModeModeInfoPtr)calloc(c->count_modes, - sizeof(*hd->configs)); - if (!hd->configs) { - ALOGE("Failed to allocate config list for display %d", display); - ret = -ENOMEM; - hd->num_configs = 0; - goto out; - } + for (int i = 0; i < c->count_modes; ++i) { + drmModeModeInfoPtr m = &hd->configs[i]; - for (i = 0; i < c->count_modes; i++) { - drmModeModeInfoPtr m = &hd->configs[i]; + memcpy(m, &c->modes[i], sizeof(*m)); - memcpy(m, &c->modes[i], sizeof(*m)); + if (i < (int)*numConfigs) + configs[i] = i; + } - if (i < (int)*numConfigs) - configs[i] = i; - } + hd->num_configs = c->count_modes; + *numConfigs = MIN(c->count_modes, *numConfigs); - hd->num_configs = c->count_modes; - *numConfigs = MIN(c->count_modes, *numConfigs); - -out: - drmModeFreeConnector(c); - return ret; + 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; - drmModeModeInfoPtr m = NULL; - int ret = 0, i; + drmModeConnectorPtr connector, int display, + int config_idx) { + struct hwc_drm_display *hd = NULL; + int ret = hwc_get_drm_display(ctx, display, &hd); + if (ret) + return ret; - ret = hwc_get_drm_display(ctx, display, &hd); - if (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]; + break; + } + } + if (!m) + return -ENOENT; - /* Make sure the requested config is still valid for the display */ - for (i = 0; i < connector->count_modes; i++) { - if (hwc_mode_is_equal(&connector->modes[i], - &hd->configs[config_idx])) { - m = &hd->configs[config_idx]; - break; - } - } - if (!m) - return -ENOENT; - - return 0; + return 0; } -static int hwc_get_display_attributes(struct hwc_composer_device_1* dev, - int display, uint32_t config, const uint32_t* attributes, - int32_t* values) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - struct hwc_drm_display *hd = NULL; - drmModeConnectorPtr c; - drmModeModeInfoPtr m; - int ret, i; +static int hwc_get_display_attributes(struct hwc_composer_device_1 *dev, + int display, uint32_t config, + 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; - 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; + } - 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); + if (!c) { + ALOGE("Failed to get connector %d", display); + return -ENODEV; + } - c = drmModeGetConnector(ctx->fd, hd->connector_id); - if (!c) { - ALOGE("Failed to get connector %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; + } - ret = hwc_check_config_valid(ctx, c, display, (int)config); - if (ret) { - ALOGE("Provided config is no longer valid %u", config); - goto out; - } + drmModeModeInfoPtr m = &hd->configs[config]; + 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; + break; + case HWC_DISPLAY_WIDTH: + values[i] = m->hdisplay; + break; + case HWC_DISPLAY_HEIGHT: + values[i] = m->vdisplay; + break; + case HWC_DISPLAY_DPI_X: + /* Dots per 1000 inches */ + values[i] = c->mmWidth ? (m->hdisplay * UM_PER_INCH) / c->mmWidth : 0; + break; + case HWC_DISPLAY_DPI_Y: + /* Dots per 1000 inches */ + values[i] = c->mmHeight ? (m->vdisplay * UM_PER_INCH) / c->mmHeight : 0; + break; + } + } - m = &hd->configs[config]; - for (i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) { - switch(attributes[i]) { - case HWC_DISPLAY_VSYNC_PERIOD: - values[i] = 1000 * 1000 * 1000 / m->vrefresh; - break; - case HWC_DISPLAY_WIDTH: - values[i] = m->hdisplay; - break; - case HWC_DISPLAY_HEIGHT: - values[i] = m->vdisplay; - break; - case HWC_DISPLAY_DPI_X: - /* Dots per 1000 inches */ - values[i] = c->mmWidth ? - (m->hdisplay * UM_PER_INCH) / c->mmWidth : 0; - break; - case HWC_DISPLAY_DPI_Y: - /* Dots per 1000 inches */ - values[i] = c->mmHeight ? - (m->vdisplay * UM_PER_INCH) / c->mmHeight : 0; - break; - } - } - -out: - drmModeFreeConnector(c); - return ret; + drmModeFreeConnector(c); + return 0; } -static int hwc_get_active_config(struct hwc_composer_device_1* dev, int display) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - struct hwc_drm_display *hd = NULL; - int ret, i, index = -1; +static int hwc_get_active_config(struct hwc_composer_device_1 *dev, + int display) { + 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; - ret = hwc_get_drm_display(ctx, display, &hd); - if (ret) - return ret; - - /* Find the current mode in the config list */ - for (i = 0; i < (int)hd->num_configs; i++) { - if (hwc_mode_is_equal(&hd->configs[i], &hd->active_mode)) { - index = i; - break; - } - } - - return index; + /* 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) -{ - int i; - - for (i = 0; i < MAX_NUM_DISPLAYS; i++) { - if (ctx->displays[i].active_crtc == crtc_id) - return true; - } - return false; +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; - int ret, i; + 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); + return -ENODEV; + } - e = drmModeGetEncoder(ctx->fd, encoder_id); - if (!e) { - ALOGE("Failed to get encoder for connector %d", encoder_id); - 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; + } + } - /* First try to use the currently-bound crtc */ - if (e->crtc_id) { - if (!hwc_crtc_is_bound(ctx, e->crtc_id)) { - *crtc_id = e->crtc_id; - ret = 0; - goto out; - } - } + /* 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; - /* Try to find a possible crtc which will work */ - for (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; - /* 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; + } + } - if (!hwc_crtc_is_bound(ctx, r->crtcs[i])) { - *crtc_id = r->crtcs[i]; - ret = 0; - goto out; - } - } - - /* We can't use the encoder, but nothing went wrong, try another one */ - ret = -EAGAIN; - -out: - drmModeFreeEncoder(e); - return ret; + /* We can't use the encoder, but nothing went wrong, try another one */ + drmModeFreeEncoder(e); + return -EAGAIN; } -static int hwc_set_active_config(struct hwc_composer_device_1* dev, int display, - int index) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)&dev->common; - struct hwc_drm_display *hd = NULL; - drmModeResPtr r = NULL; - drmModeConnectorPtr c; - uint32_t crtc_id = 0; - int ret, i; - bool new_crtc, new_encoder; +static int hwc_set_active_config(struct hwc_composer_device_1 *dev, int display, + int index) { + 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; - 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; + } - 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 (c->connection == DRM_MODE_DISCONNECTED) { - ALOGE("Tried to configure a disconnected display %d", display); - ret = -ENODEV; - goto out; - } + if (index >= c->count_modes) { + ALOGE("Index is out-of-bounds %d/%d", index, c->count_modes); + drmModeFreeConnector(c); + return -ENOENT; + } - if (index >= c->count_modes) { - ALOGE("Index is out-of-bounds %d/%d", index, c->count_modes); - ret = -ENOENT; - goto out; - } + drmModeResPtr r = drmModeGetResources(ctx->fd); + if (!r) { + ALOGE("Failed to get drm resources"); + drmModeFreeResources(r); + drmModeFreeConnector(c); + return -ENODEV; + } - r = drmModeGetResources(ctx->fd); - if (!r) { - ALOGE("Failed to get drm resources"); - goto out; - } + /* We no longer have an active_crtc */ + hd->active_crtc = 0; + hd->active_pipe = -1; - /* 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; + } + } - /* First, try to use the currently-connected encoder */ - 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); - goto out; - } - } + /* 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; + } + } + drmModeFreeConnector(c); - /* We couldn't find a crtc with the attached encoder, try the others */ - if (!crtc_id) { - for (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); - goto out; - } - } - if (!crtc_id) { - ALOGE("Couldn't find valid crtc to modeset"); - ret = -EINVAL; - goto out; - } - } + hd->active_crtc = crtc_id; + memcpy(&hd->active_mode, &hd->configs[index], sizeof(hd->active_mode)); - hd->active_crtc = crtc_id; + /* 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; + } - memcpy(&hd->active_mode, &hd->configs[index], sizeof(hd->active_mode)); - - /* Find the pipe corresponding to the crtc_id */ - for (i = 0; i < r->count_crtcs; i++) { - /* We've already tried this earlier */ - if (r->crtcs[i] == crtc_id) { - hd->active_pipe = i; - break; - } - } - /* This should never happen... hehehe */ - if (hd->active_pipe == -1) { - ALOGE("Active crtc was not found in resources!!"); - ret = -ENODEV; - goto out; - } - - /* TODO: Once we have atomic, set the crtc timing info here */ - -out: - if (r) - drmModeFreeResources(r); - - drmModeFreeConnector(c); - return ret; + /* TODO: Once we have atomic, set the crtc timing info here */ + return 0; } -static int hwc_destroy_worker(struct hwc_worker *worker) -{ - int ret; +static int hwc_destroy_worker(struct hwc_worker *worker) { + int ret = pthread_mutex_lock(&worker->lock); + if (ret) { + ALOGE("Failed to lock in destroy() %d", ret); + return ret; + } - ret = pthread_mutex_lock(&worker->lock); - if (ret) { - ALOGE("Failed to lock in destroy() %d", ret); - return ret; - } + worker->exit = true; - worker->exit = true; + ret |= pthread_cond_signal(&worker->cond); + if (ret) + ALOGE("Failed to signal cond in destroy() %d", ret); - ret |= pthread_cond_signal(&worker->cond); - if (ret) - ALOGE("Failed to signal cond in destroy() %d", ret); + ret |= pthread_mutex_unlock(&worker->lock); + if (ret) + ALOGE("Failed to unlock in destroy() %d", ret); - ret |= pthread_mutex_unlock(&worker->lock); - if (ret) - ALOGE("Failed to unlock in destroy() %d", ret); + ret |= pthread_join(worker->thread, NULL); + if (ret && ret != ESRCH) + ALOGE("Failed to join thread in destroy() %d", ret); - ret |= pthread_join(worker->thread, NULL); - if (ret && ret != ESRCH) - ALOGE("Failed to join thread in destroy() %d", ret); - - return ret; + return ret; } -static void hwc_destroy_display(struct hwc_drm_display *hd) -{ - int ret; - - if (hwc_destroy_worker(&hd->set_worker)) - ALOGE("Destroy set worker failed"); +static void hwc_destroy_display(struct hwc_drm_display *hd) { + if (hwc_destroy_worker(&hd->set_worker)) + ALOGE("Destroy set worker failed"); } -static int hwc_device_close(struct hw_device_t *dev) -{ - struct hwc_context_t *ctx = (struct hwc_context_t *)dev; - int ret, i; +static int hwc_device_close(struct hw_device_t *dev) { + struct hwc_context_t *ctx = (struct hwc_context_t *)dev; - for (i = 0; i < MAX_NUM_DISPLAYS; i++) - hwc_destroy_display(&ctx->displays[i]); + for (int i = 0; i < MAX_NUM_DISPLAYS; ++i) + hwc_destroy_display(&ctx->displays[i]); - if (hwc_destroy_worker(&ctx->event_worker)) - ALOGE("Destroy event worker failed"); + if (hwc_destroy_worker(&ctx->event_worker)) + ALOGE("Destroy event worker failed"); - drmClose(ctx->fd); + drmClose(ctx->fd); - ret = hwc_import_destroy(ctx->import_ctx); - if (ret) - ALOGE("Could not destroy import %d", ret); + int ret = hwc_import_destroy(ctx->import_ctx); + if (ret) + ALOGE("Could not destroy import %d", ret); - delete ctx; + delete ctx; - return 0; + return 0; } static int hwc_initialize_worker(struct hwc_worker *worker, - void *(*routine)(void*), void *arg) -{ - int ret; + void *(*routine)(void *), void *arg) { + int ret = pthread_cond_init(&worker->cond, NULL); + if (ret) { + ALOGE("Failed to create worker condition %d", ret); + return ret; + } - ret = pthread_cond_init(&worker->cond, NULL); - if (ret) { - ALOGE("Failed to create worker condition %d", ret); - return ret; - } + ret = pthread_mutex_init(&worker->lock, NULL); + if (ret) { + ALOGE("Failed to initialize worker lock %d", ret); + pthread_cond_destroy(&worker->cond); + return ret; + } - ret = pthread_mutex_init(&worker->lock, NULL); - if (ret) { - ALOGE("Failed to initialize worker lock %d", ret); - goto err_cond; - } + worker->exit = false; - worker->exit = false; - - ret = pthread_create(&worker->thread, NULL, routine, arg); - if (ret) { - ALOGE("Could not create worker thread %d", ret); - goto err_lock; - } - return 0; - -err_lock: - pthread_mutex_destroy(&worker->lock); -err_cond: - pthread_cond_destroy(&worker->cond); - return ret; + ret = pthread_create(&worker->thread, NULL, routine, arg); + if (ret) { + ALOGE("Could not create worker thread %d", ret); + pthread_mutex_destroy(&worker->lock); + pthread_cond_destroy(&worker->cond); + return ret; + } + return 0; } /* @@ -1158,265 +1047,243 @@ err_cond: * should be fixed such that it selects the preferred mode for the display, or * some other, saner, method of choosing the config. */ -static int hwc_set_initial_config(struct hwc_drm_display *hd) -{ - int ret; - uint32_t config; - size_t num_configs = 1; +static int hwc_set_initial_config(struct hwc_drm_display *hd) { + uint32_t config; + size_t num_configs = 1; + int ret = hwc_get_display_configs(&hd->ctx->device, hd->display, &config, + &num_configs); + if (ret || !num_configs) + return 0; - ret = hwc_get_display_configs(&hd->ctx->device, hd->display, &config, - &num_configs); - if (ret || !num_configs) - return 0; + ret = hwc_set_active_config(&hd->ctx->device, hd->display, 0); + if (ret) { + ALOGE("Failed to set active config d=%d ret=%d", hd->display, ret); + return ret; + } - ret = hwc_set_active_config(&hd->ctx->device, hd->display, 0); - if (ret) { - ALOGE("Failed to set active config d=%d ret=%d", hd->display, - ret); - return ret; - } - - return ret; + return ret; } static int hwc_initialize_display(struct hwc_context_t *ctx, int display, - uint32_t connector_id) -{ - struct hwc_drm_display *hd = NULL; - int ret; + uint32_t connector_id) { + struct hwc_drm_display *hd = NULL; + int ret = hwc_get_drm_display(ctx, display, &hd); + if (ret) + return ret; - ret = hwc_get_drm_display(ctx, display, &hd); - if (ret) - return ret; + 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; - 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; + ret = pthread_mutex_init(&hd->flip_lock, NULL); + if (ret) { + ALOGE("Failed to initialize flip lock %d", ret); + return ret; + } - ret = pthread_mutex_init(&hd->flip_lock, NULL); - if (ret) { - ALOGE("Failed to initialize flip lock %d", ret); - return ret; - } + ret = pthread_cond_init(&hd->flip_cond, NULL); + if (ret) { + ALOGE("Failed to intiialize flip condition %d", ret); + pthread_mutex_destroy(&hd->flip_lock); + return ret; + } - ret = pthread_cond_init(&hd->flip_cond, NULL); - if (ret) { - ALOGE("Failed to intiialize flip condition %d", ret); - goto err_flip_lock; - } + ret = sw_sync_timeline_create(); + if (ret < 0) { + ALOGE("Failed to create sw sync timeline %d", ret); + pthread_cond_destroy(&hd->flip_cond); + pthread_mutex_destroy(&hd->flip_lock); + return ret; + } + hd->timeline_fd = ret; - ret = sw_sync_timeline_create(); - if (ret < 0) { - ALOGE("Failed to create sw sync timeline %d", ret); - goto err_flip_cond; - } - hd->timeline_fd = ret; + /* + * Initialize timeline_next to 1, because point 0 will be the very first + * set operation. Since we increment every time set() is called, + * initializing to 0 would cause an off-by-one error where + * surfaceflinger would composite on the front buffer. + */ + hd->timeline_next = 1; - /* - * Initialize timeline_next to 1, because point 0 will be the very first - * set operation. Since we increment every time set() is called, - * initializing to 0 would cause an off-by-one error where - * surfaceflinger would composite on the front buffer. - */ - hd->timeline_next = 1; + ret = hwc_set_initial_config(hd); + if (ret) { + ALOGE("Failed to set initial config for d=%d ret=%d", display, ret); + close(hd->timeline_fd); + pthread_cond_destroy(&hd->flip_cond); + pthread_mutex_destroy(&hd->flip_lock); + return ret; + } - ret = hwc_set_initial_config(hd); - if (ret) { - ALOGE("Failed to set initial config for d=%d ret=%d", display, - ret); - goto err_sync_timeline; - } + ret = hwc_initialize_worker(&hd->set_worker, hwc_set_worker, hd); + if (ret) { + ALOGE("Failed to create set worker %d\n", ret); + close(hd->timeline_fd); + pthread_cond_destroy(&hd->flip_cond); + pthread_mutex_destroy(&hd->flip_lock); + return ret; + } - ret = hwc_initialize_worker(&hd->set_worker, hwc_set_worker, hd); - if (ret) { - ALOGE("Failed to create set worker %d\n", ret); - goto err_sync_timeline; - } - - return 0; - -err_sync_timeline: - close(hd->timeline_fd); - -err_flip_cond: - pthread_cond_destroy(&hd->flip_cond); - -err_flip_lock: - pthread_mutex_destroy(&hd->flip_lock); - - return ret; + return 0; } -static int hwc_enumerate_displays(struct hwc_context_t *ctx) -{ - struct hwc_drm_display *panel_hd; - drmModeResPtr res; - drmModeConnectorPtr *conn_list; - int ret = 0, i, j; - - ret = hwc_initialize_worker(&ctx->event_worker, hwc_event_worker, ctx); - if (ret) { - ALOGE("Failed to create event worker %d\n", ret); - return ret; - } - - res = drmModeGetResources(ctx->fd); - if (!res) { - ALOGE("Failed to get drm resources"); - return -ENODEV; - } - - conn_list = (drmModeConnector **)calloc(res->count_connectors, - sizeof(*conn_list)); - if (!conn_list) { - ALOGE("Failed to allocate connector list"); - ret = -ENOMEM; - goto out; - } - - for (i = 0; i < res->count_connectors; i++) { - conn_list[i] = drmModeGetConnector(ctx->fd, res->connectors[i]); - if (!conn_list[i]) { - ALOGE("Failed to get connector %d", res->connectors[i]); - ret = -ENODEV; - goto out; - } - } - - ctx->num_displays = 0; - - /* Find a connected, panel type connector for display 0 */ - for (i = 0; i < res->count_connectors; i++) { - drmModeConnectorPtr c = conn_list[i]; - - for (j = 0; j < ARRAY_SIZE(panel_types); j++) { - if (c->connector_type == panel_types[j] && - c->connection == DRM_MODE_CONNECTED) - break; - } - if (j == ARRAY_SIZE(panel_types)) - continue; - - hwc_initialize_display(ctx, ctx->num_displays, c->connector_id); - ctx->num_displays++; - break; - } - - ret = hwc_get_drm_display(ctx, 0, &panel_hd); - if (ret) - goto out; - - /* Fill in the other displays */ - for (i = 0; i < res->count_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++; - } - -out: - for (i = 0; i < res->count_connectors; i++) { - if (conn_list[i]) - drmModeFreeConnector(conn_list[i]); - } - free(conn_list); - - if (res) - drmModeFreeResources(res); - - if (ret) - hwc_destroy_worker(&ctx->event_worker); - - return ret; +static void hwc_free_conn_list(drmModeConnectorPtr *conn_list, int num_conn) { + for (int i = 0; i < num_conn; ++i) { + if (conn_list[i]) + drmModeFreeConnector(conn_list[i]); + } + free(conn_list); } -static int hwc_device_open(const struct hw_module_t* module, const char* name, - struct hw_device_t** dev) -{ - int ret = 0; - struct hwc_context_t *ctx; - char path[PROPERTY_VALUE_MAX]; +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; - if (strcmp(name, HWC_HARDWARE_COMPOSER)) { - ALOGE("Invalid module name- %s", name); - return -EINVAL; - } + drmModeConnectorPtr *conn_list = + (drmModeConnector **)calloc(num_connectors, sizeof(*conn_list)); + if (!conn_list) { + ALOGE("Failed to allocate connector list"); + drmModeFreeResources(res); + return -ENOMEM; + } - ctx = new hwc_context_t(); - if (!ctx) { - ALOGE("Failed to allocate hwc context"); - 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); - ret = hwc_import_init(&ctx->import_ctx); - if (ret) { - ALOGE("Failed to initialize import context"); - goto out; - } + ctx->num_displays = 0; - 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)); - goto out; - } + /* Find a connected, panel type connector for display 0 */ + for (int i = 0; i < num_connectors; ++i) { + drmModeConnectorPtr c = conn_list[i]; - ret = hwc_enumerate_displays(ctx); - if (ret) { - ALOGE("Failed to enumerate displays: %s", strerror(ret)); - goto out; - } + int j; + for (j = 0; j < ARRAY_SIZE(panel_types); ++j) { + if (c->connector_type == panel_types[j] && + c->connection == DRM_MODE_CONNECTED) + break; + } + if (j == ARRAY_SIZE(panel_types)) + continue; - ctx->device.common.tag = HARDWARE_DEVICE_TAG; - ctx->device.common.version = HWC_DEVICE_API_VERSION_1_4; - ctx->device.common.module = const_cast(module); - ctx->device.common.close = hwc_device_close; + hwc_initialize_display(ctx, ctx->num_displays, c->connector_id); + ++ctx->num_displays; + break; + } - ctx->device.prepare = hwc_prepare; - ctx->device.set = hwc_set; - ctx->device.eventControl = hwc_event_control; - ctx->device.setPowerMode = hwc_set_power_mode; - ctx->device.query = hwc_query; - ctx->device.registerProcs = hwc_register_procs; - ctx->device.getDisplayConfigs = hwc_get_display_configs; - ctx->device.getDisplayAttributes = hwc_get_display_attributes; - ctx->device.getActiveConfig = hwc_get_active_config; - ctx->device.setActiveConfig = hwc_set_active_config; - ctx->device.setCursorPositionAsync = NULL; /* TODO: Add cursor */ + 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; + } - *dev = &ctx->device.common; + /* Fill in the other displays */ + for (int i = 0; i < num_connectors; ++i) { + drmModeConnectorPtr c = conn_list[i]; - return 0; -out: - if (ctx->fd >= 0) - close(ctx->fd); + if (panel_hd->connector_id == c->connector_id) + continue; - delete ctx; - return ret; + 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; } -static struct hw_module_methods_t hwc_module_methods = { - open: hwc_device_open -}; +static int hwc_device_open(const struct hw_module_t *module, const char *name, + struct hw_device_t **dev) { + if (strcmp(name, HWC_HARDWARE_COMPOSER)) { + ALOGE("Invalid module name- %s", name); + return -EINVAL; + } + + struct hwc_context_t *ctx = new hwc_context_t(); + if (!ctx) { + ALOGE("Failed to allocate hwc context"); + return -ENOMEM; + } + + int ret = hwc_import_init(&ctx->import_ctx); + if (ret) { + ALOGE("Failed to initialize import context"); + 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)); + delete ctx; + return -ENOENT; + } + + ret = hwc_enumerate_displays(ctx); + if (ret) { + ALOGE("Failed to enumerate displays: %s", strerror(ret)); + close(ctx->fd); + delete ctx; + return ret; + } + + ctx->device.common.tag = HARDWARE_DEVICE_TAG; + ctx->device.common.version = HWC_DEVICE_API_VERSION_1_4; + ctx->device.common.module = const_cast(module); + ctx->device.common.close = hwc_device_close; + + ctx->device.prepare = hwc_prepare; + ctx->device.set = hwc_set; + ctx->device.eventControl = hwc_event_control; + ctx->device.setPowerMode = hwc_set_power_mode; + ctx->device.query = hwc_query; + ctx->device.registerProcs = hwc_register_procs; + ctx->device.getDisplayConfigs = hwc_get_display_configs; + ctx->device.getDisplayAttributes = hwc_get_display_attributes; + ctx->device.getActiveConfig = hwc_get_active_config; + ctx->device.setActiveConfig = hwc_set_active_config; + ctx->device.setCursorPositionAsync = NULL; /* TODO: Add cursor */ + + *dev = &ctx->device.common; + + return 0; +} + +static struct hw_module_methods_t hwc_module_methods = {open : hwc_device_open}; hwc_module_t HAL_MODULE_INFO_SYM = { - common: { - tag: HARDWARE_MODULE_TAG, - version_major: 1, - version_minor: 0, - id: HWC_HARDWARE_MODULE_ID, - name: "DRM hwcomposer module", - author: "The Android Open Source Project", - methods: &hwc_module_methods, - dso: NULL, - reserved: { 0 }, - } + common : { + tag : HARDWARE_MODULE_TAG, + version_major : 1, + version_minor : 0, + id : HWC_HARDWARE_MODULE_ID, + name : "DRM hwcomposer module", + author : "The Android Open Source Project", + methods : &hwc_module_methods, + dso : NULL, + reserved : {0}, + } }; diff --git a/hwcomposer_import_drm_gralloc.cpp b/hwcomposer_import_drm_gralloc.cpp index b724c83..5958f57 100644 --- a/hwcomposer_import_drm_gralloc.cpp +++ b/hwcomposer_import_drm_gralloc.cpp @@ -27,115 +27,98 @@ #include "drm_hwcomposer.h" struct hwc_import_context { - struct drm_module_t *gralloc_module; + struct drm_module_t *gralloc_module; }; -int hwc_import_init(struct hwc_import_context **ctx) -{ - int ret; - struct hwc_import_context *import_ctx; +int hwc_import_init(struct hwc_import_context **ctx) { + struct hwc_import_context *import_ctx; - import_ctx = (struct hwc_import_context *)calloc(1, - sizeof(*import_ctx)); - if (!ctx) { - ALOGE("Failed to allocate gralloc import context"); - return -ENOMEM; - } + import_ctx = (struct hwc_import_context *)calloc(1, sizeof(*import_ctx)); + if (!ctx) { + ALOGE("Failed to allocate gralloc import context"); + return -ENOMEM; + } - ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, - (const hw_module_t **)&import_ctx->gralloc_module); - if (ret) { - ALOGE("Failed to open gralloc module"); - goto err; - } + int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, + (const hw_module_t **)&import_ctx->gralloc_module); + if (ret) { + ALOGE("Failed to open gralloc module"); + free(import_ctx); + return ret; + } - *ctx = import_ctx; + *ctx = import_ctx; - return 0; - -err: - free(import_ctx); - return ret; + return 0; } -int hwc_import_destroy(struct hwc_import_context *ctx) -{ - free(ctx); - return 0; +int hwc_import_destroy(struct hwc_import_context *ctx) { + free(ctx); + return 0; } -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; - } +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; + } } int hwc_import_bo_create(int fd, hwc_import_context *ctx, - buffer_handle_t handle, struct hwc_drm_bo *bo) -{ - gralloc_drm_handle_t *gr_handle = gralloc_drm_handle(handle); - struct gralloc_drm_bo_t *gralloc_bo; - uint32_t gem_handle; - int ret; + buffer_handle_t handle, struct hwc_drm_bo *bo) { + gralloc_drm_handle_t *gr_handle = gralloc_drm_handle(handle); + if (!gr_handle) + return -EINVAL; - if (!gr_handle) - return -EINVAL; + struct gralloc_drm_bo_t *gralloc_bo = gr_handle->data; + if (!gralloc_bo) { + ALOGE("Could not get drm bo from handle"); + return -EINVAL; + } - gralloc_bo = gr_handle->data; - if (!gralloc_bo) { - ALOGE("Could not get drm bo from handle"); - return -EINVAL; - } + uint32_t gem_handle; + int ret = drmPrimeFDToHandle(fd, gr_handle->prime_fd, &gem_handle); + if (ret) { + ALOGE("failed to import prime fd %d ret=%d", gr_handle->prime_fd, ret); + return ret; + } - ret = drmPrimeFDToHandle(fd, gr_handle->prime_fd, &gem_handle); - if (ret) { - ALOGE("failed to import prime fd %d ret=%d", - gr_handle->prime_fd, ret); - return ret; - } + 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] = gem_handle; + bo->offsets[0] = 0; - 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] = gem_handle; - bo->offsets[0] = 0; + ret = drmModeAddFB2(fd, bo->width, bo->height, bo->format, bo->gem_handles, + bo->pitches, bo->offsets, &bo->fb_id, 0); + if (ret) { + ALOGE("could not create drm fb %d", ret); + return ret; + } - ret = drmModeAddFB2(fd, bo->width, bo->height, bo->format, - bo->gem_handles, bo->pitches, bo->offsets, - &bo->fb_id, 0); - if (ret) { - ALOGE("could not create drm fb %d", ret); - return ret; - } - - return ret; + return ret; } -bool hwc_import_bo_release(int fd, hwc_import_context *ctx, - struct hwc_drm_bo *bo) -{ - (void)ctx; +bool hwc_import_bo_release(int fd, hwc_import_context */* ctx */, + struct hwc_drm_bo *bo) { + if (bo->fb_id) + if (drmModeRmFB(fd, bo->fb_id)) + ALOGE("Failed to rm fb"); - if (bo->fb_id) - if (drmModeRmFB(fd, bo->fb_id)) - ALOGE("Failed to rm fb"); - - /* hwc may close the gem handles now. */ - return true; + /* hwc may close the gem handles now. */ + return true; } diff --git a/hwcomposer_import_nv_gralloc.cpp b/hwcomposer_import_nv_gralloc.cpp index c9c265d..ef6bdb2 100644 --- a/hwcomposer_import_nv_gralloc.cpp +++ b/hwcomposer_import_nv_gralloc.cpp @@ -15,7 +15,6 @@ * limitations under the License. */ - #include #include @@ -27,146 +26,128 @@ #define ARRAY_SIZE(arr) (int)(sizeof(arr) / sizeof((arr)[0])) struct hwc_import_context { - const gralloc_module_t *gralloc_module; + const gralloc_module_t *gralloc_module; }; -int hwc_import_init(struct hwc_import_context **ctx) -{ - int ret; - struct hwc_import_context *import_ctx; +int hwc_import_init(struct hwc_import_context **ctx) { + struct hwc_import_context *import_ctx = (struct hwc_import_context *)calloc(1, sizeof(*import_ctx)); + if (!ctx) { + ALOGE("Failed to allocate gralloc import context"); + return -ENOMEM; + } - import_ctx = (struct hwc_import_context *)calloc(1, - sizeof(*import_ctx)); - if (!ctx) { - ALOGE("Failed to allocate gralloc import context"); - return -ENOMEM; - } + int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, + (const hw_module_t **)&import_ctx->gralloc_module); + if (ret) { + ALOGE("Failed to open gralloc module"); + free(import_ctx); + return ret; + } - ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, - (const hw_module_t **)&import_ctx->gralloc_module); - if (ret) { - ALOGE("Failed to open gralloc module"); - goto err; - } + if (!strcasecmp(import_ctx->gralloc_module->common.author, "NVIDIA")) + ALOGW("Using non-NVIDIA gralloc module: %s\n", + import_ctx->gralloc_module->common.name); - if (!strcasecmp(import_ctx->gralloc_module->common.author, "NVIDIA")) - ALOGW("Using non-NVIDIA gralloc module: %s\n", - import_ctx->gralloc_module->common.name); + *ctx = import_ctx; - *ctx = import_ctx; - - return 0; - -err: - free(import_ctx); - return ret; + return 0; } -int hwc_import_destroy(struct hwc_import_context *ctx) -{ - free(ctx); - return 0; +int hwc_import_destroy(struct hwc_import_context *ctx) { + free(ctx); + return 0; } -struct importer_priv -{ - int drm_fd; - struct hwc_drm_bo bo; +struct importer_priv { + int drm_fd; + struct hwc_drm_bo bo; }; -static void free_priv(void *p) -{ - struct importer_priv *priv = (struct importer_priv *)p; - struct drm_gem_close gem_close; - int i, ret; +static void free_priv(void *p) { + struct importer_priv *priv = (struct importer_priv *)p; + if (priv->bo.fb_id) { + int ret = drmModeRmFB(priv->drm_fd, priv->bo.fb_id); + if (ret) + ALOGE("Failed to rm fb %d", ret); + } - if (priv->bo.fb_id) { - ret = drmModeRmFB(priv->drm_fd, priv->bo.fb_id); - if (ret) - ALOGE("Failed to rm fb %d", ret); - } + struct drm_gem_close gem_close; + memset(&gem_close, 0, sizeof(gem_close)); + for (int i = 0; i < ARRAY_SIZE(priv->bo.gem_handles); i++) { + if (!priv->bo.gem_handles[i]) + continue; + gem_close.handle = priv->bo.gem_handles[i]; + int ret = drmIoctl(priv->drm_fd, DRM_IOCTL_GEM_CLOSE, &gem_close); + if (ret) + ALOGE("Failed to close gem handle %d", ret); + } - memset(&gem_close, 0, sizeof(gem_close)); - for (i = 0; i < ARRAY_SIZE(priv->bo.gem_handles); i++) { - if (!priv->bo.gem_handles[i]) - continue; - gem_close.handle = priv->bo.gem_handles[i]; - ret = drmIoctl(priv->drm_fd, DRM_IOCTL_GEM_CLOSE, &gem_close); - if (ret) - ALOGE("Failed to close gem handle %d", ret); - } - - free(priv); + free(priv); } -static int -hwc_import_set_priv(hwc_import_context *ctx, buffer_handle_t handle, struct importer_priv *priv) -{ - int ret; - const gralloc_module_t *g = ctx->gralloc_module; - - return g->perform(g, GRALLOC_MODULE_PERFORM_SET_IMPORTER_PRIVATE, handle, free_priv, priv); +static int hwc_import_set_priv(hwc_import_context *ctx, buffer_handle_t handle, + struct importer_priv *priv) { + const gralloc_module_t *g = ctx->gralloc_module; + return g->perform(g, GRALLOC_MODULE_PERFORM_SET_IMPORTER_PRIVATE, handle, + free_priv, priv); } -static struct importer_priv * -hwc_import_get_priv(hwc_import_context *ctx, buffer_handle_t handle) -{ - int ret; - void *priv = NULL; - const gralloc_module_t *g = ctx->gralloc_module; - - ret = g->perform(g, GRALLOC_MODULE_PERFORM_GET_IMPORTER_PRIVATE, handle, free_priv, &priv); - return ret ? NULL : (struct importer_priv *)priv; +static struct importer_priv *hwc_import_get_priv(hwc_import_context *ctx, + buffer_handle_t handle) { + const gralloc_module_t *g = ctx->gralloc_module; + void *priv = NULL; + int ret = g->perform(g, GRALLOC_MODULE_PERFORM_GET_IMPORTER_PRIVATE, handle, + free_priv, &priv); + return ret ? NULL : (struct importer_priv *)priv; } int hwc_import_bo_create(int fd, hwc_import_context *ctx, - buffer_handle_t handle, struct hwc_drm_bo *bo) -{ - int ret = 0; - const gralloc_module_t *g = ctx->gralloc_module; + buffer_handle_t handle, struct hwc_drm_bo *bo) { + /* Get imported bo that is cached in gralloc buffer, or create a new one. */ + struct importer_priv *priv = hwc_import_get_priv(ctx, handle); + if (priv) { + *bo = priv->bo; + return 0; + } - /* Get imported bo that is cached in gralloc buffer, or create a new one. */ - struct importer_priv *priv = hwc_import_get_priv(ctx, handle); - if (!priv) { - priv = (struct importer_priv *)calloc(1, sizeof(*priv)); - if (!priv) - return -ENOMEM; - priv->drm_fd = fd; + priv = (struct importer_priv *)calloc(1, sizeof(*priv)); + if (!priv) + return -ENOMEM; + priv->drm_fd = fd; - ret = g->perform(g, GRALLOC_MODULE_PERFORM_DRM_IMPORT, fd, handle, &priv->bo); - if (ret) { - ALOGE("GRALLOC_MODULE_PERFORM_DRM_IMPORT failed %d", ret); - free_priv(priv); - return ret; - } + const gralloc_module_t *g = ctx->gralloc_module; + int ret = + g->perform(g, GRALLOC_MODULE_PERFORM_DRM_IMPORT, fd, handle, &priv->bo); + if (ret) { + ALOGE("GRALLOC_MODULE_PERFORM_DRM_IMPORT failed %d", ret); + free_priv(priv); + return ret; + } - ret = drmModeAddFB2(fd, priv->bo.width, priv->bo.height, - priv->bo.format, priv->bo.gem_handles, - priv->bo.pitches, priv->bo.offsets, - &priv->bo.fb_id, 0); - if (ret) { - ALOGE("Failed to add fb %d", ret); - free_priv(priv); - return ret; - } + ret = drmModeAddFB2(fd, priv->bo.width, priv->bo.height, priv->bo.format, + priv->bo.gem_handles, priv->bo.pitches, + priv->bo.offsets, &priv->bo.fb_id, 0); + if (ret) { + ALOGE("Failed to add fb %d", ret); + free_priv(priv); + return ret; + } - ret = hwc_import_set_priv(ctx, handle, priv); - if (ret) { - /* This will happen is persist.tegra.gpu_mapping_cache is 0/off, - * or if NV gralloc runs out of "priv slots" (currently 3 per buffer, - * only one of which should be used by drm_hwcomposer). */ - ALOGE("Failed to register free callback for imported buffer %d", ret); - free_priv(priv); - return ret; - } - } - *bo = priv->bo; - return ret; + ret = hwc_import_set_priv(ctx, handle, priv); + if (ret) { + /* This will happen is persist.tegra.gpu_mapping_cache is 0/off, + * or if NV gralloc runs out of "priv slots" (currently 3 per buffer, + * only one of which should be used by drm_hwcomposer). */ + ALOGE("Failed to register free callback for imported buffer %d", ret); + free_priv(priv); + return ret; + } + *bo = priv->bo; + return ret; } bool hwc_import_bo_release(int fd, hwc_import_context *ctx, - struct hwc_drm_bo *bo) -{ - /* hwc may not close the gem handles, we own them */ - return false; + struct hwc_drm_bo *bo) { + /* hwc may not close the gem handles, we own them */ + return false; }