X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=drv.c;h=bc1f782d009093cfba01b32e0433128803514c24;hb=refs%2Fheads%2Fpie-x86;hp=cb54a93553c487a255e8cb955843c8cbcbf7ac2b;hpb=47e629b70ddec014c7691a48509ef437c57761bb;p=android-x86%2Fexternal-minigbm.git diff --git a/drv.c b/drv.c index cb54a93..bc1f782 100644 --- a/drv.c +++ b/drv.c @@ -16,6 +16,11 @@ #include #include +#ifdef __ANDROID__ +#include +#include +#endif + #include "drv_priv.h" #include "helpers.h" #include "util.h" @@ -27,7 +32,6 @@ extern const struct backend backend_evdi; #ifdef DRV_EXYNOS extern const struct backend backend_exynos; #endif -extern const struct backend backend_gma500; #ifdef DRV_I915 extern const struct backend backend_i915; #endif @@ -37,6 +41,12 @@ extern const struct backend backend_marvell; #ifdef DRV_MEDIATEK extern const struct backend backend_mediatek; #endif +#ifdef DRV_MESON +extern const struct backend backend_meson; +#endif +#ifdef DRV_MSM +extern const struct backend backend_msm; +#endif extern const struct backend backend_nouveau; #ifdef DRV_RADEON extern const struct backend backend_radeon; @@ -72,7 +82,6 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_EXYNOS &backend_exynos, #endif - &backend_gma500, #ifdef DRV_I915 &backend_i915, #endif @@ -82,6 +91,12 @@ static const struct backend *drv_get_backend(int fd) #ifdef DRV_MEDIATEK &backend_mediatek, #endif +#ifdef DRV_MESON + &backend_meson, +#endif +#ifdef DRV_MSM + &backend_msm, +#endif &backend_nouveau, #ifdef DRV_RADEON &backend_radeon, @@ -132,30 +147,26 @@ struct driver *drv_create(int fd) if (!drv->buffer_table) goto free_lock; - drv->map_table = drmHashCreate(); - if (!drv->map_table) + drv->mappings = drv_array_init(sizeof(struct mapping)); + if (!drv->mappings) goto free_buffer_table; - /* Start with a power of 2 number of allocations. */ - drv->combos.allocations = 2; - drv->combos.size = 0; - - drv->combos.data = calloc(drv->combos.allocations, sizeof(struct combination)); - if (!drv->combos.data) - goto free_map_table; + drv->combos = drv_array_init(sizeof(struct combination)); + if (!drv->combos) + goto free_mappings; if (drv->backend->init) { ret = drv->backend->init(drv); if (ret) { - free(drv->combos.data); - goto free_map_table; + drv_array_destroy(drv->combos); + goto free_mappings; } } return drv; -free_map_table: - drmHashDestroy(drv->map_table); +free_mappings: + drv_array_destroy(drv->mappings); free_buffer_table: drmHashDestroy(drv->buffer_table); free_lock: @@ -173,9 +184,8 @@ void drv_destroy(struct driver *drv) drv->backend->close(drv); drmHashDestroy(drv->buffer_table); - drmHashDestroy(drv->map_table); - - free(drv->combos.data); + drv_array_destroy(drv->mappings); + drv_array_destroy(drv->combos); pthread_mutex_unlock(&drv->driver_lock); pthread_mutex_destroy(&drv->driver_lock); @@ -202,8 +212,8 @@ struct combination *drv_get_combination(struct driver *drv, uint32_t format, uin best = NULL; uint32_t i; - for (i = 0; i < drv->combos.size; i++) { - curr = &drv->combos.data[i]; + for (i = 0; i < drv_array_size(drv->combos); i++) { + curr = drv_array_at_idx(drv->combos, i); if ((format == curr->format) && use_flags == (curr->use_flags & use_flags)) if (!best || best->metadata.priority < curr->metadata.priority) best = curr; @@ -357,7 +367,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) seek_end = lseek(data->fds[plane], 0, SEEK_END); if (seek_end == (off_t)(-1)) { - fprintf(stderr, "drv: lseek() failed with %s\n", strerror(errno)); + drv_log("lseek() failed with %s\n", strerror(errno)); goto destroy_bo; } @@ -368,7 +378,7 @@ struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) bo->sizes[plane] = data->offsets[plane + 1] - data->offsets[plane]; if ((int64_t)bo->offsets[plane] + bo->sizes[plane] > seek_end) { - fprintf(stderr, "drv: buffer size is too large.\n"); + drv_log("buffer size is too large.\n"); goto destroy_bo; } @@ -382,78 +392,102 @@ destroy_bo: return NULL; } -void *drv_bo_map(struct bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, - uint32_t map_flags, struct mapping **map_data, size_t plane) +void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags, + struct mapping **map_data, size_t plane) { - void *ptr; + uint32_t i; uint8_t *addr; - size_t offset; - struct mapping *mapping; + struct mapping mapping; - assert(width > 0); - assert(height > 0); - assert(x + width <= drv_bo_get_width(bo)); - assert(y + height <= drv_bo_get_height(bo)); + assert(rect->width >= 0); + assert(rect->height >= 0); + assert(rect->x + rect->width <= drv_bo_get_width(bo)); + assert(rect->y + rect->height <= drv_bo_get_height(bo)); assert(BO_MAP_READ_WRITE & map_flags); /* No CPU access for protected buffers. */ assert(!(bo->use_flags & BO_USE_PROTECTED)); + memset(&mapping, 0, sizeof(mapping)); + mapping.rect = *rect; + mapping.refcount = 1; + pthread_mutex_lock(&bo->drv->driver_lock); - if (!drmHashLookup(bo->drv->map_table, bo->handles[plane].u32, &ptr)) { - mapping = (struct mapping *)ptr; - /* TODO(gsingh): support mapping same buffer with different flags. */ - assert(mapping->vma->map_flags == map_flags); - mapping->vma->refcount++; + for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { + struct mapping *prior = (struct mapping *)drv_array_at_idx(bo->drv->mappings, i); + if (prior->vma->handle != bo->handles[plane].u32 || + prior->vma->map_flags != map_flags) + continue; + + if (rect->x != prior->rect.x || rect->y != prior->rect.y || + rect->width != prior->rect.width || rect->height != prior->rect.height) + continue; + + prior->refcount++; + *map_data = prior; + goto exact_match; + } + + for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { + struct mapping *prior = (struct mapping *)drv_array_at_idx(bo->drv->mappings, i); + if (prior->vma->handle != bo->handles[plane].u32 || + prior->vma->map_flags != map_flags) + continue; + + prior->vma->refcount++; + mapping.vma = prior->vma; goto success; } - mapping = calloc(1, sizeof(*mapping)); - mapping->vma = calloc(1, sizeof(*mapping->vma)); - addr = bo->drv->backend->bo_map(bo, mapping, plane, map_flags); + mapping.vma = calloc(1, sizeof(*mapping.vma)); + memcpy(mapping.vma->map_strides, bo->strides, sizeof(mapping.vma->map_strides)); + addr = bo->drv->backend->bo_map(bo, mapping.vma, plane, map_flags); if (addr == MAP_FAILED) { *map_data = NULL; - free(mapping->vma); - free(mapping); + free(mapping.vma); pthread_mutex_unlock(&bo->drv->driver_lock); return MAP_FAILED; } - mapping->vma->refcount = 1; - mapping->vma->addr = addr; - mapping->vma->handle = bo->handles[plane].u32; - mapping->vma->map_flags = map_flags; - drmHashInsert(bo->drv->map_table, bo->handles[plane].u32, (void *)mapping); + mapping.vma->refcount = 1; + mapping.vma->addr = addr; + mapping.vma->handle = bo->handles[plane].u32; + mapping.vma->map_flags = map_flags; success: - drv_bo_invalidate(bo, mapping); - *map_data = mapping; - offset = drv_bo_get_plane_stride(bo, plane) * y; - offset += drv_stride_from_format(bo->format, x, plane); - addr = (uint8_t *)mapping->vma->addr; - addr += drv_bo_get_plane_offset(bo, plane) + offset; + *map_data = drv_array_append(bo->drv->mappings, &mapping); +exact_match: + drv_bo_invalidate(bo, *map_data); + addr = (uint8_t *)((*map_data)->vma->addr); + addr += drv_bo_get_plane_offset(bo, plane); pthread_mutex_unlock(&bo->drv->driver_lock); - return (void *)addr; } int drv_bo_unmap(struct bo *bo, struct mapping *mapping) { - int ret = drv_bo_flush(bo, mapping); - if (ret) - return ret; + uint32_t i; + int ret = 0; pthread_mutex_lock(&bo->drv->driver_lock); + if (--mapping->refcount) + goto out; + if (!--mapping->vma->refcount) { - ret = bo->drv->backend->bo_unmap(bo, mapping); - drmHashDelete(bo->drv->map_table, mapping->vma->handle); + ret = bo->drv->backend->bo_unmap(bo, mapping->vma); free(mapping->vma); - free(mapping); } - pthread_mutex_unlock(&bo->drv->driver_lock); + for (i = 0; i < drv_array_size(bo->drv->mappings); i++) { + if (mapping == (struct mapping *)drv_array_at_idx(bo->drv->mappings, i)) { + drv_array_remove(bo->drv->mappings, i); + break; + } + } +out: + pthread_mutex_unlock(&bo->drv->driver_lock); return ret; } @@ -463,6 +497,7 @@ int drv_bo_invalidate(struct bo *bo, struct mapping *mapping) assert(mapping); assert(mapping->vma); + assert(mapping->refcount > 0); assert(mapping->vma->refcount > 0); if (bo->drv->backend->bo_invalidate) @@ -471,17 +506,20 @@ int drv_bo_invalidate(struct bo *bo, struct mapping *mapping) return ret; } -int drv_bo_flush(struct bo *bo, struct mapping *mapping) +int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping) { int ret = 0; assert(mapping); assert(mapping->vma); + assert(mapping->refcount > 0); assert(mapping->vma->refcount > 0); assert(!(bo->use_flags & BO_USE_PROTECTED)); if (bo->drv->backend->bo_flush) ret = bo->drv->backend->bo_flush(bo, mapping); + else + ret = drv_bo_unmap(bo, mapping); return ret; } @@ -523,6 +561,10 @@ int drv_bo_get_plane_fd(struct bo *bo, size_t plane) ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC | DRM_RDWR, &fd); + // Older DRM implementations blocked DRM_RDWR, but gave a read/write mapping anyways + if (ret) + ret = drmPrimeHandleToFD(bo->drv->fd, bo->handles[plane].u32, DRM_CLOEXEC, &fd); + return (ret) ? ret : fd; } @@ -563,69 +605,6 @@ uint32_t drv_resolve_format(struct driver *drv, uint32_t format, uint64_t use_fl return format; } -size_t drv_num_planes_from_format(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_ABGR1555: - case DRM_FORMAT_ABGR2101010: - case DRM_FORMAT_ABGR4444: - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_ARGB1555: - case DRM_FORMAT_ARGB2101010: - case DRM_FORMAT_ARGB4444: - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_AYUV: - case DRM_FORMAT_BGR233: - case DRM_FORMAT_BGR565: - case DRM_FORMAT_BGR888: - case DRM_FORMAT_BGRA1010102: - case DRM_FORMAT_BGRA4444: - case DRM_FORMAT_BGRA5551: - case DRM_FORMAT_BGRA8888: - case DRM_FORMAT_BGRX1010102: - case DRM_FORMAT_BGRX4444: - case DRM_FORMAT_BGRX5551: - case DRM_FORMAT_BGRX8888: - case DRM_FORMAT_C8: - case DRM_FORMAT_GR88: - case DRM_FORMAT_R8: - case DRM_FORMAT_RG88: - case DRM_FORMAT_RGB332: - case DRM_FORMAT_RGB565: - case DRM_FORMAT_RGB888: - case DRM_FORMAT_RGBA1010102: - case DRM_FORMAT_RGBA4444: - case DRM_FORMAT_RGBA5551: - case DRM_FORMAT_RGBA8888: - case DRM_FORMAT_RGBX1010102: - case DRM_FORMAT_RGBX4444: - case DRM_FORMAT_RGBX5551: - case DRM_FORMAT_RGBX8888: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VYUY: - case DRM_FORMAT_XBGR1555: - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_XBGR4444: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_XRGB1555: - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_XRGB4444: - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_YUYV: - case DRM_FORMAT_YVYU: - return 1; - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - return 2; - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YVU420_ANDROID: - return 3; - } - - fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format); - return 0; -} - uint32_t drv_num_buffers_per_bo(struct bo *bo) { uint32_t count = 0; @@ -641,3 +620,19 @@ uint32_t drv_num_buffers_per_bo(struct bo *bo) return count; } + +void drv_log_prefix(const char *prefix, const char *file, int line, const char *format, ...) +{ + char buf[50]; + snprintf(buf, sizeof(buf), "[%s:%s(%d)]", prefix, basename(file), line); + + va_list args; + va_start(args, format); +#ifdef __ANDROID__ + __android_log_vprint(ANDROID_LOG_ERROR, buf, format, args); +#else + fprintf(stderr, "%s ", buf); + vfprintf(stderr, format, args); +#endif + va_end(args); +}