X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=drv.c;h=d5484482102c59edeca088d56abd42ca4d86a7b8;hb=3381588d35f78e1c1d3f3fac3927f3cde9462e66;hp=cb54a93553c487a255e8cb955843c8cbcbf7ac2b;hpb=47e629b70ddec014c7691a48509ef437c57761bb;p=android-x86%2Fexternal-minigbm.git diff --git a/drv.c b/drv.c index cb54a93..d548448 100644 --- a/drv.c +++ b/drv.c @@ -27,7 +27,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 +36,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 +77,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 +86,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 +142,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 +179,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 +207,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; @@ -382,78 +387,103 @@ 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)); + 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) { + uint32_t i; int ret = drv_bo_flush(bo, mapping); if (ret) return ret; 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 +493,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) @@ -477,6 +508,7 @@ int drv_bo_flush(struct bo *bo, struct mapping *mapping) assert(mapping); assert(mapping->vma); + assert(mapping->refcount > 0); assert(mapping->vma->refcount > 0); assert(!(bo->use_flags & BO_USE_PROTECTED));