| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 1 | /* | 
| Daniele Castagna | 7a755de | 2016-12-16 17:32:30 -0500 | [diff] [blame] | 2 | * Copyright 2014 The Chromium OS Authors. All rights reserved. | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 3 | * Use of this source code is governed by a BSD-style license that can be | 
|  | 4 | * found in the LICENSE file. | 
|  | 5 | */ | 
|  | 6 |  | 
| Yuly Novikov | 96c7a3b | 2015-12-08 22:48:29 -0500 | [diff] [blame] | 7 | #include <assert.h> | 
| Dominik Behr | f7b33d7 | 2014-11-11 07:17:11 -0800 | [diff] [blame] | 8 | #include <fcntl.h> | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 9 | #include <stdint.h> | 
|  | 10 | #include <stdio.h> | 
|  | 11 | #include <stdlib.h> | 
|  | 12 | #include <string.h> | 
| Gurchetan Singh | 1ef809e | 2017-11-06 11:07:52 -0800 | [diff] [blame] | 13 | #include <sys/mman.h> | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 14 | #include <xf86drm.h> | 
|  | 15 |  | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 16 | #include "drv.h" | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 17 | #include "gbm_helpers.h" | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 18 | #include "gbm_priv.h" | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 19 | #include "util.h" | 
|  | 20 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 21 | PUBLIC int gbm_device_get_fd(struct gbm_device *gbm) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 22 | { | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 23 |  | 
|  | 24 | return drv_get_fd(gbm->drv); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 25 | } | 
|  | 26 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 27 | PUBLIC const char *gbm_device_get_backend_name(struct gbm_device *gbm) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 28 | { | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 29 | return drv_get_name(gbm->drv); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 30 | } | 
|  | 31 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 32 | PUBLIC int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t format, uint32_t usage) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 33 | { | 
| Gurchetan Singh | a1892b2 | 2017-09-28 16:40:52 -0700 | [diff] [blame] | 34 | uint64_t use_flags; | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 35 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 36 | if (usage & GBM_BO_USE_CURSOR && usage & GBM_BO_USE_RENDERING) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 37 | return 0; | 
|  | 38 |  | 
| Gurchetan Singh | a1892b2 | 2017-09-28 16:40:52 -0700 | [diff] [blame] | 39 | use_flags = gbm_convert_usage(usage); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 40 |  | 
| Gurchetan Singh | a1892b2 | 2017-09-28 16:40:52 -0700 | [diff] [blame] | 41 | return (drv_get_combination(gbm->drv, format, use_flags) != NULL); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 42 | } | 
|  | 43 |  | 
| Gurchetan Singh | 1cfdc31 | 2019-12-06 10:24:53 -0800 | [diff] [blame] | 44 | PUBLIC int gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm, uint32_t format, | 
|  | 45 | uint64_t modifier) | 
|  | 46 | { | 
|  | 47 | return 0; | 
|  | 48 | } | 
|  | 49 |  | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 50 | PUBLIC struct gbm_device *gbm_create_device(int fd) | 
|  | 51 | { | 
|  | 52 | struct gbm_device *gbm; | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 53 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 54 | gbm = (struct gbm_device *)malloc(sizeof(*gbm)); | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 55 |  | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 56 | if (!gbm) | 
|  | 57 | return NULL; | 
|  | 58 |  | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 59 | gbm->drv = drv_create(fd); | 
|  | 60 | if (!gbm->drv) { | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 61 | free(gbm); | 
|  | 62 | return NULL; | 
|  | 63 | } | 
|  | 64 |  | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 65 | return gbm; | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | PUBLIC void gbm_device_destroy(struct gbm_device *gbm) | 
|  | 69 | { | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 70 | drv_destroy(gbm->drv); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 71 | free(gbm); | 
|  | 72 | } | 
|  | 73 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 74 | PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t width, | 
| Gurchetan Singh | a1892b2 | 2017-09-28 16:40:52 -0700 | [diff] [blame] | 75 | uint32_t height, uint32_t format, uint32_t usage) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 76 | { | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 77 | struct gbm_surface *surface = (struct gbm_surface *)malloc(sizeof(*surface)); | 
| Stéphane Marchesin | ec88e89 | 2015-11-03 16:14:59 -0800 | [diff] [blame] | 78 |  | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 79 | if (!surface) | 
|  | 80 | return NULL; | 
|  | 81 |  | 
|  | 82 | return surface; | 
|  | 83 | } | 
|  | 84 |  | 
| Gurchetan Singh | 1cfdc31 | 2019-12-06 10:24:53 -0800 | [diff] [blame] | 85 | PUBLIC struct gbm_surface *gbm_surface_create_with_modifiers(struct gbm_device *gbm, uint32_t width, | 
|  | 86 | uint32_t height, uint32_t format, | 
|  | 87 | const uint64_t *modifiers, | 
|  | 88 | const unsigned int count) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 89 | { | 
| Gurchetan Singh | 1cfdc31 | 2019-12-06 10:24:53 -0800 | [diff] [blame] | 90 | if (count != 0 || modifiers != NULL) | 
|  | 91 | return NULL; | 
|  | 92 |  | 
|  | 93 | return gbm_surface_create(gbm, width, height, format, 0); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 94 | } | 
|  | 95 |  | 
|  | 96 | PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface) | 
|  | 97 | { | 
|  | 98 | return NULL; | 
|  | 99 | } | 
|  | 100 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 101 | PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 102 | { | 
|  | 103 | } | 
|  | 104 |  | 
| Gurchetan Singh | 1cfdc31 | 2019-12-06 10:24:53 -0800 | [diff] [blame] | 105 | PUBLIC int gbm_surface_has_free_buffers(struct gbm_surface *surface) | 
|  | 106 | { | 
|  | 107 | return 0; | 
|  | 108 | } | 
|  | 109 |  | 
|  | 110 | PUBLIC void gbm_surface_destroy(struct gbm_surface *surface) | 
|  | 111 | { | 
|  | 112 | free(surface); | 
|  | 113 | } | 
|  | 114 |  | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 115 | static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t format) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 116 | { | 
|  | 117 | struct gbm_bo *bo; | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 118 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 119 | bo = (struct gbm_bo *)calloc(1, sizeof(*bo)); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 120 | if (!bo) | 
|  | 121 | return NULL; | 
|  | 122 |  | 
|  | 123 | bo->gbm = gbm; | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 124 | bo->gbm_format = format; | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 125 |  | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 126 | return bo; | 
|  | 127 | } | 
|  | 128 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 129 | PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, | 
| Gurchetan Singh | a1892b2 | 2017-09-28 16:40:52 -0700 | [diff] [blame] | 130 | uint32_t format, uint32_t usage) | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 131 | { | 
|  | 132 | struct gbm_bo *bo; | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 133 |  | 
| Gurchetan Singh | a1892b2 | 2017-09-28 16:40:52 -0700 | [diff] [blame] | 134 | if (!gbm_device_is_format_supported(gbm, format, usage)) | 
| Yuly Novikov | 96c7a3b | 2015-12-08 22:48:29 -0500 | [diff] [blame] | 135 | return NULL; | 
|  | 136 |  | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 137 | bo = gbm_bo_new(gbm, format); | 
|  | 138 |  | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 139 | if (!bo) | 
|  | 140 | return NULL; | 
|  | 141 |  | 
| Gurchetan Singh | c062c3b | 2019-06-20 20:48:01 -0700 | [diff] [blame] | 142 | /* | 
|  | 143 | * HACK: This is for HAL_PIXEL_FORMAT_YV12 buffers allocated by arcvm. | 
|  | 144 | * None of our platforms can display YV12, so we can treat as a SW buffer. | 
|  | 145 | * Remove once this can be intelligently resolved in the guest. | 
|  | 146 | */ | 
|  | 147 | if (format == GBM_FORMAT_YVU420 && (usage & GBM_BO_USE_LINEAR)) | 
|  | 148 | format = DRM_FORMAT_YVU420_ANDROID; | 
|  | 149 |  | 
| Gurchetan Singh | a1892b2 | 2017-09-28 16:40:52 -0700 | [diff] [blame] | 150 | bo->bo = drv_bo_create(gbm->drv, width, height, format, gbm_convert_usage(usage)); | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 151 |  | 
|  | 152 | if (!bo->bo) { | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 153 | free(bo); | 
|  | 154 | return NULL; | 
|  | 155 | } | 
|  | 156 |  | 
|  | 157 | return bo; | 
|  | 158 | } | 
|  | 159 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 160 | PUBLIC struct gbm_bo *gbm_bo_create_with_modifiers(struct gbm_device *gbm, uint32_t width, | 
|  | 161 | uint32_t height, uint32_t format, | 
|  | 162 | const uint64_t *modifiers, uint32_t count) | 
| Kristian H. Kristensen | b1efbd8 | 2016-09-06 11:43:26 -0700 | [diff] [blame] | 163 | { | 
|  | 164 | struct gbm_bo *bo; | 
|  | 165 |  | 
|  | 166 | bo = gbm_bo_new(gbm, format); | 
|  | 167 |  | 
|  | 168 | if (!bo) | 
|  | 169 | return NULL; | 
|  | 170 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 171 | bo->bo = drv_bo_create_with_modifiers(gbm->drv, width, height, format, modifiers, count); | 
| Kristian H. Kristensen | b1efbd8 | 2016-09-06 11:43:26 -0700 | [diff] [blame] | 172 |  | 
|  | 173 | if (!bo->bo) { | 
|  | 174 | free(bo); | 
|  | 175 | return NULL; | 
|  | 176 | } | 
|  | 177 |  | 
|  | 178 | return bo; | 
|  | 179 | } | 
|  | 180 |  | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 181 | PUBLIC void gbm_bo_destroy(struct gbm_bo *bo) | 
|  | 182 | { | 
|  | 183 | if (bo->destroy_user_data) { | 
|  | 184 | bo->destroy_user_data(bo, bo->user_data); | 
|  | 185 | bo->destroy_user_data = NULL; | 
|  | 186 | bo->user_data = NULL; | 
|  | 187 | } | 
|  | 188 |  | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 189 | drv_bo_destroy(bo->bo); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 190 | free(bo); | 
|  | 191 | } | 
|  | 192 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 193 | PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer, | 
|  | 194 | uint32_t usage) | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 195 | { | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 196 | struct gbm_bo *bo; | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 197 | struct drv_import_fd_data drv_data; | 
|  | 198 | struct gbm_import_fd_data *fd_data = buffer; | 
| Maksim Sisov | 4fe3038 | 2019-01-07 15:11:47 +0200 | [diff] [blame] | 199 | struct gbm_import_fd_modifier_data *fd_modifier_data = buffer; | 
| Kristian H. Kristensen | 3345977 | 2016-09-16 11:14:16 -0700 | [diff] [blame] | 200 | uint32_t gbm_format; | 
| Maksim Sisov | 4fe3038 | 2019-01-07 15:11:47 +0200 | [diff] [blame] | 201 | size_t num_planes, i, num_fds; | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 202 |  | 
| Kristian H. Kristensen | 3345977 | 2016-09-16 11:14:16 -0700 | [diff] [blame] | 203 | memset(&drv_data, 0, sizeof(drv_data)); | 
| Gurchetan Singh | a1892b2 | 2017-09-28 16:40:52 -0700 | [diff] [blame] | 204 | drv_data.use_flags = gbm_convert_usage(usage); | 
| Kristian H. Kristensen | 3345977 | 2016-09-16 11:14:16 -0700 | [diff] [blame] | 205 | switch (type) { | 
|  | 206 | case GBM_BO_IMPORT_FD: | 
|  | 207 | gbm_format = fd_data->format; | 
|  | 208 | drv_data.width = fd_data->width; | 
|  | 209 | drv_data.height = fd_data->height; | 
| Gurchetan Singh | f3b22da | 2016-11-21 10:46:38 -0800 | [diff] [blame] | 210 | drv_data.format = fd_data->format; | 
| Kristian H. Kristensen | 3345977 | 2016-09-16 11:14:16 -0700 | [diff] [blame] | 211 | drv_data.fds[0] = fd_data->fd; | 
|  | 212 | drv_data.strides[0] = fd_data->stride; | 
| ChromeOS Developer | 9b367b3 | 2020-03-02 13:08:53 +0100 | [diff] [blame] | 213 |  | 
|  | 214 | for (i = 0; i < GBM_MAX_PLANES; ++i) | 
|  | 215 | drv_data.format_modifiers[i] = DRM_FORMAT_MOD_INVALID; | 
| Kristian H. Kristensen | 3345977 | 2016-09-16 11:14:16 -0700 | [diff] [blame] | 216 | break; | 
| Maksim Sisov | 4fe3038 | 2019-01-07 15:11:47 +0200 | [diff] [blame] | 217 | case GBM_BO_IMPORT_FD_MODIFIER: | 
|  | 218 | gbm_format = fd_modifier_data->format; | 
|  | 219 | drv_data.width = fd_modifier_data->width; | 
|  | 220 | drv_data.height = fd_modifier_data->height; | 
|  | 221 | drv_data.format = fd_modifier_data->format; | 
| ChromeOS Developer | 44588bb | 2020-03-02 16:32:09 +0100 | [diff] [blame] | 222 | num_planes = drv_num_planes_from_modifier(gbm->drv, drv_data.format, | 
|  | 223 | fd_modifier_data->modifier); | 
| Mark Yacoub | 769de64 | 2019-07-09 13:59:50 -0400 | [diff] [blame] | 224 | assert(num_planes); | 
| Maksim Sisov | 4fe3038 | 2019-01-07 15:11:47 +0200 | [diff] [blame] | 225 |  | 
| Mark Yacoub | 769de64 | 2019-07-09 13:59:50 -0400 | [diff] [blame] | 226 | num_fds = fd_modifier_data->num_fds; | 
|  | 227 | if (!num_fds || num_fds > num_planes) | 
|  | 228 | return NULL; | 
|  | 229 |  | 
| Maksim Sisov | 4fe3038 | 2019-01-07 15:11:47 +0200 | [diff] [blame] | 230 | for (i = 0; i < num_planes; i++) { | 
|  | 231 | if (num_fds != num_planes) | 
|  | 232 | drv_data.fds[i] = fd_modifier_data->fds[0]; | 
|  | 233 | else | 
|  | 234 | drv_data.fds[i] = fd_modifier_data->fds[i]; | 
|  | 235 | drv_data.offsets[i] = fd_modifier_data->offsets[i]; | 
|  | 236 | drv_data.strides[i] = fd_modifier_data->strides[i]; | 
|  | 237 | drv_data.format_modifiers[i] = fd_modifier_data->modifier; | 
|  | 238 | } | 
|  | 239 |  | 
|  | 240 | for (i = num_planes; i < GBM_MAX_PLANES; i++) | 
|  | 241 | drv_data.fds[i] = -1; | 
|  | 242 |  | 
|  | 243 | break; | 
| Kristian H. Kristensen | 3345977 | 2016-09-16 11:14:16 -0700 | [diff] [blame] | 244 | default: | 
|  | 245 | return NULL; | 
|  | 246 | } | 
|  | 247 |  | 
|  | 248 | if (!gbm_device_is_format_supported(gbm, gbm_format, usage)) | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 249 | return NULL; | 
|  | 250 |  | 
| Kristian H. Kristensen | 3345977 | 2016-09-16 11:14:16 -0700 | [diff] [blame] | 251 | bo = gbm_bo_new(gbm, gbm_format); | 
| Yuly Novikov | 96c7a3b | 2015-12-08 22:48:29 -0500 | [diff] [blame] | 252 |  | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 253 | if (!bo) | 
|  | 254 | return NULL; | 
|  | 255 |  | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 256 | bo->bo = drv_bo_import(gbm->drv, &drv_data); | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 257 |  | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 258 | if (!bo->bo) { | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 259 | free(bo); | 
|  | 260 | return NULL; | 
|  | 261 | } | 
|  | 262 |  | 
| Stéphane Marchesin | f4bfdba | 2015-11-05 11:43:59 -0800 | [diff] [blame] | 263 | return bo; | 
|  | 264 | } | 
|  | 265 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 266 | PUBLIC void gbm_bo_unmap(struct gbm_bo *bo, void *map_data) | 
| Gurchetan Singh | 5753c31 | 2016-10-05 15:16:22 -0700 | [diff] [blame] | 267 | { | 
|  | 268 | assert(bo); | 
| Gurchetan Singh | bd1b1b5 | 2018-03-29 16:34:53 -0700 | [diff] [blame] | 269 | drv_bo_flush_or_unmap(bo->bo, map_data); | 
| Gurchetan Singh | 5753c31 | 2016-10-05 15:16:22 -0700 | [diff] [blame] | 270 | } | 
|  | 271 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 272 | PUBLIC uint32_t gbm_bo_get_width(struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 273 | { | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 274 | return drv_bo_get_width(bo->bo); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 275 | } | 
|  | 276 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 277 | PUBLIC uint32_t gbm_bo_get_height(struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 278 | { | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 279 | return drv_bo_get_height(bo->bo); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 280 | } | 
|  | 281 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 282 | PUBLIC uint32_t gbm_bo_get_stride(struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 283 | { | 
| Keiichi Watanabe | 79155d7 | 2018-08-13 16:44:54 +0900 | [diff] [blame] | 284 | return gbm_bo_get_stride_for_plane(bo, 0); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 285 | } | 
|  | 286 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 287 | PUBLIC uint32_t gbm_bo_get_format(struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 288 | { | 
| Gurchetan Singh | 46faf6b | 2016-08-05 14:40:07 -0700 | [diff] [blame] | 289 | return bo->gbm_format; | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 290 | } | 
|  | 291 |  | 
| Gurchetan Singh | 1cfdc31 | 2019-12-06 10:24:53 -0800 | [diff] [blame] | 292 | PUBLIC uint32_t gbm_bo_get_bpp(struct gbm_bo *bo) | 
|  | 293 | { | 
|  | 294 | return drv_bytes_per_pixel_from_format(drv_bo_get_format(bo->bo), 0); | 
|  | 295 | } | 
|  | 296 |  | 
| Maksim Sisov | 79205a5 | 2018-08-03 16:31:20 +0300 | [diff] [blame] | 297 | PUBLIC uint64_t gbm_bo_get_modifier(struct gbm_bo *bo) | 
|  | 298 | { | 
| Gurchetan Singh | e32ec0b | 2019-12-06 09:52:03 -0800 | [diff] [blame] | 299 | return drv_bo_get_plane_format_modifier(bo->bo, 0); | 
| Vince Hsu | a6878fe | 2016-05-23 10:32:25 +0800 | [diff] [blame] | 300 | } | 
|  | 301 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 302 | PUBLIC struct gbm_device *gbm_bo_get_device(struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 303 | { | 
|  | 304 | return bo->gbm; | 
|  | 305 | } | 
|  | 306 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 307 | PUBLIC union gbm_bo_handle gbm_bo_get_handle(struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 308 | { | 
| Maksim Sisov | ff1ecaf | 2018-08-10 14:53:34 +0300 | [diff] [blame] | 309 | return gbm_bo_get_handle_for_plane(bo, 0); | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 310 | } | 
|  | 311 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 312 | PUBLIC int gbm_bo_get_fd(struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 313 | { | 
| Yuly Novikov | 96c7a3b | 2015-12-08 22:48:29 -0500 | [diff] [blame] | 314 | return gbm_bo_get_plane_fd(bo, 0); | 
|  | 315 | } | 
| Stéphane Marchesin | 5bb6adc | 2014-11-05 20:21:25 -0800 | [diff] [blame] | 316 |  | 
| Gurchetan Singh | e32ec0b | 2019-12-06 09:52:03 -0800 | [diff] [blame] | 317 | PUBLIC int gbm_bo_get_plane_count(struct gbm_bo *bo) | 
| Maksim Sisov | 79205a5 | 2018-08-03 16:31:20 +0300 | [diff] [blame] | 318 | { | 
| Keiichi Watanabe | 79155d7 | 2018-08-13 16:44:54 +0900 | [diff] [blame] | 319 | return drv_bo_get_num_planes(bo->bo); | 
| Yuly Novikov | 96c7a3b | 2015-12-08 22:48:29 -0500 | [diff] [blame] | 320 | } | 
|  | 321 |  | 
| Gurchetan Singh | 2b1d689 | 2018-09-17 16:58:16 -0700 | [diff] [blame] | 322 | PUBLIC union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo *bo, size_t plane) | 
| Maksim Sisov | ff1ecaf | 2018-08-10 14:53:34 +0300 | [diff] [blame] | 323 | { | 
| Gurchetan Singh | e32ec0b | 2019-12-06 09:52:03 -0800 | [diff] [blame] | 324 | return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, (size_t)plane).u64; | 
| Maksim Sisov | 79205a5 | 2018-08-03 16:31:20 +0300 | [diff] [blame] | 325 | } | 
|  | 326 |  | 
|  | 327 | PUBLIC uint32_t gbm_bo_get_offset(struct gbm_bo *bo, size_t plane) | 
|  | 328 | { | 
| Gurchetan Singh | e32ec0b | 2019-12-06 09:52:03 -0800 | [diff] [blame] | 329 | return drv_bo_get_plane_offset(bo->bo, (size_t)plane); | 
| Maksim Sisov | 79205a5 | 2018-08-03 16:31:20 +0300 | [diff] [blame] | 330 | } | 
|  | 331 |  | 
|  | 332 | PUBLIC uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, size_t plane) | 
|  | 333 | { | 
| Gurchetan Singh | e32ec0b | 2019-12-06 09:52:03 -0800 | [diff] [blame] | 334 | return drv_bo_get_plane_stride(bo->bo, (size_t)plane); | 
| Vince Hsu | a6878fe | 2016-05-23 10:32:25 +0800 | [diff] [blame] | 335 | } | 
|  | 336 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 337 | PUBLIC void gbm_bo_set_user_data(struct gbm_bo *bo, void *data, | 
|  | 338 | void (*destroy_user_data)(struct gbm_bo *, void *)) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 339 | { | 
|  | 340 | bo->user_data = data; | 
|  | 341 | bo->destroy_user_data = destroy_user_data; | 
|  | 342 | } | 
|  | 343 |  | 
| Gurchetan Singh | 1b1d56a | 2017-03-10 16:25:23 -0800 | [diff] [blame] | 344 | PUBLIC void *gbm_bo_get_user_data(struct gbm_bo *bo) | 
| Stéphane Marchesin | 25a2606 | 2014-09-12 16:18:59 -0700 | [diff] [blame] | 345 | { | 
|  | 346 | return bo->user_data; | 
|  | 347 | } | 
| Gurchetan Singh | e32ec0b | 2019-12-06 09:52:03 -0800 | [diff] [blame] | 348 |  | 
| Gurchetan Singh | 1cfdc31 | 2019-12-06 10:24:53 -0800 | [diff] [blame] | 349 | /* The two GBM_BO_FORMAT_[XA]RGB8888 formats alias the GBM_FORMAT_* | 
|  | 350 | * formats of the same name. We want to accept them whenever someone | 
|  | 351 | * has a GBM format, but never return them to the user. | 
|  | 352 | */ | 
|  | 353 | static uint32_t gbm_format_canonicalize(uint32_t gbm_format) | 
|  | 354 | { | 
|  | 355 | switch (gbm_format) { | 
|  | 356 | case GBM_BO_FORMAT_XRGB8888: | 
|  | 357 | return GBM_FORMAT_XRGB8888; | 
|  | 358 | case GBM_BO_FORMAT_ARGB8888: | 
|  | 359 | return GBM_FORMAT_ARGB8888; | 
|  | 360 | default: | 
|  | 361 | return gbm_format; | 
|  | 362 | } | 
|  | 363 | } | 
|  | 364 |  | 
|  | 365 | /** | 
|  | 366 | * Returns a string representing the fourcc format name. | 
|  | 367 | */ | 
|  | 368 | PUBLIC char *gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc) | 
|  | 369 | { | 
|  | 370 | gbm_format = gbm_format_canonicalize(gbm_format); | 
|  | 371 |  | 
|  | 372 | desc->name[0] = gbm_format; | 
|  | 373 | desc->name[1] = gbm_format >> 8; | 
|  | 374 | desc->name[2] = gbm_format >> 16; | 
|  | 375 | desc->name[3] = gbm_format >> 24; | 
|  | 376 | desc->name[4] = 0; | 
|  | 377 |  | 
|  | 378 | return desc->name; | 
|  | 379 | } | 
|  | 380 |  | 
| Gurchetan Singh | e32ec0b | 2019-12-06 09:52:03 -0800 | [diff] [blame] | 381 | /* | 
|  | 382 | * The following functions are not deprecated, but not in the Mesa the gbm | 
|  | 383 | * header. The main difference is minigbm allows for the possibility of | 
|  | 384 | * disjoint YUV images, while Mesa GBM does not. | 
|  | 385 | */ | 
|  | 386 | PUBLIC uint32_t gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane) | 
|  | 387 | { | 
|  | 388 | return drv_bo_get_plane_size(bo->bo, plane); | 
|  | 389 | } | 
|  | 390 |  | 
|  | 391 | PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane) | 
|  | 392 | { | 
|  | 393 | return drv_bo_get_plane_fd(bo->bo, plane); | 
|  | 394 | } | 
|  | 395 |  | 
|  | 396 | PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, | 
|  | 397 | uint32_t transfer_flags, uint32_t *stride, void **map_data, size_t plane) | 
|  | 398 | { | 
| Gurchetan Singh | 064a36b | 2019-12-12 10:20:41 -0800 | [diff] [blame] | 399 | return gbm_bo_map2(bo, x, y, width, height, transfer_flags, stride, map_data, plane); | 
|  | 400 | } | 
|  | 401 |  | 
|  | 402 | PUBLIC void *gbm_bo_map2(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, | 
|  | 403 | uint32_t transfer_flags, uint32_t *stride, void **map_data, int plane) | 
|  | 404 | { | 
| Gurchetan Singh | e32ec0b | 2019-12-06 09:52:03 -0800 | [diff] [blame] | 405 | void *addr; | 
|  | 406 | off_t offset; | 
|  | 407 | uint32_t map_flags; | 
|  | 408 | plane = (size_t)plane; | 
|  | 409 | struct rectangle rect = { .x = x, .y = y, .width = width, .height = height }; | 
|  | 410 | if (!bo || width == 0 || height == 0 || !stride || !map_data) | 
|  | 411 | return NULL; | 
|  | 412 |  | 
|  | 413 | map_flags = (transfer_flags & GBM_BO_TRANSFER_READ) ? BO_MAP_READ : BO_MAP_NONE; | 
|  | 414 | map_flags |= (transfer_flags & GBM_BO_TRANSFER_WRITE) ? BO_MAP_WRITE : BO_MAP_NONE; | 
|  | 415 |  | 
|  | 416 | addr = drv_bo_map(bo->bo, &rect, map_flags, (struct mapping **)map_data, plane); | 
|  | 417 | if (addr == MAP_FAILED) | 
|  | 418 | return MAP_FAILED; | 
|  | 419 |  | 
|  | 420 | *stride = ((struct mapping *)*map_data)->vma->map_strides[plane]; | 
|  | 421 |  | 
|  | 422 | offset = *stride * rect.y; | 
|  | 423 | offset += rect.x * drv_bytes_per_pixel_from_format(bo->gbm_format, plane); | 
|  | 424 | return (void *)((uint8_t *)addr + offset); | 
|  | 425 | } |