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 /xf86drmMode.c
parentc12a1a7cc6fef927b9d3dc92c1a6a5eb30ee04a1 (diff)
downloadexternal-libgbm-ba5b0e9d9a3c894673b68b14cc82f53df32bbce8.tar.gz
external-libgbm-ba5b0e9d9a3c894673b68b14cc82f53df32bbce8.tar.xz
external-libgbm-ba5b0e9d9a3c894673b68b14cc82f53df32bbce8.zip
BACKPORT: libdrm: atomic mode set
(cherry picked from commit fb8403c23edb3e06c979115b7b0cce2ba5099aa2) Signed-off-by: Sean Paul <seanpaul@chromium.org>
Diffstat (limited to 'xf86drmMode.c')
-rw-r--r--xf86drmMode.c273
1 files changed, 273 insertions, 0 deletions
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}