diff options
author | Sean Paul <seanpaul@chromium.org> | 2015-01-21 15:12:57 -0500 |
---|---|---|
committer | Tomasz Figa <tfiga@google.com> | 2015-05-30 15:51:00 +0900 |
commit | d81a9375614e30376947013d24cea546d39e93fc (patch) | |
tree | c696e24e75a282e1de1c1c33c4ad4fe42453e198 | |
parent | 5eeaf6970ee63bffe221da91bddeafcbb8405c78 (diff) | |
download | drm_gralloc-d81a9375614e30376947013d24cea546d39e93fc.tar.gz |
drm_gralloc: Remove kms functionality
All of the kms functionality in gralloc should be handled
by hwcomposer.
Change-Id: I164a0af4d03aa4777e494e401cd81e841d3bfa33
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Tomasz Figa <tfiga@google.com>
-rw-r--r-- | Android.mk | 3 | ||||
-rw-r--r-- | gralloc.c | 110 | ||||
-rw-r--r-- | gralloc_drm.c | 5 | ||||
-rw-r--r-- | gralloc_drm.h | 20 | ||||
-rw-r--r-- | gralloc_drm_handle.h | 2 | ||||
-rw-r--r-- | gralloc_drm_intel.c | 174 | ||||
-rw-r--r-- | gralloc_drm_kms.c | 1256 | ||||
-rw-r--r-- | gralloc_drm_nouveau.c | 22 | ||||
-rw-r--r-- | gralloc_drm_pipe.c | 79 | ||||
-rw-r--r-- | gralloc_drm_priv.h | 108 | ||||
-rw-r--r-- | gralloc_drm_radeon.c | 20 |
11 files changed, 10 insertions, 1789 deletions
@@ -82,8 +82,7 @@ LOCAL_MODULE := libgralloc_drm LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := \ - gralloc_drm.c \ - gralloc_drm_kms.c + gralloc_drm.c LOCAL_C_INCLUDES := \ external/libdrm \ @@ -33,9 +33,9 @@ #include "gralloc_drm_priv.h" /* - * Initialize the DRM device object, optionally with KMS. + * Initialize the DRM device object */ -static int drm_init(struct drm_module_t *dmod, int kms) +static int drm_init(struct drm_module_t *dmod) { int err = 0; @@ -45,8 +45,6 @@ static int drm_init(struct drm_module_t *dmod, int kms) if (!dmod->drm) err = -EINVAL; } - if (!err && kms) - err = gralloc_drm_init_kms(dmod->drm); pthread_mutex_unlock(&dmod->mutex); return err; @@ -58,7 +56,7 @@ static int drm_mod_perform(const struct gralloc_module_t *mod, int op, ...) va_list args; int err; - err = drm_init(dmod, 0); + err = drm_init(dmod); if (err) return err; @@ -110,7 +108,7 @@ static int drm_mod_register_buffer(const gralloc_module_t *mod, struct drm_module_t *dmod = (struct drm_module_t *) mod; int err; - err = drm_init(dmod, 0); + err = drm_init(dmod); if (err) return err; @@ -189,15 +187,6 @@ static int drm_mod_alloc_gpu0(alloc_device_t *dev, if (!bo) return -ENOMEM; - if (gralloc_drm_bo_need_fb(bo)) { - err = gralloc_drm_bo_add_fb(bo); - if (err) { - ALOGE("failed to add fb"); - gralloc_drm_bo_decref(bo); - return err; - } - } - *handle = gralloc_drm_bo_get_handle(bo, stride); /* in pixels */ *stride /= bpp; @@ -210,7 +199,7 @@ static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev) struct alloc_device_t *alloc; int err; - err = drm_init(dmod, 0); + err = drm_init(dmod); if (err) return err; @@ -231,90 +220,6 @@ static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev) return 0; } -static int drm_mod_close_fb0(struct hw_device_t *dev) -{ - struct framebuffer_device_t *fb = (struct framebuffer_device_t *) dev; - - free(fb); - - return 0; -} - -static int drm_mod_set_swap_interval_fb0(struct framebuffer_device_t *fb, - int interval) -{ - if (interval < fb->minSwapInterval || interval > fb->maxSwapInterval) - return -EINVAL; - return 0; -} - -static int drm_mod_post_fb0(struct framebuffer_device_t *fb, - buffer_handle_t handle) -{ - struct drm_module_t *dmod = (struct drm_module_t *) fb->common.module; - struct gralloc_drm_bo_t *bo; - - bo = gralloc_drm_bo_from_handle(handle); - if (!bo) - return -EINVAL; - - return gralloc_drm_bo_post(bo); -} - -#include <GLES/gl.h> -static int drm_mod_composition_complete_fb0(struct framebuffer_device_t *fb) -{ - struct drm_module_t *dmod = (struct drm_module_t *) fb->common.module; - - if (gralloc_drm_is_kms_pipelined(dmod->drm)) - glFlush(); - else - glFinish(); - - return 0; -} - -static int drm_mod_open_fb0(struct drm_module_t *dmod, struct hw_device_t **dev) -{ - struct framebuffer_device_t *fb; - int err; - - err = drm_init(dmod, 1); - if (err) - return err; - - fb = calloc(1, sizeof(*fb)); - if (!fb) - return -ENOMEM; - - fb->common.tag = HARDWARE_DEVICE_TAG; - fb->common.version = 0; - fb->common.module = &dmod->base.common; - fb->common.close = drm_mod_close_fb0; - - fb->setSwapInterval = drm_mod_set_swap_interval_fb0; - fb->post = drm_mod_post_fb0; - fb->compositionComplete = drm_mod_composition_complete_fb0; - - gralloc_drm_get_kms_info(dmod->drm, fb); - - *dev = &fb->common; - - ALOGI("mode.hdisplay %d\n" - "mode.vdisplay %d\n" - "mode.vrefresh %f\n" - "format 0x%x\n" - "xdpi %f\n" - "ydpi %f\n", - fb->width, - fb->height, - fb->fps, - fb->format, - fb->xdpi, fb->ydpi); - - return 0; -} - static int drm_mod_open(const struct hw_module_t *mod, const char *name, struct hw_device_t **dev) { @@ -323,8 +228,6 @@ static int drm_mod_open(const struct hw_module_t *mod, if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0) err = drm_mod_open_gpu0(dmod, dev); - else if (strcmp(name, GRALLOC_HARDWARE_FB0) == 0) - err = drm_mod_open_fb0(dmod, dev); else err = -EINVAL; @@ -352,9 +255,6 @@ struct drm_module_t HAL_MODULE_INFO_SYM = { .unlock = drm_mod_unlock, .perform = drm_mod_perform }, - .hwc_reserve_plane = gralloc_drm_reserve_plane, - .hwc_disable_planes = gralloc_drm_disable_planes, - .hwc_set_plane_handle = gralloc_drm_set_plane_handle, .mutex = PTHREAD_MUTEX_INITIALIZER, .drm = NULL diff --git a/gralloc_drm.c b/gralloc_drm.c index 31ac988..e74b423 100644 --- a/gralloc_drm.c +++ b/gralloc_drm.c @@ -263,7 +263,6 @@ static struct gralloc_drm_handle_t *create_bo_handle(int width, handle->height = height; handle->format = format; handle->usage = usage; - handle->plane_mask = 0; return handle; } @@ -281,8 +280,6 @@ struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, if (!handle) return NULL; - handle->plane_mask = planes_for_format(drm, format); - bo = drm->drv->alloc(drm->drv, handle); if (!bo) { free(handle); @@ -313,8 +310,6 @@ static void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo) if (bo->refcount) return; - gralloc_drm_bo_rm_fb(bo); - bo->drm->drv->free(bo->drm->drv, bo); if (imported) { handle->data_owner = 0; diff --git a/gralloc_drm.h b/gralloc_drm.h index 773b5fe..e1b50fc 100644 --- a/gralloc_drm.h +++ b/gralloc_drm.h @@ -45,13 +45,6 @@ int gralloc_drm_auth_magic(struct gralloc_drm_t *drm, int32_t magic); int gralloc_drm_set_master(struct gralloc_drm_t *drm); void gralloc_drm_drop_master(struct gralloc_drm_t *drm); -int gralloc_drm_init_kms(struct gralloc_drm_t *drm); -void gralloc_drm_fini_kms(struct gralloc_drm_t *drm); -int gralloc_drm_is_kms_initialized(struct gralloc_drm_t *drm); - -void gralloc_drm_get_kms_info(struct gralloc_drm_t *drm, struct framebuffer_device_t *fb); -int gralloc_drm_is_kms_pipelined(struct gralloc_drm_t *drm); - static inline int gralloc_drm_get_bpp(int format) { int bpp; @@ -129,19 +122,6 @@ unsigned int planes_for_format(struct gralloc_drm_t *drm, int hal_format); int gralloc_drm_bo_lock(struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, int enable_write, void **addr); void gralloc_drm_bo_unlock(struct gralloc_drm_bo_t *bo); -int gralloc_drm_bo_need_fb(const struct gralloc_drm_bo_t *bo); -int gralloc_drm_bo_add_fb(struct gralloc_drm_bo_t *bo); -void gralloc_drm_bo_rm_fb(struct gralloc_drm_bo_t *bo); -int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo); - -int gralloc_drm_reserve_plane(struct gralloc_drm_t *drm, - buffer_handle_t handle, uint32_t id, - uint32_t dst_x, uint32_t dst_y, uint32_t dst_w, uint32_t dst_h, - uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h); -void gralloc_drm_disable_planes(struct gralloc_drm_t *mod); -int gralloc_drm_set_plane_handle(struct gralloc_drm_t *drm, - uint32_t id, buffer_handle_t handle); - #ifdef __cplusplus } #endif diff --git a/gralloc_drm_handle.h b/gralloc_drm_handle.h index 7fc4746..6bf2d2f 100644 --- a/gralloc_drm_handle.h +++ b/gralloc_drm_handle.h @@ -46,8 +46,6 @@ struct gralloc_drm_handle_t { int format; int usage; - unsigned int plane_mask; /* planes that support handle */ - int name; /* the name of the bo */ int stride; /* the stride in bytes */ diff --git a/gralloc_drm_intel.c b/gralloc_drm_intel.c index 3a020b4..53cceff 100644 --- a/gralloc_drm_intel.c +++ b/gralloc_drm_intel.c @@ -238,131 +238,6 @@ static void intel_resolve_format(struct gralloc_drm_drv_t *drv, } } - -static void intel_blit(struct gralloc_drm_drv_t *drv, - struct gralloc_drm_bo_t *dst, - struct gralloc_drm_bo_t *src, - uint16_t dst_x1, uint16_t dst_y1, - uint16_t dst_x2, uint16_t dst_y2, - uint16_t src_x1, uint16_t src_y1, - uint16_t src_x2, uint16_t src_y2) -{ - struct intel_info *info = (struct intel_info *) drv; - struct intel_buffer *dst_ib = (struct intel_buffer *) dst; - struct intel_buffer *src_ib = (struct intel_buffer *) src; - drm_intel_bo *bo_table[3]; - uint32_t cmd, br13, dst_pitch, src_pitch; - - /* - * XY_SRC_COPY_BLT_CMD does not support scaling, - * rectangle dimensions much match - */ - if (src_x2 - src_x1 != dst_x2 - dst_x1 || - src_y2 - src_y1 != dst_y2 - dst_y1) { - ALOGE("%s, src and dst rect must match", __func__); - return; - } - - if (dst->handle->format != src->handle->format) { - ALOGE("%s, src and dst format must match", __func__); - return; - } - - /* nothing to blit */ - if (src_x2 <= src_x1 || src_y2 <= src_y1) - return; - - /* clamp x2, y2 to surface size */ - if (src_x2 > src->handle->width) - src_x2 = src->handle->width; - if (src_y2 > src->handle->height) - src_y2 = src->handle->height; - - if (dst_x2 > dst->handle->width) - dst_x2 = dst->handle->width; - if (dst_y2 > dst->handle->height) - dst_y2 = dst->handle->height; - - bo_table[0] = info->batch_ibo; - bo_table[1] = src_ib->ibo; - bo_table[2] = dst_ib->ibo; - if (drm_intel_bufmgr_check_aperture_space(bo_table, 3)) { - if (batch_flush(info)) - return; - assert(!drm_intel_bufmgr_check_aperture_space(bo_table, 3)); - } - - cmd = XY_SRC_COPY_BLT_CMD; - br13 = 0xcc << 16; /* ROP_S/GXcopy */ - dst_pitch = dst->handle->stride; - src_pitch = src->handle->stride; - - /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to - * drop the low bits. - */ - if (src_pitch % 4 != 0 || dst_pitch % 4 != 0) { - ALOGE("%s, src and dst pitch must be dword aligned", __func__); - return; - } - - switch (gralloc_drm_get_bpp(dst->handle->format)) { - case 1: - break; - case 2: - br13 |= (1 << 24); - break; - case 4: - br13 |= (1 << 24) | (1 << 25); - cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; - break; - default: - ALOGE("%s, copy with unsupported format", __func__); - return; - } - - if (info->gen >= 40) { - if (dst_ib->tiling != I915_TILING_NONE) { - assert(dst_pitch % 512 == 0); - dst_pitch >>= 2; - cmd |= XY_SRC_COPY_BLT_DST_TILED; - } - if (src_ib->tiling != I915_TILING_NONE) { - assert(src_pitch % 512 == 0); - src_pitch >>= 2; - cmd |= XY_SRC_COPY_BLT_SRC_TILED; - } - } - - if (batch_reserve(info, 8)) - return; - - batch_dword(info, cmd); - batch_dword(info, br13 | (uint16_t)dst_pitch); - batch_dword(info, (dst_y1 << 16) | dst_x1); - batch_dword(info, (dst_y2 << 16) | dst_x2); - batch_reloc(info, dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); - batch_dword(info, (src_y1 << 16) | src_x1); - batch_dword(info, (uint16_t)src_pitch); - batch_reloc(info, src, I915_GEM_DOMAIN_RENDER, 0); - - if (info->gen >= 60) { - batch_reserve(info, 4); - batch_dword(info, MI_FLUSH_DW | 2); - batch_dword(info, 0); - batch_dword(info, 0); - batch_dword(info, 0); - } - else { - int flags = (info->gen >= 40) ? 0 : - MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE; - - batch_reserve(info, 1); - batch_dword(info, MI_FLUSH | flags); - } - - batch_flush(info); -} - static drm_intel_bo *alloc_ibo(struct intel_info *info, const struct gralloc_drm_handle_t *handle, uint32_t *tiling, unsigned long *stride) @@ -560,42 +435,21 @@ static void intel_unmap(struct gralloc_drm_drv_t *drv, } #include "intel_chipset.h" /* for platform detection macros */ -static void intel_init_kms_features(struct gralloc_drm_drv_t *drv, - struct gralloc_drm_t *drm) +static void gen_init(struct intel_info *info) { - struct intel_info *info = (struct intel_info *) drv; struct drm_i915_getparam gp; int pageflipping, id, has_blt; - switch (drm->primary.fb_format) { - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGB_565: - break; - default: - drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888; - break; - } - - drm->mode_quirk_vmwgfx = 0; - /* why? */ - drm->mode_sync_flip = 1; - - memset(&gp, 0, sizeof(gp)); - gp.param = I915_PARAM_HAS_PAGEFLIPPING; - gp.value = &pageflipping; - if (drmCommandWriteRead(drm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp))) - pageflipping = 0; - memset(&gp, 0, sizeof(gp)); gp.param = I915_PARAM_CHIPSET_ID; gp.value = &id; - if (drmCommandWriteRead(drm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp))) + if (drmCommandWriteRead(info->fd, DRM_I915_GETPARAM, &gp, sizeof(gp))) id = 0; memset(&gp, 0, sizeof(gp)); gp.param = I915_PARAM_HAS_BLT; gp.value = &has_blt; - if (drmCommandWriteRead(drm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp))) + if (drmCommandWriteRead(info->fd, DRM_I915_GETPARAM, &gp, sizeof(gp))) has_blt = 0; info->exec_blt = has_blt ? I915_EXEC_BLT : 0; @@ -613,25 +467,6 @@ static void intel_init_kms_features(struct gralloc_drm_drv_t *drv, else { info->gen = 30; } - - if (pageflipping && info->gen > 30) - drm->swap_mode = DRM_SWAP_FLIP; - else if (info->batch && info->gen == 30) - drm->swap_mode = DRM_SWAP_COPY; - else - drm->swap_mode = DRM_SWAP_SETCRTC; - - if (drm->resources) { - int pipe; - - pipe = drm_intel_get_pipe_from_crtc_id(info->bufmgr, - drm->primary.crtc_id); - drm->swap_interval = (pipe >= 0) ? 1 : 0; - drm->vblank_secondary = (pipe > 0); - } - else { - drm->swap_interval = 0; - } } static void intel_destroy(struct gralloc_drm_drv_t *drv) @@ -662,14 +497,13 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd) } batch_init(info); + gen_init(info); info->base.destroy = intel_destroy; - info->base.init_kms_features = intel_init_kms_features; info->base.alloc = intel_alloc; info->base.free = intel_free; info->base.map = intel_map; info->base.unmap = intel_unmap; - info->base.blit = intel_blit; info->base.resolve_format = intel_resolve_format; return &info->base; diff --git a/gralloc_drm_kms.c b/gralloc_drm_kms.c deleted file mode 100644 index a4f1198..0000000 --- a/gralloc_drm_kms.c +++ /dev/null @@ -1,1256 +0,0 @@ -/* - * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com> - * Copyright (C) 2010-2011 LunarG Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#define LOG_TAG "GRALLOC-KMS" - -#include <cutils/properties.h> -#include <cutils/log.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <poll.h> -#include <math.h> -#include "gralloc_drm.h" -#include "gralloc_drm_priv.h" -#include <hardware_legacy/uevent.h> - -#include <drm_fourcc.h> - -/* - * Return true if a bo needs fb. - */ -int gralloc_drm_bo_need_fb(const struct gralloc_drm_bo_t *bo) -{ - return ((bo->handle->usage & GRALLOC_USAGE_HW_FB) && - bo->drm->swap_mode != DRM_SWAP_COPY); -} - -static unsigned int drm_format_from_hal(int hal_format) -{ - switch(hal_format) { - case HAL_PIXEL_FORMAT_RGB_888: - case HAL_PIXEL_FORMAT_BGRA_8888: - return DRM_FORMAT_XRGB8888; - case HAL_PIXEL_FORMAT_RGBX_8888: - return DRM_FORMAT_XBGR8888; - case HAL_PIXEL_FORMAT_RGBA_8888: - return DRM_FORMAT_RGBA8888; - case HAL_PIXEL_FORMAT_RGB_565: - return DRM_FORMAT_RGB565; - case HAL_PIXEL_FORMAT_YV12: - return DRM_FORMAT_YUV420; - default: - return 0; - } -} - -/* - * Modify pitches, offsets and handles according to - * the format and return corresponding drm format value - */ -static int resolve_drm_format(struct gralloc_drm_bo_t *bo, - uint32_t *pitches, uint32_t *offsets, uint32_t *handles) -{ - struct gralloc_drm_t *drm = bo->drm; - - pitches[0] = bo->handle->stride; - handles[0] = bo->fb_handle; - - /* driver takes care of HW specific padding, alignment etc. */ - if (drm->drv->resolve_format) - drm->drv->resolve_format(drm->drv, bo, - pitches, offsets, handles); - - return drm_format_from_hal(bo->handle->format); -} - -/* - * Returns planes that are supported for a particular format - */ -unsigned int planes_for_format(struct gralloc_drm_t *drm, - int hal_format) -{ - unsigned int i, j, mask = 0; - unsigned int drm_format = drm_format_from_hal(hal_format); - struct gralloc_drm_plane_t *plane = drm->planes; - - /* no planes available */ - if (!plane) - return 0; - - /* iterate through planes, mark those that match format */ - for (i=0; i<drm->plane_resources->count_planes; i++, plane++) - for (j=0; j<plane->drm_plane->count_formats; j++) - if (plane->drm_plane->formats[j] == drm_format) - mask |= (1U << plane->drm_plane->plane_id); - - return mask; -} - -/* - * Add a fb object for a bo. - */ -int gralloc_drm_bo_add_fb(struct gralloc_drm_bo_t *bo) -{ - uint32_t pitches[4] = { 0, 0, 0, 0 }; - uint32_t offsets[4] = { 0, 0, 0, 0 }; - uint32_t handles[4] = { 0, 0, 0, 0 }; - - if (bo->fb_id) - return 0; - - int drm_format = resolve_drm_format(bo, pitches, offsets, handles); - - if (drm_format == 0) { - ALOGE("error resolving drm format"); - return -EINVAL; - } - - return drmModeAddFB2(bo->drm->fd, - bo->handle->width, bo->handle->height, - drm_format, handles, pitches, offsets, - (uint32_t *) &bo->fb_id, 0); -} - -/* - * Remove a fb object for a bo. - */ -void gralloc_drm_bo_rm_fb(struct gralloc_drm_bo_t *bo) -{ - if (bo->fb_id) { - drmModeRmFB(bo->drm->fd, bo->fb_id); - bo->fb_id = 0; - } -} - -/* - * Program CRTC. - */ -static int drm_kms_set_crtc(struct gralloc_drm_t *drm, - struct gralloc_drm_output *output, int fb_id) -{ - int ret; - - ret = drmModeSetCrtc(drm->fd, output->crtc_id, fb_id, - 0, 0, &output->connector_id, 1, &output->mode); - if (ret) { - ALOGE("failed to set crtc (%s) (crtc_id %d, fb_id %d, conn %d, mode %dx%d)", - strerror(errno), output->crtc_id, fb_id, output->connector_id, - output->mode.hdisplay, output->mode.vdisplay); - return ret; - } - - if (drm->mode_quirk_vmwgfx) - ret = drmModeDirtyFB(drm->fd, fb_id, &drm->clip, 1); - - return ret; -} - -/* - * Callback for a page flip event. - */ -static void page_flip_handler(int fd, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data) -{ - struct gralloc_drm_t *drm = (struct gralloc_drm_t *) user_data; - - /* ack the last scheduled flip */ - drm->current_front = drm->next_front; - drm->next_front = NULL; -} - -/* - * Set a plane. - */ -static int gralloc_drm_bo_setplane(struct gralloc_drm_t *drm, - struct gralloc_drm_plane_t *plane) -{ - struct gralloc_drm_bo_t *bo = NULL; - int err; - - if (plane->handle) - bo = gralloc_drm_bo_from_handle(plane->handle); - - // create a framebuffer if does not exist - if (bo && bo->fb_id == 0) { - err = gralloc_drm_bo_add_fb(bo); - if (err) { - ALOGE("%s: could not create drm fb, (%s)", - __func__, strerror(-err)); - return err; - } - } - - err = drmModeSetPlane(drm->fd, - plane->drm_plane->plane_id, - drm->primary.crtc_id, - bo ? bo->fb_id : 0, - 0, // flags - plane->dst_x, - plane->dst_y, - plane->dst_w, - plane->dst_h, - plane->src_x << 16, - plane->src_y << 16, - plane->src_w << 16, - plane->src_h << 16); - - if (err) { - /* clear plane_mask so that this buffer won't be tried again */ - struct gralloc_drm_handle_t *drm_handle = - (struct gralloc_drm_handle_t *) plane->handle; - drm_handle->plane_mask = 0; - - ALOGE("drmModeSetPlane : error (%s) (plane %d crtc %d fb %d)", - strerror(-err), - plane->drm_plane->plane_id, - drm->primary.crtc_id, - bo ? bo->fb_id : 0); - } - - if (plane->prev) - gralloc_drm_bo_decref(plane->prev); - - if (bo) - bo->refcount++; - - plane->prev = bo; - - return err; -} - -/* - * Returns if a particular plane is supported with the implementation - */ -static unsigned is_plane_supported(const struct gralloc_drm_t *drm, - const struct gralloc_drm_plane_t *plane) -{ - /* Planes are only supported on primary pipe for now */ - return plane->drm_plane->possible_crtcs & (1 << drm->primary.pipe); -} - -/* - * Sets all the active planes to be displayed. - */ -static void gralloc_drm_set_planes(struct gralloc_drm_t *drm) -{ - struct gralloc_drm_plane_t *plane = drm->planes; - unsigned int i; - for (i = 0; i < drm->plane_resources->count_planes; - i++, plane++) { - /* plane is not in use at all */ - if (!plane->active && !plane->handle) - continue; - - /* plane is active, safety check if it is supported */ - if (!is_plane_supported(drm, plane)) - ALOGE("%s: plane %d is not supported", - __func__, plane->drm_plane->plane_id); - - /* - * Disable overlay if it is not active - * or if there is error during setplane - */ - if (!plane->active) - plane->handle = 0; - - if (gralloc_drm_bo_setplane(drm, plane)) - plane->active = 0; - } -} - -/* - * Interface for HWC, used to reserve a plane for a layer. - */ -int gralloc_drm_reserve_plane(struct gralloc_drm_t *drm, - buffer_handle_t handle, - uint32_t id, - uint32_t dst_x, - uint32_t dst_y, - uint32_t dst_w, - uint32_t dst_h, - uint32_t src_x, - uint32_t src_y, - uint32_t src_w, - uint32_t src_h) -{ - int j; - struct gralloc_drm_handle_t *drm_handle = - gralloc_drm_handle(handle); - int plane_count = drm->plane_resources->count_planes; - struct gralloc_drm_plane_t *plane = drm->planes; - - /* no supported planes for this handle */ - if (!drm_handle->plane_mask) { - ALOGE("%s: buffer %p cannot be shown on a plane\n", - __func__, drm_handle); - return -EINVAL; - } - - for (j = 0; j < plane_count; j++, plane++) { - - /* - * handle may be suitable to be shown on a plane, in - * addition we need to check that this particular plane - * is supported by the current implementation - */ - if (!is_plane_supported(drm, plane)) - continue; - - /* if plane is available and can support this buffer */ - if (!plane->active && - drm_handle->plane_mask & - (1U << plane->drm_plane->plane_id)) { - - plane->dst_x = dst_x; - plane->dst_y = dst_y; - plane->dst_w = dst_w; - plane->dst_h = dst_h; - plane->src_x = src_x; - plane->src_y = src_y; - plane->src_w = src_w; - plane->src_h = src_h; - plane->handle = handle; - plane->id = id; - plane->active = 1; - - return 0; - } - } - - /* no free planes available */ - return -EBUSY; -} - -/* - * Interface for HWC, used to disable all the overlays. Plane id - * is also set to 0 as it should be mappable to a particular layer only - * if it has been reserved with 'reserve_plane'. - */ -void gralloc_drm_disable_planes(struct gralloc_drm_t *drm) -{ - struct gralloc_drm_plane_t *plane = drm->planes; - unsigned int i; - - for (i = 0; i < drm->plane_resources->count_planes; i++, plane++) { - plane->active = 0; - plane->id = 0; - } -} - -/* - * Interface for HWC, used to change handle of a reserved plane. - */ -int gralloc_drm_set_plane_handle(struct gralloc_drm_t *drm, - uint32_t id, buffer_handle_t handle) -{ - struct gralloc_drm_plane_t *plane = drm->planes; - unsigned i; - - for (i = 0; i < drm->plane_resources->count_planes; i++, plane++) - if (plane->active && plane->id == id) { - plane->handle = handle; - return 0; - } - - return -EINVAL; -} - -/* - * Schedule a page flip. - */ -static int drm_kms_page_flip(struct gralloc_drm_t *drm, - struct gralloc_drm_bo_t *bo) -{ - int ret; - - /* there is another flip pending */ - while (drm->next_front) { - drm->waiting_flip = 1; - drmHandleEvent(drm->fd, &drm->evctx); - drm->waiting_flip = 0; - if (drm->next_front) { - /* record an error and break */ - ALOGE("drmHandleEvent returned without flipping"); - drm->current_front = drm->next_front; - drm->next_front = NULL; - } - } - - if (!bo) - return 0; - - pthread_mutex_lock(&drm->hdmi_mutex); - if (drm->hdmi.active && drm->hdmi_mode == HDMI_CLONED && drm->hdmi.bo) { - - int dst_x1 = 0, dst_y1 = 0; - - if (drm->hdmi.bo->handle->width > bo->handle->width) - dst_x1 = (drm->hdmi.bo->handle->width - bo->handle->width) / 2; - if (drm->hdmi.bo->handle->height > bo->handle->height) - dst_y1 = (drm->hdmi.bo->handle->height - bo->handle->height) / 2; - - drm->drv->blit(drm->drv, drm->hdmi.bo, bo, - dst_x1, dst_y1, - dst_x1 + bo->handle->width, - dst_y1 + bo->handle->height, - 0, 0, bo->handle->width, bo->handle->height); - - ret = drmModePageFlip(drm->fd, drm->hdmi.crtc_id, drm->hdmi.bo->fb_id, 0, NULL); - if (ret && errno != EBUSY) - ALOGE("failed to perform page flip for hdmi (%s) (crtc %d fb %d))", - strerror(errno), drm->hdmi.crtc_id, drm->hdmi.bo->fb_id); - } - pthread_mutex_unlock(&drm->hdmi_mutex); - - /* set planes to be displayed */ - gralloc_drm_set_planes(drm); - - ret = drmModePageFlip(drm->fd, drm->primary.crtc_id, bo->fb_id, - DRM_MODE_PAGE_FLIP_EVENT, (void *) drm); - if (ret) { - ALOGE("failed to perform page flip for primary (%s) (crtc %d fb %d))", - strerror(errno), drm->primary.crtc_id, bo->fb_id); - /* try to set mode for next frame */ - if (errno != EBUSY) - drm->first_post = 1; - } - else - drm->next_front = bo; - - return ret; -} - -/* - * Wait for the next post. - */ -static void drm_kms_wait_for_post(struct gralloc_drm_t *drm, int flip) -{ - unsigned int current, target; - drmVBlank vbl; - int ret; - - if (drm->mode_quirk_vmwgfx) - return; - - flip = !!flip; - - memset(&vbl, 0, sizeof(vbl)); - vbl.request.type = DRM_VBLANK_RELATIVE; - if (drm->vblank_secondary) - vbl.request.type |= DRM_VBLANK_SECONDARY; - vbl.request.sequence = 0; - - /* get the current vblank */ - ret = drmWaitVBlank(drm->fd, &vbl); - if (ret) { - ALOGW("failed to get vblank"); - return; - } - - current = vbl.reply.sequence; - if (drm->first_post) - target = current; - else - target = drm->last_swap + drm->swap_interval - flip; - - /* wait for vblank */ - if (current < target || !flip) { - memset(&vbl, 0, sizeof(vbl)); - vbl.request.type = DRM_VBLANK_ABSOLUTE; - if (drm->vblank_secondary) - vbl.request.type |= DRM_VBLANK_SECONDARY; - if (!flip) { - vbl.request.type |= DRM_VBLANK_NEXTONMISS; - if (target < current) - target = current; - } - - vbl.request.sequence = target; - - ret = drmWaitVBlank(drm->fd, &vbl); - if (ret) { - ALOGW("failed to wait vblank"); - return; - } - } - - drm->last_swap = vbl.reply.sequence + flip; -} - -/* - * Post a bo. This is not thread-safe. - */ -int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo) -{ - struct gralloc_drm_t *drm = bo->drm; - int ret; - - if (!bo->fb_id && drm->swap_mode != DRM_SWAP_COPY) { - ALOGE("unable to post bo %p without fb", bo); - return -EINVAL; - } - - /* TODO spawn a thread to avoid waiting and race */ - - if (drm->first_post) { - if (drm->swap_mode == DRM_SWAP_COPY) { - struct gralloc_drm_bo_t *dst; - - dst = (drm->next_front) ? - drm->next_front : - drm->current_front; - drm->drv->blit(drm->drv, dst, bo, 0, 0, - bo->handle->width, - bo->handle->height, - 0, 0, - bo->handle->width, - bo->handle->height); - bo = dst; - } - - ret = drm_kms_set_crtc(drm, &drm->primary, bo->fb_id); - if (!ret) { - drm->first_post = 0; - drm->current_front = bo; - if (drm->next_front == bo) - drm->next_front = NULL; - } - - pthread_mutex_lock(&drm->hdmi_mutex); - if (drm->hdmi.active && drm->hdmi_mode == HDMI_CLONED && drm->hdmi.bo) - drm_kms_set_crtc(drm, &drm->hdmi, drm->hdmi.bo->fb_id); - pthread_mutex_unlock(&drm->hdmi_mutex); - - return ret; - } - - switch (drm->swap_mode) { - case DRM_SWAP_FLIP: - if (drm->swap_interval > 1) - drm_kms_wait_for_post(drm, 1); - ret = drm_kms_page_flip(drm, bo); - if (drm->next_front) { - /* - * wait if the driver says so or the current front - * will be written by CPU - */ - if (drm->mode_sync_flip || - (drm->current_front->handle->usage & - GRALLOC_USAGE_SW_WRITE_MASK)) - drm_kms_page_flip(drm, NULL); - } - break; - case DRM_SWAP_COPY: - drm_kms_wait_for_post(drm, 0); - drm->drv->blit(drm->drv, drm->current_front, - bo, 0, 0, - bo->handle->width, - bo->handle->height, - 0, 0, - bo->handle->width, - bo->handle->height); - if (drm->mode_quirk_vmwgfx) - ret = drmModeDirtyFB(drm->fd, drm->current_front->fb_id, &drm->clip, 1); - ret = 0; - break; - case DRM_SWAP_SETCRTC: - drm_kms_wait_for_post(drm, 0); - ret = drm_kms_set_crtc(drm, &drm->primary, bo->fb_id); - - pthread_mutex_lock(&drm->hdmi_mutex); - if (drm->hdmi.active && drm->hdmi_mode == HDMI_CLONED && drm->hdmi.bo) - drm_kms_set_crtc(drm, &drm->hdmi, drm->hdmi.bo->fb_id); - pthread_mutex_unlock(&drm->hdmi_mutex); - - drm->current_front = bo; - break; - default: - /* no-op */ - ret = 0; - break; - } - - return ret; -} - -static struct gralloc_drm_t *drm_singleton; - -static void on_signal(int sig) -{ - struct gralloc_drm_t *drm = drm_singleton; - - /* wait the pending flip */ - if (drm && drm->swap_mode == DRM_SWAP_FLIP && drm->next_front) { - /* there is race, but this function is hacky enough to ignore that */ - if (drm_singleton->waiting_flip) - usleep(100 * 1000); /* 100ms */ - else - drm_kms_page_flip(drm_singleton, NULL); - } - - exit(-1); -} - -static void drm_kms_init_features(struct gralloc_drm_t *drm) -{ - const char *swap_mode; - - /* call to the driver here, after KMS has been initialized */ - drm->drv->init_kms_features(drm->drv, drm); - - if (drm->swap_mode == DRM_SWAP_FLIP) { - struct sigaction act; - - memset(&drm->evctx, 0, sizeof(drm->evctx)); - drm->evctx.version = DRM_EVENT_CONTEXT_VERSION; - drm->evctx.page_flip_handler = page_flip_handler; - - /* - * XXX GPU tends to freeze if the program is terminiated with a - * flip pending. What is the right way to handle the - * situation? - */ - sigemptyset(&act.sa_mask); - act.sa_handler = on_signal; - act.sa_flags = 0; - sigaction(SIGINT, &act, NULL); - sigaction(SIGTERM, &act, NULL); - - drm_singleton = drm; - } - else if (drm->swap_mode == DRM_SWAP_COPY) { - struct gralloc_drm_bo_t *front; - int stride; - - /* create the real front buffer */ - front = gralloc_drm_bo_create(drm, - drm->primary.mode.hdisplay, - drm->primary.mode.vdisplay, - drm->primary.fb_format, - GRALLOC_USAGE_HW_FB); - if (front && gralloc_drm_bo_add_fb(front)) { - gralloc_drm_bo_decref(front); - front = NULL; - } - - /* abuse next_front */ - if (front) - drm->next_front = front; - else - drm->swap_mode = DRM_SWAP_SETCRTC; - } - - switch (drm->swap_mode) { - case DRM_SWAP_FLIP: - swap_mode = "flip"; - break; - case DRM_SWAP_COPY: - swap_mode = "copy"; - break; - case DRM_SWAP_SETCRTC: - swap_mode = "set-crtc"; - break; - default: - swap_mode = "no-op"; - break; - } - - ALOGD("will use %s for fb posting", swap_mode); -} - -#define MARGIN_PERCENT 1.8 /* % of active vertical image*/ -#define CELL_GRAN 8.0 /* assumed character cell granularity*/ -#define MIN_PORCH 1 /* minimum front porch */ -#define V_SYNC_RQD 3 /* width of vsync in lines */ -#define H_SYNC_PERCENT 8.0 /* width of hsync as % of total line */ -#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */ -#define M 600.0 /* blanking formula gradient */ -#define C 40.0 /* blanking formula offset */ -#define K 128.0 /* blanking formula scaling factor */ -#define J 20.0 /* blanking formula scaling factor */ -/* C' and M' are part of the Blanking Duty Cycle computation */ -#define C_PRIME (((C - J) * K / 256.0) + J) -#define M_PRIME (K / 256.0 * M) - -static drmModeModeInfoPtr generate_mode(int h_pixels, int v_lines, float freq) -{ - float h_pixels_rnd; - float v_lines_rnd; - float v_field_rate_rqd; - float top_margin; - float bottom_margin; - float interlace; - float h_period_est; - float vsync_plus_bp; - float v_back_porch; - float total_v_lines; - float v_field_rate_est; - float h_period; - float v_field_rate; - float v_frame_rate; - float left_margin; - float right_margin; - float total_active_pixels; - float ideal_duty_cycle; - float h_blank; - float total_pixels; - float pixel_freq; - float h_freq; - - float h_sync; - float h_front_porch; - float v_odd_front_porch_lines; - int interlaced = 0; - int margins = 0; - - drmModeModeInfoPtr m = malloc(sizeof(drmModeModeInfo)); - - h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN; - v_lines_rnd = interlaced ? rint((float) v_lines) / 2.0 : rint((float) v_lines); - v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq); - top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0); - bottom_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0); - interlace = interlaced ? 0.5 : 0.0; - h_period_est = (((1.0 / v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP / 1000000.0)) / (v_lines_rnd + (2 * top_margin) + MIN_PORCH + interlace) * 1000000.0); - vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP / h_period_est); - v_back_porch = vsync_plus_bp - V_SYNC_RQD; - total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp + interlace + MIN_PORCH; - v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0; - h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est); - v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0; - v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate; - left_margin = margins ? rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : 0.0; - right_margin = margins ? rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : 0.0; - total_active_pixels = h_pixels_rnd + left_margin + right_margin; - ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0); - h_blank = rint(total_active_pixels * ideal_duty_cycle / (100.0 - ideal_duty_cycle) / (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN); - total_pixels = total_active_pixels + h_blank; - pixel_freq = total_pixels / h_period; - h_freq = 1000.0 / h_period; - h_sync = rint(H_SYNC_PERCENT / 100.0 * total_pixels / CELL_GRAN) * CELL_GRAN; - h_front_porch = (h_blank / 2.0) - h_sync; - v_odd_front_porch_lines = MIN_PORCH + interlace; - - m->clock = ceil(pixel_freq) * 1000; - m->hdisplay = (int) (h_pixels_rnd); - m->hsync_start = (int) (h_pixels_rnd + h_front_porch); - m->hsync_end = (int) (h_pixels_rnd + h_front_porch + h_sync); - m->htotal = (int) (total_pixels); - m->hskew = 0; - m->vdisplay = (int) (v_lines_rnd); - m->vsync_start = (int) (v_lines_rnd + v_odd_front_porch_lines); - m->vsync_end = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD); - m->vtotal = (int) (total_v_lines); - m->vscan = 0; - m->vrefresh = freq; - m->flags = 10; - m->type = 64; - - return (m); -} - -static drmModeModeInfoPtr find_mode(drmModeConnectorPtr connector, int *bpp) -{ - char value[PROPERTY_VALUE_MAX]; - drmModeModeInfoPtr mode; - int dist, i; - int xres = 0, yres = 0, rate = 0; - int forcemode = 0; - - if (property_get("debug.drm.mode", value, NULL)) { - char *p = value, *end; - - /* parse <xres>x<yres>[@<bpp>] */ - if (sscanf(value, "%dx%d@%d", &xres, &yres, bpp) != 3) { - *bpp = 0; - if (sscanf(value, "%dx%d", &xres, &yres) != 2) - xres = yres = 0; - } - - if ((xres && yres) || *bpp) { - ALOGI("will find the closest match for %dx%d@%d", - xres, yres, *bpp); - } - } else if (property_get("debug.drm.mode.force", value, NULL)) { - char *p = value, *end; - *bpp = 0; - - /* parse <xres>x<yres>[@<refreshrate>] */ - if (sscanf(value, "%dx%d@%d", &xres, &yres, &rate) != 3) { - rate = 60; - if (sscanf(value, "%dx%d", &xres, &yres) != 2) - xres = yres = 0; - } - - if (xres && yres && rate) { - ALOGI("will use %dx%d@%dHz", xres, yres, rate); - forcemode = 1; - } - } else { - *bpp = 0; - } - - dist = INT_MAX; - - if (forcemode) - mode = generate_mode(xres, yres, rate); - else { - mode = NULL; - for (i = 0; i < connector->count_modes; i++) { - drmModeModeInfoPtr m = &connector->modes[i]; - int tmp; - - if (xres && yres) { - tmp = (m->hdisplay - xres) * (m->hdisplay - xres) + - (m->vdisplay - yres) * (m->vdisplay - yres); - } - else { - /* use the first preferred mode */ - tmp = (m->type & DRM_MODE_TYPE_PREFERRED) ? 0 : dist; - } - - if (tmp < dist) { - mode = m; - dist = tmp; - if (!dist) - break; - } - } - } - - /* fallback to the first mode */ - if (!mode) - mode = &connector->modes[0]; - - ALOGI("Established mode:"); - ALOGI("clock: %d, hdisplay: %d, hsync_start: %d, hsync_end: %d, htotal: %d, hskew: %d", mode->clock, mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, mode->hskew); - ALOGI("vdisplay: %d, vsync_start: %d, vsync_end: %d, vtotal: %d, vscan: %d, vrefresh: %d", mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal, mode->vscan, mode->vrefresh); - ALOGI("flags: %d, type: %d, name %s", mode->flags, mode->type, mode->name); - - *bpp /= 8; - - return mode; -} - -/* - * Initialize KMS with a connector. - */ -static int drm_kms_init_with_connector(struct gralloc_drm_t *drm, - struct gralloc_drm_output *output, drmModeConnectorPtr connector) -{ - drmModeEncoderPtr encoder; - drmModeModeInfoPtr mode; - static int used_crtcs = 0; - int bpp, i; - - if (!connector->count_modes) - return -EINVAL; - - encoder = drmModeGetEncoder(drm->fd, connector->encoders[0]); - if (!encoder) - return -EINVAL; - - /* find first possible crtc which is not used yet */ - for (i = 0; i < drm->resources->count_crtcs; i++) { - if (encoder->possible_crtcs & (1 << i) && - (used_crtcs & (1 << i)) != (1 << i)) - break; - } - - used_crtcs |= (1 << i); - - drmModeFreeEncoder(encoder); - if (i == drm->resources->count_crtcs) - return -EINVAL; - - output->bo = NULL; - output->crtc_id = drm->resources->crtcs[i]; - output->connector_id = connector->connector_id; - output->pipe = i; - - /* print connector info */ - if (connector->count_modes > 1) { - ALOGI("there are %d modes on connector 0x%x, type %d", - connector->count_modes, - connector->connector_id, - connector->connector_type); - for (i = 0; i < connector->count_modes; i++) - ALOGI(" %s", connector->modes[i].name); - } - else { - ALOGI("there is one mode on connector 0x%d: %s", - connector->connector_id, - connector->modes[0].name); - } - - mode = find_mode(connector, &bpp); - - ALOGI("the best mode is %s", mode->name); - - output->mode = *mode; - switch (bpp) { - case 2: - output->fb_format = HAL_PIXEL_FORMAT_RGB_565; - break; - case 4: - default: - output->fb_format = HAL_PIXEL_FORMAT_BGRA_8888; - break; - } - - if (connector->mmWidth && connector->mmHeight) { - output->xdpi = (output->mode.hdisplay * 25.4 / connector->mmWidth); - output->ydpi = (output->mode.vdisplay * 25.4 / connector->mmHeight); - } - else { - output->xdpi = 75; - output->ydpi = 75; - } - -#ifdef DRM_MODE_FEATURE_DIRTYFB - drm->clip.x1 = 0; - drm->clip.y1 = 0; - drm->clip.x2 = output->mode.hdisplay; - drm->clip.y2 = output->mode.vdisplay; -#endif - - return 0; -} - - -/* - * Fetch a connector of particular type - */ -static drmModeConnectorPtr fetch_connector(struct gralloc_drm_t *drm, - uint32_t type) -{ - int i; - - if (!drm->resources) - return NULL; - - for (i = 0; i < drm->resources->count_connectors; i++) { - drmModeConnectorPtr connector = - connector = drmModeGetConnector(drm->fd, - drm->resources->connectors[i]); - if (connector) { - if (connector->connector_type == type && - connector->connection == DRM_MODE_CONNECTED) - return connector; - drmModeFreeConnector(connector); - } - } - return NULL; -} - - -/* - * Initializes hdmi output with a connector and allocates - * a private framebuffer for it. This is called on startup if - * hdmi cable is connected and also on hotplug events. - */ -static void init_hdmi_output(struct gralloc_drm_t *drm, - drmModeConnectorPtr connector) -{ - drm_kms_init_with_connector(drm, &drm->hdmi, connector); - - ALOGD("%s, allocate private buffer for hdmi [%dx%d]", - __func__, drm->hdmi.mode.hdisplay, drm->hdmi.mode.vdisplay); - - drm->hdmi.bo = gralloc_drm_bo_create(drm, - drm->hdmi.mode.hdisplay, drm->hdmi.mode.vdisplay, - drm->hdmi.fb_format, - GRALLOC_USAGE_SW_WRITE_OFTEN|GRALLOC_USAGE_HW_RENDER); - - gralloc_drm_bo_add_fb(drm->hdmi.bo); - - drm->hdmi_mode = HDMI_CLONED; - drm->hdmi.active = 1; -} - - -/* - * Thread that listens to uevents and checks if hdmi state changes - */ -static void *hdmi_observer(void *data) -{ - static char uevent_desc[4096]; - drmModeConnectorPtr hdmi; - struct gralloc_drm_t *drm = - (struct gralloc_drm_t *) data; - - uevent_init(); - - memset(uevent_desc, 0, sizeof(uevent_desc)); - - while(1) { - - /* this polls */ - int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2); - - if(len && strstr(uevent_desc, "devices/virtual/switch/hdmi")) { - - /* check what changed */ - const char *prop = uevent_desc + strlen(uevent_desc) + 1; - - while (*prop) { - - const char *state = strstr(prop, "SWITCH_STATE="); - if (state) { - unsigned int value = 0; - state += strlen("SWITCH_STATE="); - value = atoi(state); - - pthread_mutex_lock(&drm->hdmi_mutex); - - if (value) { - hdmi = fetch_connector(drm, DRM_MODE_CONNECTOR_HDMIA); - if (hdmi) { - - ALOGD("init hdmi on hotplug event"); - init_hdmi_output(drm, hdmi); - - /* will trigger modeset */ - drm->first_post = 1; - - drmModeFreeConnector(hdmi); - - pthread_mutex_unlock(&drm->hdmi_mutex); - } - break; - } else { - drm->hdmi.active = 0; - - ALOGD("destroy hdmi private buffer"); - gralloc_drm_bo_decref(drm->hdmi.bo); - drm->hdmi.bo = NULL; - - pthread_mutex_unlock(&drm->hdmi_mutex); - break; - } - - pthread_mutex_unlock(&drm->hdmi_mutex); - } - - /* next property/value pair */ - prop += strlen(prop) + 1; - if (prop - uevent_desc >= len) - break; - } - } - } - - pthread_exit(NULL); - return 0; -} - - -/* - * Initialize KMS. - */ -int gralloc_drm_init_kms(struct gralloc_drm_t *drm) -{ - drmModeConnectorPtr lvds, hdmi; - int i, ret; - - if (drm->resources) - return 0; - - drm->resources = drmModeGetResources(drm->fd); - if (!drm->resources) { - ALOGE("failed to get modeset resources"); - return -EINVAL; - } - - drm->plane_resources = drmModeGetPlaneResources(drm->fd); - if (!drm->plane_resources) { - ALOGD("no planes found from drm resources"); - } else { - unsigned int i, j; - - ALOGD("supported drm planes and formats"); - /* fill a helper structure for hwcomposer */ - drm->planes = calloc(drm->plane_resources->count_planes, - sizeof(struct gralloc_drm_plane_t)); - - for (i = 0; i < drm->plane_resources->count_planes; i++) { - drm->planes[i].drm_plane = drmModeGetPlane(drm->fd, - drm->plane_resources->planes[i]); - - ALOGD("plane id %d", drm->planes[i].drm_plane->plane_id); - for (j = 0; j < drm->planes[i].drm_plane->count_formats; j++) - ALOGD(" format %c%c%c%c", - (drm->planes[i].drm_plane->formats[j]), - (drm->planes[i].drm_plane->formats[j])>>8, - (drm->planes[i].drm_plane->formats[j])>>16, - (drm->planes[i].drm_plane->formats[j])>>24); - } - } - - /* find the crtc/connector/mode to use */ - lvds = fetch_connector(drm, DRM_MODE_CONNECTOR_LVDS); - if (lvds) { - drm_kms_init_with_connector(drm, &drm->primary, lvds); - drmModeFreeConnector(lvds); - drm->primary.active = 1; - } - - /* if still no connector, find first connected connector and try it */ - if (!drm->primary.active) { - - for (i = 0; i < drm->resources->count_connectors; i++) { - drmModeConnectorPtr connector; - - connector = drmModeGetConnector(drm->fd, - drm->resources->connectors[i]); - if (connector) { - if (connector->connection == DRM_MODE_CONNECTED) { - if (!drm_kms_init_with_connector(drm, - &drm->primary, connector)) - break; - } - - drmModeFreeConnector(connector); - } - } - if (i == drm->resources->count_connectors) { - ALOGE("failed to find a valid crtc/connector/mode combination"); - drmModeFreeResources(drm->resources); - drm->resources = NULL; - - return -EINVAL; - } - } - - - /* check if hdmi is connected already */ - hdmi = fetch_connector(drm, DRM_MODE_CONNECTOR_HDMIA); - if (hdmi) { - - if (hdmi->connector_id == drm->primary.connector_id) { - /* special case: our primary connector is hdmi */ - ALOGD("hdmi is the primary connector"); - goto skip_hdmi_modes; - } - - ALOGD("init hdmi on startup"); - init_hdmi_output(drm, hdmi); - - drmModeFreeConnector(hdmi); - } - -goto skip_hdmi_modes; - /* launch hdmi observer thread */ - pthread_mutex_init(&drm->hdmi_mutex, NULL); - pthread_create(&drm->hdmi_hotplug_thread, NULL, hdmi_observer, drm); - -skip_hdmi_modes: - - drm_kms_init_features(drm); - drm->first_post = 1; - - return 0; -} - -void gralloc_drm_fini_kms(struct gralloc_drm_t *drm) -{ - switch (drm->swap_mode) { - case DRM_SWAP_FLIP: - drm_kms_page_flip(drm, NULL); - break; - case DRM_SWAP_COPY: - { - struct gralloc_drm_bo_t **bo = (drm->current_front) ? - &drm->current_front : &drm->next_front; - - if (*bo) - gralloc_drm_bo_decref(*bo); - *bo = NULL; - } - break; - default: - break; - } - - /* restore crtc? */ - - if (drm->resources) { - drmModeFreeResources(drm->resources); - drm->resources = NULL; - } - - if (drm->planes) { - unsigned int i; - for (i = 0; i < drm->plane_resources->count_planes; i++) - drmModeFreePlane(drm->planes[i].drm_plane); - free(drm->planes); - drm->planes = NULL; - } - - if (drm->plane_resources) { - drmModeFreePlaneResources(drm->plane_resources); - drm->plane_resources = NULL; - } - - /* destroy private buffer of hdmi output */ - if (drm->hdmi.bo) - gralloc_drm_bo_decref(drm->hdmi.bo); - - drm_singleton = NULL; -} - -int gralloc_drm_is_kms_initialized(struct gralloc_drm_t *drm) -{ - return (drm->resources != NULL); -} - -/* - * Initialize a framebuffer device with KMS info. - */ -void gralloc_drm_get_kms_info(struct gralloc_drm_t *drm, - struct framebuffer_device_t *fb) -{ - *((uint32_t *) &fb->flags) = 0x0; - *((uint32_t *) &fb->width) = drm->primary.mode.hdisplay; - *((uint32_t *) &fb->height) = drm->primary.mode.vdisplay; - *((int *) &fb->stride) = drm->primary.mode.hdisplay; - *((float *) &fb->fps) = drm->primary.mode.vrefresh; - - *((int *) &fb->format) = drm->primary.fb_format; - *((float *) &fb->xdpi) = drm->primary.xdpi; - *((float *) &fb->ydpi) = drm->primary.ydpi; - *((int *) &fb->minSwapInterval) = drm->swap_interval; - *((int *) &fb->maxSwapInterval) = drm->swap_interval; -} - -/* - * Return true if fb posting is pipelined. - */ -int gralloc_drm_is_kms_pipelined(struct gralloc_drm_t *drm) -{ - return (drm->swap_mode != DRM_SWAP_SETCRTC); -} diff --git a/gralloc_drm_nouveau.c b/gralloc_drm_nouveau.c index 576966e..2f15655 100644 --- a/gralloc_drm_nouveau.c +++ b/gralloc_drm_nouveau.c @@ -267,27 +267,6 @@ static void nouveau_unmap(struct gralloc_drm_drv_t *drv, nouveau_bo_unmap(nb->bo); } -static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv, - struct gralloc_drm_t *drm) -{ - struct nouveau_info *info = (struct nouveau_info *) drv; - - switch (drm->primary.fb_format) { - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGB_565: - break; - default: - drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888; - break; - } - - drm->mode_quirk_vmwgfx = 0; - drm->swap_mode = (info->chan) ? DRM_SWAP_FLIP : DRM_SWAP_SETCRTC; - drm->mode_sync_flip = 1; - drm->swap_interval = 1; - drm->vblank_secondary = 0; -} - static void nouveau_destroy(struct gralloc_drm_drv_t *drv) { struct nouveau_info *info = (struct nouveau_info *) drv; @@ -374,7 +353,6 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_nouveau(int fd) } info->base.destroy = nouveau_destroy; - info->base.init_kms_features = nouveau_init_kms_features; info->base.alloc = nouveau_alloc; info->base.free = nouveau_free; info->base.map = nouveau_map; diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c index ec3e19d..d237b7d 100644 --- a/gralloc_drm_pipe.c +++ b/gralloc_drm_pipe.c @@ -281,83 +281,6 @@ static void pipe_unmap(struct gralloc_drm_drv_t *drv, pthread_mutex_unlock(&pm->mutex); } -static void pipe_blit(struct gralloc_drm_drv_t *drv, - struct gralloc_drm_bo_t *dst_bo, - struct gralloc_drm_bo_t *src_bo, - uint16_t dst_x1, uint16_t dst_y1, - uint16_t dst_x2, uint16_t dst_y2, - uint16_t src_x1, uint16_t src_y1, - uint16_t src_x2, uint16_t src_y2) -{ - struct pipe_manager *pm = (struct pipe_manager *) drv; - struct pipe_buffer *dst = (struct pipe_buffer *) dst_bo; - struct pipe_buffer *src = (struct pipe_buffer *) src_bo; - struct pipe_box src_box; - - if (dst_bo->handle->width != src_bo->handle->width || - dst_bo->handle->height != src_bo->handle->height || - dst_bo->handle->stride != src_bo->handle->stride || - dst_bo->handle->format != src_bo->handle->format) { - ALOGE("copy between incompatible buffers"); - return; - } - - if (dst_x2 > dst_bo->handle->width) - dst_x2 = dst_bo->handle->width; - if (dst_y2 > dst_bo->handle->height) - dst_y2 = dst_bo->handle->height; - - if (src_x2 <= src_x1 || src_y2 <= src_y1) - return; - - u_box_2d(src_x1, src_y1, src_x2 - src_x1, src_y2 - src_y1, &src_box); - - pthread_mutex_lock(&pm->mutex); - - /* need a context for copying */ - if (!pm->context) { - pm->context = pm->screen->context_create(pm->screen, NULL); - if (!pm->context) { - ALOGE("failed to create pipe context"); - pthread_mutex_unlock(&pm->mutex); - return; - } - } - - pm->context->resource_copy_region(pm->context, - dst->resource, 0, dst_x1, dst_y1, 0, - src->resource, 0, &src_box); - pm->context->flush(pm->context, NULL, 0); - - pthread_mutex_unlock(&pm->mutex); -} - -static void pipe_init_kms_features(struct gralloc_drm_drv_t *drv, struct gralloc_drm_t *drm) -{ - struct pipe_manager *pm = (struct pipe_manager *) drv; - - switch (drm->primary.fb_format) { - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGB_565: - break; - default: - drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888; - break; - } - - if (strcmp(pm->driver, "vmwgfx") == 0) { - drm->mode_quirk_vmwgfx = 1; - drm->swap_mode = DRM_SWAP_COPY; - } - else { - drm->mode_quirk_vmwgfx = 0; - drm->swap_mode = DRM_SWAP_FLIP; - } - drm->mode_sync_flip = 1; - drm->swap_interval = 1; - drm->vblank_secondary = 0; -} - static void pipe_destroy(struct gralloc_drm_drv_t *drv) { struct pipe_manager *pm = (struct pipe_manager *) drv; @@ -552,12 +475,10 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *na } pm->base.destroy = pipe_destroy; - pm->base.init_kms_features = pipe_init_kms_features; pm->base.alloc = pipe_alloc; pm->base.free = pipe_free; pm->base.map = pipe_map; pm->base.unmap = pipe_unmap; - pm->base.blit = pipe_blit; return &pm->base; } diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h index 1a36cc1..9a87b78 100644 --- a/gralloc_drm_priv.h +++ b/gralloc_drm_priv.h @@ -34,110 +34,15 @@ extern "C" { #endif -/* how a bo is posted */ -enum drm_swap_mode { - DRM_SWAP_NOOP, - DRM_SWAP_FLIP, - DRM_SWAP_COPY, - DRM_SWAP_SETCRTC, -}; - -enum hdmi_output_mode { - HDMI_CLONED, - HDMI_EXTENDED, -}; - -struct gralloc_drm_plane_t { - drmModePlane *drm_plane; - - /* plane has been set to display a layer */ - uint32_t active; - - /* handle to display */ - buffer_handle_t handle; - - /* identifier set by hwc */ - uint32_t id; - - /* position, crop and scale */ - uint32_t src_x; - uint32_t src_y; - uint32_t src_w; - uint32_t src_h; - uint32_t dst_x; - uint32_t dst_y; - uint32_t dst_w; - uint32_t dst_h; - - /* previous buffer, for refcounting */ - struct gralloc_drm_bo_t *prev; -}; - -struct gralloc_drm_output -{ - uint32_t crtc_id; - uint32_t connector_id; - uint32_t pipe; - drmModeModeInfo mode; - int xdpi, ydpi; - int fb_format; - int bpp; - uint32_t active; - - /* 'private fb' for this output */ - struct gralloc_drm_bo_t *bo; -}; - struct gralloc_drm_t { /* initialized by gralloc_drm_create */ int fd; struct gralloc_drm_drv_t *drv; - - /* initialized by gralloc_drm_init_kms */ - drmModeResPtr resources; - struct gralloc_drm_output primary; - struct gralloc_drm_output hdmi; - enum hdmi_output_mode hdmi_mode; - - /* hdmi hotplug */ - pthread_mutex_t hdmi_mutex; - pthread_t hdmi_hotplug_thread; - -#ifdef DRM_MODE_FEATURE_DIRTYFB - drmModeClip clip; -#endif - - /* initialized by drv->init_kms_features */ - enum drm_swap_mode swap_mode; - int swap_interval; - int mode_quirk_vmwgfx; - int mode_sync_flip; /* page flip should block */ - int vblank_secondary; - - drmEventContext evctx; - - int first_post; - struct gralloc_drm_bo_t *current_front, *next_front; - int waiting_flip; - unsigned int last_swap; - - /* plane support */ - drmModePlaneResPtr plane_resources; - struct gralloc_drm_plane_t *planes; }; struct drm_module_t { gralloc_module_t base; - /* HWC plane API */ - int (*hwc_reserve_plane) (struct gralloc_drm_t *mod, - buffer_handle_t handle, uint32_t id, - uint32_t dst_x, uint32_t dst_y, uint32_t dst_w, uint32_t dst_h, - uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h); - void (*hwc_disable_planes) (struct gralloc_drm_t *mod); - int (*hwc_set_plane_handle) (struct gralloc_drm_t *mod, - uint32_t id, buffer_handle_t handle); - pthread_mutex_t mutex; struct gralloc_drm_t *drm; }; @@ -146,10 +51,6 @@ struct gralloc_drm_drv_t { /* destroy the driver */ void (*destroy)(struct gralloc_drm_drv_t *drv); - /* initialize KMS features */ - void (*init_kms_features)(struct gralloc_drm_drv_t *drv, - struct gralloc_drm_t *drm); - /* allocate or import a bo */ struct gralloc_drm_bo_t *(*alloc)(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle); @@ -167,15 +68,6 @@ struct gralloc_drm_drv_t { void (*unmap)(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *bo); - /* blit between two bo's, used for DRM_SWAP_COPY and general blitting */ - void (*blit)(struct gralloc_drm_drv_t *drv, - struct gralloc_drm_bo_t *dst, - struct gralloc_drm_bo_t *src, - uint16_t dst_x1, uint16_t dst_y1, - uint16_t dst_x2, uint16_t dst_y2, - uint16_t src_x1, uint16_t src_y1, - uint16_t src_x2, uint16_t src_y2); - /* query component offsets, strides and handles for a format */ void (*resolve_format)(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *bo, diff --git a/gralloc_drm_radeon.c b/gralloc_drm_radeon.c index be2ea9b..8eee668 100644 --- a/gralloc_drm_radeon.c +++ b/gralloc_drm_radeon.c @@ -320,25 +320,6 @@ static void drm_gem_radeon_unmap(struct gralloc_drm_drv_t *drv, radeon_bo_unmap(rbuf->rbo); } -static void drm_gem_radeon_init_kms_features(struct gralloc_drm_drv_t *drv, - struct gralloc_drm_t *drm) -{ - switch (drm->primary.fb_format) { - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGB_565: - break; - default: - drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888; - break; - } - - drm->mode_quirk_vmwgfx = 0; - drm->swap_mode = DRM_SWAP_FLIP; - drm->mode_sync_flip = 1; - drm->swap_interval = 1; - drm->vblank_secondary = 0; -} - static void drm_gem_radeon_destroy(struct gralloc_drm_drv_t *drv) { struct radeon_info *info = (struct radeon_info *) drv; @@ -544,7 +525,6 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_radeon(int fd) } info->base.destroy = drm_gem_radeon_destroy; - info->base.init_kms_features = drm_gem_radeon_init_kms_features; info->base.alloc = drm_gem_radeon_alloc; info->base.free = drm_gem_radeon_free; info->base.map = drm_gem_radeon_map; |