diff options
author | Ville Syrjälä | 2012-05-18 07:52:09 -0500 |
---|---|---|
committer | Sean Paul | 2015-04-17 15:16:05 -0500 |
commit | ba5b0e9d9a3c894673b68b14cc82f53df32bbce8 (patch) | |
tree | bad6288a951187c89e1ac495b61d71af8e64f59f | |
parent | c12a1a7cc6fef927b9d3dc92c1a6a5eb30ee04a1 (diff) | |
download | external-libdrm-ba5b0e9d9a3c894673b68b14cc82f53df32bbce8.tar.gz external-libdrm-ba5b0e9d9a3c894673b68b14cc82f53df32bbce8.tar.xz external-libdrm-ba5b0e9d9a3c894673b68b14cc82f53df32bbce8.zip |
BACKPORT: libdrm: atomic mode set
(cherry picked from commit fb8403c23edb3e06c979115b7b0cce2ba5099aa2)
Signed-off-by: Sean Paul <seanpaul@chromium.org>
-rw-r--r-- | include/drm/drm.h | 1 | ||||
-rw-r--r-- | include/drm/drm_mode.h | 22 | ||||
-rw-r--r-- | xf86drmMode.c | 273 | ||||
-rw-r--r-- | xf86drmMode.h | 20 |
4 files changed, 316 insertions, 0 deletions
diff --git a/include/drm/drm.h b/include/drm/drm.h index 229a29f9..768b7db9 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h | |||
@@ -758,6 +758,7 @@ struct drm_prime_handle { | |||
758 | #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) | 758 | #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) |
759 | #define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) | 759 | #define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) |
760 | #define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) | 760 | #define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) |
761 | #define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic) | ||
761 | 762 | ||
762 | /** | 763 | /** |
763 | * Device specific ioctls should only be in their respective headers | 764 | * Device specific ioctls should only be in their respective headers |
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index a2ab88a5..1c3f6200 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h | |||
@@ -507,4 +507,26 @@ struct drm_mode_destroy_dumb { | |||
507 | __u32 handle; | 507 | __u32 handle; |
508 | }; | 508 | }; |
509 | 509 | ||
510 | /* page-flip flags are valid, plus: */ | ||
511 | #define DRM_MODE_ATOMIC_TEST_ONLY 0x0100 | ||
512 | #define DRM_MODE_ATOMIC_NONBLOCK 0x0200 | ||
513 | |||
514 | #define DRM_MODE_ATOMIC_FLAGS (\ | ||
515 | DRM_MODE_PAGE_FLIP_EVENT |\ | ||
516 | DRM_MODE_PAGE_FLIP_ASYNC |\ | ||
517 | DRM_MODE_ATOMIC_TEST_ONLY |\ | ||
518 | DRM_MODE_ATOMIC_NONBLOCK) | ||
519 | |||
520 | /* FIXME come up with some sane error reporting mechanism? */ | ||
521 | struct drm_mode_atomic { | ||
522 | __u32 flags; | ||
523 | __u32 count_objs; | ||
524 | __u64 objs_ptr; | ||
525 | __u64 count_props_ptr; | ||
526 | __u64 props_ptr; | ||
527 | __u64 prop_values_ptr; | ||
528 | __u64 blob_values_ptr; | ||
529 | __u64 user_data; | ||
530 | }; | ||
531 | |||
510 | #endif | 532 | #endif |
diff --git a/xf86drmMode.c b/xf86drmMode.c index 60ce3699..56762217 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <stdint.h> | 40 | #include <stdint.h> |
41 | #include <sys/ioctl.h> | 41 | #include <sys/ioctl.h> |
42 | #include <stdio.h> | 42 | #include <stdio.h> |
43 | #include <stdbool.h> | ||
43 | 44 | ||
44 | #ifdef HAVE_CONFIG_H | 45 | #ifdef HAVE_CONFIG_H |
45 | #include "config.h" | 46 | #include "config.h" |
@@ -1129,3 +1130,275 @@ int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type, | |||
1129 | 1130 | ||
1130 | return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop); | 1131 | return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop); |
1131 | } | 1132 | } |
1133 | |||
1134 | typedef struct _drmModePropertySetItem drmModePropertySetItem, *drmModePropertySetItemPtr; | ||
1135 | |||
1136 | struct _drmModePropertySetItem { | ||
1137 | uint32_t object_id; | ||
1138 | uint32_t property_id; | ||
1139 | bool is_blob; | ||
1140 | uint64_t value; | ||
1141 | void *blob; | ||
1142 | drmModePropertySetItemPtr next; | ||
1143 | }; | ||
1144 | |||
1145 | struct _drmModePropertySet { | ||
1146 | unsigned int count_objs; | ||
1147 | unsigned int count_props; | ||
1148 | unsigned int count_blobs; | ||
1149 | drmModePropertySetItem list; | ||
1150 | }; | ||
1151 | |||
1152 | drmModePropertySetPtr drmModePropertySetAlloc(void) | ||
1153 | { | ||
1154 | drmModePropertySetPtr set; | ||
1155 | |||
1156 | set = drmMalloc(sizeof *set); | ||
1157 | if (!set) | ||
1158 | return NULL; | ||
1159 | |||
1160 | set->list.next = NULL; | ||
1161 | set->count_props = 0; | ||
1162 | set->count_objs = 0; | ||
1163 | |||
1164 | return set; | ||
1165 | } | ||
1166 | |||
1167 | int drmModePropertySetAdd(drmModePropertySetPtr set, | ||
1168 | uint32_t object_id, | ||
1169 | uint32_t property_id, | ||
1170 | uint64_t value) | ||
1171 | { | ||
1172 | drmModePropertySetItemPtr prev = &set->list; | ||
1173 | bool new_obj = false; | ||
1174 | |||
1175 | /* keep it sorted by object_id and property_id */ | ||
1176 | while (prev->next) { | ||
1177 | if (prev->next->object_id > object_id) { | ||
1178 | new_obj = true; | ||
1179 | break; | ||
1180 | } | ||
1181 | |||
1182 | if (prev->next->object_id == object_id && | ||
1183 | prev->next->property_id >= property_id) | ||
1184 | break; | ||
1185 | |||
1186 | prev = prev->next; | ||
1187 | } | ||
1188 | |||
1189 | if (!prev->next && | ||
1190 | (prev == &set->list || prev->object_id != object_id)) | ||
1191 | new_obj = true; | ||
1192 | |||
1193 | /* replace or add? */ | ||
1194 | if (prev->next && | ||
1195 | prev->next->object_id == object_id && | ||
1196 | prev->next->property_id == property_id) { | ||
1197 | drmModePropertySetItemPtr item = prev->next; | ||
1198 | |||
1199 | if (item->is_blob) | ||
1200 | return -EINVAL; | ||
1201 | |||
1202 | item->value = value; | ||
1203 | } else { | ||
1204 | drmModePropertySetItemPtr item; | ||
1205 | |||
1206 | item = drmMalloc(sizeof *item); | ||
1207 | if (!item) | ||
1208 | return -1; | ||
1209 | |||
1210 | item->object_id = object_id; | ||
1211 | item->property_id = property_id; | ||
1212 | item->value = value; | ||
1213 | item->is_blob = false; | ||
1214 | item->blob = NULL; | ||
1215 | |||
1216 | item->next = prev->next; | ||
1217 | prev->next = item; | ||
1218 | |||
1219 | set->count_props++; | ||
1220 | } | ||
1221 | |||
1222 | if (new_obj) | ||
1223 | set->count_objs++; | ||
1224 | |||
1225 | return 0; | ||
1226 | } | ||
1227 | |||
1228 | int drmModePropertySetAddBlob(drmModePropertySetPtr set, | ||
1229 | uint32_t object_id, | ||
1230 | uint32_t property_id, | ||
1231 | uint64_t length, | ||
1232 | void *data) | ||
1233 | { | ||
1234 | drmModePropertySetItemPtr prev = &set->list; | ||
1235 | bool new_obj = false; | ||
1236 | |||
1237 | /* keep it sorted by object_id and property_id */ | ||
1238 | while (prev->next) { | ||
1239 | if (prev->next->object_id > object_id) { | ||
1240 | new_obj = true; | ||
1241 | break; | ||
1242 | } | ||
1243 | |||
1244 | if (prev->next->object_id == object_id && | ||
1245 | prev->next->property_id >= property_id) | ||
1246 | break; | ||
1247 | |||
1248 | prev = prev->next; | ||
1249 | } | ||
1250 | |||
1251 | if (!prev->next && | ||
1252 | (prev == &set->list || prev->object_id != object_id)) | ||
1253 | new_obj = true; | ||
1254 | |||
1255 | /* replace or add? */ | ||
1256 | if (prev->next && | ||
1257 | prev->next->object_id == object_id && | ||
1258 | prev->next->property_id == property_id) { | ||
1259 | drmModePropertySetItemPtr item = prev->next; | ||
1260 | |||
1261 | if (!item->is_blob) | ||
1262 | return -EINVAL; | ||
1263 | |||
1264 | item->value = length; | ||
1265 | item->blob = data; | ||
1266 | } else { | ||
1267 | drmModePropertySetItemPtr item; | ||
1268 | |||
1269 | item = drmMalloc(sizeof *item); | ||
1270 | if (!item) | ||
1271 | return -1; | ||
1272 | |||
1273 | item->object_id = object_id; | ||
1274 | item->property_id = property_id; | ||
1275 | item->is_blob = true; | ||
1276 | item->value = length; | ||
1277 | item->blob = data; | ||
1278 | |||
1279 | item->next = prev->next; | ||
1280 | prev->next = item; | ||
1281 | |||
1282 | set->count_props++; | ||
1283 | set->count_blobs++; | ||
1284 | } | ||
1285 | |||
1286 | if (new_obj) | ||
1287 | set->count_objs++; | ||
1288 | |||
1289 | return 0; | ||
1290 | } | ||
1291 | |||
1292 | void drmModePropertySetFree(drmModePropertySetPtr set) | ||
1293 | { | ||
1294 | drmModePropertySetItemPtr item; | ||
1295 | |||
1296 | if (!set) | ||
1297 | return; | ||
1298 | |||
1299 | item = set->list.next; | ||
1300 | |||
1301 | while (item) { | ||
1302 | drmModePropertySetItemPtr next = item->next; | ||
1303 | |||
1304 | drmFree(item); | ||
1305 | |||
1306 | item = next; | ||
1307 | } | ||
1308 | |||
1309 | drmFree(set); | ||
1310 | } | ||
1311 | |||
1312 | int drmModePropertySetCommit(int fd, uint32_t flags, void *user_data, | ||
1313 | drmModePropertySetPtr set) | ||
1314 | { | ||
1315 | drmModePropertySetItemPtr item; | ||
1316 | uint32_t *objs_ptr = NULL; | ||
1317 | uint32_t *count_props_ptr = NULL; | ||
1318 | uint32_t *props_ptr = NULL; | ||
1319 | uint64_t *prop_values_ptr = NULL; | ||
1320 | uint64_t *blob_values_ptr = NULL; | ||
1321 | struct drm_mode_atomic atomic = { 0 }; | ||
1322 | unsigned int obj_idx = 0; | ||
1323 | unsigned int prop_idx = 0; | ||
1324 | unsigned int blob_idx = 0; | ||
1325 | int ret = -1; | ||
1326 | |||
1327 | if (!set) | ||
1328 | return -1; | ||
1329 | |||
1330 | objs_ptr = drmMalloc(set->count_objs * sizeof objs_ptr[0]); | ||
1331 | if (!objs_ptr) { | ||
1332 | errno = ENOMEM; | ||
1333 | goto out; | ||
1334 | } | ||
1335 | |||
1336 | count_props_ptr = drmMalloc(set->count_objs * sizeof count_props_ptr[0]); | ||
1337 | if (!count_props_ptr) { | ||
1338 | errno = ENOMEM; | ||
1339 | goto out; | ||
1340 | } | ||
1341 | |||
1342 | props_ptr = drmMalloc(set->count_props * sizeof props_ptr[0]); | ||
1343 | if (!props_ptr) { | ||
1344 | errno = ENOMEM; | ||
1345 | goto out; | ||
1346 | } | ||
1347 | |||
1348 | prop_values_ptr = drmMalloc(set->count_props * sizeof prop_values_ptr[0]); | ||
1349 | if (!prop_values_ptr) { | ||
1350 | errno = ENOMEM; | ||
1351 | goto out; | ||
1352 | } | ||
1353 | |||
1354 | blob_values_ptr = drmMalloc(set->count_blobs * sizeof blob_values_ptr[0]); | ||
1355 | if (!blob_values_ptr) { | ||
1356 | errno = ENOMEM; | ||
1357 | goto out; | ||
1358 | } | ||
1359 | |||
1360 | item = set->list.next; | ||
1361 | |||
1362 | while (item) { | ||
1363 | int count_props = 0; | ||
1364 | drmModePropertySetItemPtr next = item; | ||
1365 | |||
1366 | objs_ptr[obj_idx] = item->object_id; | ||
1367 | |||
1368 | while (next && next->object_id == item->object_id) { | ||
1369 | props_ptr[prop_idx] = next->property_id; | ||
1370 | prop_values_ptr[prop_idx] = next->value; | ||
1371 | prop_idx++; | ||
1372 | |||
1373 | if (next->is_blob) | ||
1374 | blob_values_ptr[blob_idx++] = VOID2U64(next->blob); | ||
1375 | |||
1376 | count_props++; | ||
1377 | |||
1378 | next = next->next; | ||
1379 | } | ||
1380 | |||
1381 | count_props_ptr[obj_idx++] = count_props; | ||
1382 | |||
1383 | item = next; | ||
1384 | } | ||
1385 | |||
1386 | atomic.count_objs = set->count_objs; | ||
1387 | atomic.flags = flags; | ||
1388 | atomic.objs_ptr = VOID2U64(objs_ptr); | ||
1389 | atomic.count_props_ptr = VOID2U64(count_props_ptr); | ||
1390 | atomic.props_ptr = VOID2U64(props_ptr); | ||
1391 | atomic.prop_values_ptr = VOID2U64(prop_values_ptr); | ||
1392 | atomic.blob_values_ptr = VOID2U64(blob_values_ptr); | ||
1393 | atomic.user_data = VOID2U64(user_data); | ||
1394 | |||
1395 | ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic); | ||
1396 | |||
1397 | out: | ||
1398 | drmFree(objs_ptr); | ||
1399 | drmFree(count_props_ptr); | ||
1400 | drmFree(props_ptr); | ||
1401 | drmFree(prop_values_ptr); | ||
1402 | |||
1403 | return ret; | ||
1404 | } | ||
diff --git a/xf86drmMode.h b/xf86drmMode.h index 856a6bb0..02c94b30 100644 --- a/xf86drmMode.h +++ b/xf86drmMode.h | |||
@@ -471,6 +471,26 @@ extern int drmModeObjectSetProperty(int fd, uint32_t object_id, | |||
471 | uint32_t object_type, uint32_t property_id, | 471 | uint32_t object_type, uint32_t property_id, |
472 | uint64_t value); | 472 | uint64_t value); |
473 | 473 | ||
474 | |||
475 | typedef struct _drmModePropertySet drmModePropertySet, *drmModePropertySetPtr; | ||
476 | |||
477 | extern drmModePropertySetPtr drmModePropertySetAlloc(void); | ||
478 | |||
479 | extern int drmModePropertySetAdd(drmModePropertySetPtr set, | ||
480 | uint32_t object_id, | ||
481 | uint32_t property_id, | ||
482 | uint64_t value); | ||
483 | extern int drmModePropertySetAddBlob(drmModePropertySetPtr set, | ||
484 | uint32_t object_id, | ||
485 | uint32_t property_id, | ||
486 | uint64_t length, | ||
487 | void *blob); | ||
488 | |||
489 | extern int drmModePropertySetCommit(int fd, uint32_t flags, | ||
490 | void *user_data, drmModePropertySetPtr set); | ||
491 | |||
492 | extern void drmModePropertySetFree(drmModePropertySetPtr set); | ||
493 | |||
474 | #if defined(__cplusplus) || defined(c_plusplus) | 494 | #if defined(__cplusplus) || defined(c_plusplus) |
475 | } | 495 | } |
476 | #endif | 496 | #endif |