aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä2012-05-18 07:52:09 -0500
committerSean Paul2015-04-17 15:16:05 -0500
commitba5b0e9d9a3c894673b68b14cc82f53df32bbce8 (patch)
treebad6288a951187c89e1ac495b61d71af8e64f59f
parentc12a1a7cc6fef927b9d3dc92c1a6a5eb30ee04a1 (diff)
downloadexternal-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.h1
-rw-r--r--include/drm/drm_mode.h22
-rw-r--r--xf86drmMode.c273
-rw-r--r--xf86drmMode.h20
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? */
521struct 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
1134typedef struct _drmModePropertySetItem drmModePropertySetItem, *drmModePropertySetItemPtr;
1135
1136struct _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
1145struct _drmModePropertySet {
1146 unsigned int count_objs;
1147 unsigned int count_props;
1148 unsigned int count_blobs;
1149 drmModePropertySetItem list;
1150};
1151
1152drmModePropertySetPtr 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
1167int 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
1228int 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
1292void 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
1312int 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
1397out:
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
475typedef struct _drmModePropertySet drmModePropertySet, *drmModePropertySetPtr;
476
477extern drmModePropertySetPtr drmModePropertySetAlloc(void);
478
479extern int drmModePropertySetAdd(drmModePropertySetPtr set,
480 uint32_t object_id,
481 uint32_t property_id,
482 uint64_t value);
483extern int drmModePropertySetAddBlob(drmModePropertySetPtr set,
484 uint32_t object_id,
485 uint32_t property_id,
486 uint64_t length,
487 void *blob);
488
489extern int drmModePropertySetCommit(int fd, uint32_t flags,
490 void *user_data, drmModePropertySetPtr set);
491
492extern 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