xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkisp_demo/demo/rkdrm_display.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL), available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 #include <libdrm/drm_mode.h>
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <stddef.h>
36 #include <xf86drmMode.h>
37 #include <sys/mman.h>
38 #include <unistd.h>
39 #include "rkdrm_display.h"
40 
41 #define IS_SUPPORT_WINID_PROPERTY 0
42 #define INT_MAX 0xff
43 #define COLOR_KEY 0xFFFFFFFF
44 
drm_plane_set_property(int fd,drmModePlane * plane,const char * prop_name,uint64_t prop_value)45 static bool drm_plane_set_property (int fd, drmModePlane * plane,
46         const char *prop_name, uint64_t prop_value)
47 {
48     drmModeObjectPropertiesPtr props;
49     drmModePropertyPtr prop;
50     int i, ret = -1;
51 
52     props = drmModeObjectGetProperties (fd, plane->plane_id,
53             DRM_MODE_OBJECT_PLANE);
54     if (!props)
55         return false;
56 
57     for (i = 0; i < props->count_props; i++) {
58         prop = drmModeGetProperty (fd, props->props[i]);
59         if (prop && !strcmp (prop->name, prop_name)) {
60             ret = drmModeObjectSetProperty (fd, plane->plane_id,
61                     DRM_MODE_OBJECT_PLANE, props->props[i], prop_value);
62         }
63         drmModeFreeProperty (prop);
64     }
65 
66     drmModeFreeObjectProperties (props);
67     return ret < 0 ? false : true;
68 }
69 
70 /**
71  * drm_fb_get_bpp_depth - get the bpp/depth values for format
72  * @format: pixel format (DRM_FORMAT_*)
73  * @depth: storage for the depth value
74  * @bpp: storage for the bpp value
75  *
76  * This only supports RGB formats here for compat with code that doesn't use
77  * pixel formats directly yet.
78  */
drm_fb_get_bpp_depth(uint32_t format,unsigned int * depth,int * bpp)79 void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp)
80 {
81     switch (format) {
82     case DRM_FORMAT_C8:
83     case DRM_FORMAT_RGB332:
84     case DRM_FORMAT_BGR233:
85         *depth = 8;
86         *bpp = 8;
87         break;
88     case DRM_FORMAT_XRGB1555:
89     case DRM_FORMAT_XBGR1555:
90     case DRM_FORMAT_RGBX5551:
91     case DRM_FORMAT_BGRX5551:
92     case DRM_FORMAT_ARGB1555:
93     case DRM_FORMAT_ABGR1555:
94     case DRM_FORMAT_RGBA5551:
95     case DRM_FORMAT_BGRA5551:
96         *depth = 15;
97         *bpp = 16;
98         break;
99     case DRM_FORMAT_RGB565:
100     case DRM_FORMAT_BGR565:
101         *depth = 16;
102         *bpp = 16;
103         break;
104     case DRM_FORMAT_RGB888:
105     case DRM_FORMAT_BGR888:
106         *depth = 24;
107         *bpp = 24;
108         break;
109     case DRM_FORMAT_XRGB8888:
110     case DRM_FORMAT_XBGR8888:
111     case DRM_FORMAT_RGBX8888:
112     case DRM_FORMAT_BGRX8888:
113         *depth = 24;
114         *bpp = 32;
115         break;
116     case DRM_FORMAT_XRGB2101010:
117     case DRM_FORMAT_XBGR2101010:
118     case DRM_FORMAT_RGBX1010102:
119     case DRM_FORMAT_BGRX1010102:
120     case DRM_FORMAT_ARGB2101010:
121     case DRM_FORMAT_ABGR2101010:
122     case DRM_FORMAT_RGBA1010102:
123     case DRM_FORMAT_BGRA1010102:
124         *depth = 30;
125         *bpp = 32;
126         break;
127     case DRM_FORMAT_ARGB8888:
128     case DRM_FORMAT_ABGR8888:
129     case DRM_FORMAT_RGBA8888:
130     case DRM_FORMAT_BGRA8888:
131         *depth = 32;
132         *bpp = 32;
133         break;
134     default:
135         printf("unsupported pixel format %d\n", format);
136         *depth = 0;
137         *bpp = 0;
138         break;
139     }
140 }
141 
drm_format_to_bpp(uint32_t format)142 int drm_format_to_bpp(uint32_t format)
143 {
144     unsigned int depth;
145     int bpp;
146 
147     switch(format) {
148     case DRM_FORMAT_NV12:
149     case DRM_FORMAT_NV21:
150     case DRM_FORMAT_YUV420:
151     case DRM_FORMAT_YUV422:
152     case DRM_FORMAT_YUV444:
153         return 8;
154     default:
155         drm_fb_get_bpp_depth(format, &depth, &bpp);
156         return bpp;
157     }
158 }
159 
drmGetBuffer(int fd,int width,int height,int format,struct drm_buf * buffer)160 int drmGetBuffer(int fd, int width, int height, int format,
161                  struct drm_buf *buffer)
162 {
163     struct drm_mode_create_dumb alloc_arg;
164     struct drm_mode_map_dumb mmap_arg;
165     struct drm_mode_destroy_dumb destory_arg;
166     uint32_t handles[4], pitches[4], offsets[4];
167     int bpp, ret;
168     void *map;
169 
170     if (fd < 0 || !width || !height) {
171         printf("%s: invalid parameters\n", __func__);
172         return -EINVAL;
173     }
174 
175     bpp = drm_format_to_bpp(format);
176 
177     memset(&alloc_arg, 0, sizeof(alloc_arg));
178     alloc_arg.bpp = bpp;
179     alloc_arg.width = width;
180     if (format == DRM_FORMAT_NV12)
181         alloc_arg.height = height * 3 / 2;
182     else
183         alloc_arg.height = height;
184 
185     ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &alloc_arg);
186     if (ret) {
187         printf("failed to create dumb buffer: %s\n", strerror(errno));
188         return ret;
189     }
190     //HACK of gpu 64 bytes align?
191     if (format == DRM_FORMAT_NV12)
192         alloc_arg.pitch = width;
193 
194     memset(&mmap_arg, 0, sizeof(mmap_arg));
195     mmap_arg.handle = alloc_arg.handle;
196 
197     ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mmap_arg);
198     if (ret) {
199         printf("failed to create map dumb: %s\n", strerror(errno));
200         ret = -EINVAL;
201         goto destory_dumb;
202     }
203 
204     map = mmap(0, alloc_arg.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_arg.offset);
205     if (map == MAP_FAILED) {
206         printf("failed to mmap buffer: %s\n", strerror(errno));
207         ret = -EINVAL;
208         goto destory_dumb;
209     }
210 
211     ret = drmPrimeHandleToFD(fd, alloc_arg.handle, 0, &buffer->dmabuf_fd);
212     if (ret) {
213         printf("failed to get dmabuf fd: %s\n", strerror(errno));
214         munmap(map, alloc_arg.size);
215         ret = -EINVAL;
216         goto destory_dumb;
217     }
218 
219     handles[0] = alloc_arg.handle;
220     pitches[0] = alloc_arg.pitch;
221     offsets[0] = 0;
222 
223     if (format == DRM_FORMAT_NV12) {
224         handles[1] = alloc_arg.handle;
225         pitches[1] = pitches[0];
226         offsets[1] = pitches[0] * height;
227     }
228 
229     ret = drmModeAddFB2(fd, width, height, format, handles,
230                 pitches, offsets, (uint32_t*) &buffer->fb_id, 0);
231     if (ret)
232         printf("failed to create fb_id %d\n", ret);
233 
234     buffer->handle = alloc_arg.handle;
235     buffer->pitch = alloc_arg.pitch;
236     buffer->size = alloc_arg.size;
237     buffer->map = map;
238 
239 destory_dumb:
240     memset(&destory_arg, 0, sizeof(destory_arg));
241     destory_arg.handle = alloc_arg.handle;
242     drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destory_arg);
243 
244     return ret;
245 }
246 
drmPutBuffer(int fd,struct drm_buf * buffer)247 int drmPutBuffer(int fd, struct drm_buf *buffer)
248 {
249     if (buffer) {
250         drmModeRmFB(fd, buffer->fb_id);
251         close(buffer->dmabuf_fd);
252         return munmap(buffer->map, buffer->size);
253     }
254 
255     return -EINVAL;
256 }
257 
drmSetDpmsMode(uint32_t dpms_mode,struct drm_dev * dev)258 int drmSetDpmsMode(uint32_t dpms_mode, struct drm_dev *dev)
259 {
260     uint32_t connector_id;
261     uint32_t dpms_prop_id;
262     int ret = 0;
263 
264     if (dev->drm_fd < 0 || !dev->dpms_prop)
265         return -ENODEV;
266 
267     connector_id = dev->connector->connector_id;
268     dpms_prop_id = dev->dpms_prop->prop_id;
269 
270     ret = drmModeConnectorSetProperty(dev->drm_fd, connector_id, dpms_prop_id, dpms_mode);
271     if (ret) {
272         printf("Failed to set dpms mode %d ret=%d\n", dpms_mode, ret);
273         return ret;
274     }
275 
276     return 0;
277 }
278 
drmGetPlaneType(int fd,drmModePlanePtr p)279 static int drmGetPlaneType(int fd, drmModePlanePtr p)
280 {
281     drmModeObjectPropertiesPtr props;
282     drmModePropertyPtr prop;
283     int i, type = -1;
284 
285     props = drmModeObjectGetProperties(fd, p->plane_id,
286                     DRM_MODE_OBJECT_PLANE);
287     if (!props) {
288         printf("failed to found props plane[%d] %s\n",
289                p->plane_id, strerror(errno));
290         return -errno;
291     }
292 
293     for (i = 0; i < props->count_props; i++) {
294         prop = drmModeGetProperty(fd, props->props[i]);
295         if (!strcmp(prop->name, "type")) {
296             type = props->prop_values[i];
297             drmModeFreeProperty(prop);
298             break;
299         }
300         drmModeFreeProperty(prop);
301     }
302 
303     drmModeFreeObjectProperties(props);
304     return type;
305 }
306 
drmFillPlaneProp(int fd,struct drm_dev_plane * pp)307 static int drmFillPlaneProp(int fd, struct drm_dev_plane *pp)
308 {
309     drmModeObjectPropertiesPtr props;
310     drmModePropertyPtr prop;
311     struct plane_prop *plane_prop = &pp->plane_prop;
312     drmModePlanePtr p = pp->p;
313     int i;
314 
315     props = drmModeObjectGetProperties(fd, p->plane_id,
316                     DRM_MODE_OBJECT_PLANE);
317     if (!props) {
318         printf("failed to found props plane[%d] %s\n",
319                p->plane_id, strerror(errno));
320         return -errno;
321     }
322 
323     pp->zpos_max = INT_MAX;
324     for (i = 0; i < props->count_props; i++) {
325         prop = drmModeGetProperty(fd, props->props[i]);
326         if (!strcmp(prop->name, "CRTC_ID"))
327             plane_prop->crtc_id = prop->prop_id;
328         else if (!strcmp(prop->name, "FB_ID"))
329             plane_prop->fb_id = prop->prop_id;
330         else if (!strcmp(prop->name, "SRC_X"))
331             plane_prop->src_x = prop->prop_id;
332         else if (!strcmp(prop->name, "SRC_Y"))
333             plane_prop->src_y = prop->prop_id;
334         else if (!strcmp(prop->name, "SRC_W"))
335             plane_prop->src_w = prop->prop_id;
336         else if (!strcmp(prop->name, "SRC_H"))
337             plane_prop->src_h = prop->prop_id;
338         else if (!strcmp(prop->name, "CRTC_X"))
339             plane_prop->crtc_x = prop->prop_id;
340         else if (!strcmp(prop->name, "CRTC_Y"))
341             plane_prop->crtc_y = prop->prop_id;
342         else if (!strcmp(prop->name, "CRTC_W"))
343             plane_prop->crtc_w = prop->prop_id;
344         else if (!strcmp(prop->name, "CRTC_H"))
345             plane_prop->crtc_h = prop->prop_id;
346         else if (!strcmp(prop->name, "ZPOS")) {
347             plane_prop->zpos = prop->prop_id;
348             pp->zpos_max = prop->values[1];
349         }
350 
351         drmModeFreeProperty(prop);
352     }
353     drmModeFreeObjectProperties(props);
354 
355     return 0;
356 }
357 
drmGetPlaneByType(int fd,int crtc_index,int type)358 static drmModePlanePtr drmGetPlaneByType(int fd, int crtc_index, int type)
359 {
360     drmModePlanePtr plane = NULL;
361     drmModePlaneResPtr plane_res;
362     int i;
363 
364     plane_res = drmModeGetPlaneResources(fd);
365     for (i = 0; i < plane_res->count_planes; i++) {
366         drmModePlanePtr p = drmModeGetPlane(fd, plane_res->planes[i]);
367 
368         if (!(p->possible_crtcs & (1 << crtc_index))) {
369             drmModeFreePlane(p);
370             continue;
371         }
372         if (drmGetPlaneType(fd, p) == type) {
373             plane = p;
374             break;
375         }
376         drmModeFreePlane(p);
377     }
378 
379     drmModeFreePlaneResources(plane_res);
380 
381     return plane;
382 }
383 
drmFoundConn(int fd,drmModeResPtr res)384 drmModeConnectorPtr drmFoundConn(int fd, drmModeResPtr res)
385 {
386     drmModeConnectorPtr connector = NULL;
387     int i;
388 
389     for (i = 0; i < res->count_connectors; ++i) {
390         drmModeConnectorPtr c;
391         c = drmModeGetConnector(fd, res->connectors[i]);
392         if (!c)
393             continue;
394         if (c->connector_type == DRM_MODE_CONNECTOR_DSI ||
395             c->connector_type == DRM_MODE_CONNECTOR_eDP ||
396             c->connector_type == DRM_MODE_CONNECTOR_LVDS) {
397             connector = c;
398             break;
399         }
400         drmModeFreeConnector(c);
401     }
402 
403     return connector;
404 }
405 
drmFoundDPMS(int fd,drmModeConnectorPtr connector)406 static drmModePropertyPtr drmFoundDPMS(int fd, drmModeConnectorPtr connector)
407 {
408     drmModePropertyPtr dpms_prop = NULL;
409     drmModeObjectPropertiesPtr props;
410     int i;
411 
412     props = drmModeObjectGetProperties(fd, connector->connector_id,
413                        DRM_MODE_OBJECT_CONNECTOR);
414     if (!props) {
415         printf("failed to found props connector[%d] %s\n",
416             connector->connector_id, strerror(errno));
417         goto out;
418     }
419     for (i = 0; i < props->count_props; i++) {
420         drmModePropertyPtr prop;
421         prop = drmModeGetProperty(fd, props->props[i]);
422         if (!strcmp(prop->name, "DPMS")) {
423             dpms_prop = prop;
424             goto out;
425         }
426         drmModeFreeProperty(prop);
427     }
428 
429 out:
430     drmModeFreeObjectProperties(props);
431     return dpms_prop;
432 }
433 
drmFoundCrtc(int fd,drmModeResPtr res,drmModeConnector * conn,int * crtc_index)434 static drmModeCrtcPtr drmFoundCrtc(int fd, drmModeResPtr res,
435             drmModeConnector * conn, int *crtc_index)
436 {
437   int i;
438   int crtc_id;
439   drmModeEncoder *enc;
440   drmModeCrtc *crtc;
441   uint32_t crtcs_for_connector = 0;
442 
443   crtc_id = -1;
444   for (i = 0; i < res->count_encoders; i++) {
445     enc = drmModeGetEncoder (fd, res->encoders[i]);
446     if (enc) {
447       if (enc->encoder_id == conn->encoder_id) {
448         crtc_id = enc->crtc_id;
449         drmModeFreeEncoder (enc);
450         break;
451       }
452       drmModeFreeEncoder (enc);
453     }
454   }
455 
456   /* If no active crtc was found, pick the first possible crtc */
457   if (crtc_id == -1) {
458     for (i = 0; i < conn->count_encoders; i++) {
459       enc = drmModeGetEncoder (fd, conn->encoders[i]);
460       crtcs_for_connector |= enc->possible_crtcs;
461       drmModeFreeEncoder (enc);
462     }
463 
464     if (crtcs_for_connector != 0)
465       crtc_id = res->crtcs[ffs (crtcs_for_connector) - 1];
466   }
467 
468   if (crtc_id == -1)
469     return NULL;
470 
471   for (i = 0; i < res->count_crtcs; i++) {
472     crtc = drmModeGetCrtc (fd, res->crtcs[i]);
473     if (crtc) {
474       if (crtc_id == crtc->crtc_id) {
475         if (crtc_index)
476           *crtc_index= i;
477         return crtc;
478       }
479       drmModeFreeCrtc (crtc);
480     }
481   }
482 
483   return NULL;
484 }
485 
drmInit(struct drm_dev * dev)486 int drmInit(struct drm_dev *dev)
487 {
488     drmModeResPtr res;
489     drmModeCrtcPtr crtc = NULL;
490     drmModeConnectorPtr connector = NULL;
491     drmModePlanePtr plane = NULL;
492     int fd, ret;
493     int crtc_index;
494 
495     fd = drmOpen("rockchip", NULL);
496     if (fd < 0) {
497         printf("failed to open rockchip drm: %s\n",
498             strerror(errno));
499         return fd;
500     }
501     dev->drm_fd = fd;
502 
503     ret = drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
504     if (ret) {
505         printf("Failed to set atomic cap %s", strerror(errno));
506         return ret;
507     }
508 
509     ret = drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1);
510     if (ret) {
511         printf("Failed to set atomic cap %s", strerror(errno));
512         return ret;
513     }
514 
515     res = drmModeGetResources(fd);
516     if (!res) {
517         printf("Failed to get resources: %s\n",
518             strerror(errno));
519         return -ENODEV;
520     }
521 
522     /* found connector */
523     connector = drmFoundConn(fd, res);
524     if (!connector) {
525         printf("failed to find connector\n");
526         ret = -ENODEV;
527         goto err_conn;
528     }
529     /* found connector dpms prop */
530     dev->dpms_prop = drmFoundDPMS(fd, connector);
531     if (!dev->dpms_prop) {
532         ret = -ENODEV;
533         goto err_dpms;
534     }
535 
536     /* found crtc that connect to connector */
537     crtc = drmFoundCrtc(fd, res, connector, &crtc_index);
538     if (!crtc) {
539         printf("failed to find crtc connect to connector \n");
540         ret = -ENODEV;
541         goto err_crtc;
542     }
543 
544     plane = drmGetPlaneByType(fd, crtc_index, DRM_PLANE_TYPE_PRIMARY);
545     if (!plane) {
546         printf("failed to found expected plane\n");
547         ret = -ENODEV;
548         goto err_plane_primary;
549     }
550     dev->plane_primary.p = plane;
551 
552     plane = drmGetPlaneByType(fd, crtc_index, DRM_PLANE_TYPE_OVERLAY);
553     if (!plane) {
554         printf("failed to found expected plane\n");
555         ret = -ENODEV;
556         goto err_plane_overlay;
557     }
558     dev->plane_overlay.p = plane;
559 
560     drmModeFreeResources(res);
561 
562     drmFillPlaneProp(fd, &dev->plane_primary);
563     drmFillPlaneProp(fd, &dev->plane_overlay);
564     dev->crtc_index = crtc_index;
565     dev->crtc = crtc;
566     dev->connector = connector;
567 
568     if (!drm_plane_set_property(fd, dev->plane_primary.p, "ZPOS", 0)) {
569         printf("%s: set ZPOS property failed!\n", __func__);
570         goto err_plane_overlay;
571     }
572     if (!drm_plane_set_property(fd, dev->plane_overlay.p, "ZPOS", 1)) {
573         printf("%s: set ZPOS property failed!\n", __func__);
574         goto err_plane_overlay;
575     }
576 
577     return 0;
578 
579 err_plane_overlay:
580     drmModeFreePlane(dev->plane_primary.p);
581 err_plane_primary:
582     drmModeFreeCrtc(crtc);
583 err_crtc:
584     drmModeFreeProperty(dev->dpms_prop);
585 err_dpms:
586     drmModeFreeConnector(connector);
587 err_conn:
588     drmModeFreeResources(res);
589 
590     return ret;
591 }
592 
drmDeinit(struct drm_dev * dev)593 int drmDeinit(struct drm_dev *dev)
594 {
595     if (dev->plane_primary.p)
596         drmModeFreePlane(dev->plane_primary.p);
597     if (dev->plane_overlay.p)
598         drmModeFreePlane(dev->plane_overlay.p);
599     if (dev->dpms_prop)
600         drmModeFreeProperty(dev->dpms_prop);
601     if (dev->crtc)
602         drmModeFreeCrtc(dev->crtc);
603     if (dev->connector)
604         drmModeFreeConnector(dev->connector);
605     if (dev->drm_fd > 0)
606         drmClose(dev->drm_fd);
607 
608     return 0;
609 }
610 
drmCommit(struct drm_buf * buffer,int width,int height,int x_off,int y_off,struct drm_dev * dev,int plane_type)611 int drmCommit(struct drm_buf *buffer, int width, int height,
612               int x_off, int y_off, struct drm_dev *dev, int plane_type)
613 {
614     drmModeAtomicReq *req;
615     drmModeCrtcPtr crtc = dev->crtc;
616     drmModePlanePtr plane;
617     struct plane_prop *plane_prop;
618     int plane_zpos;
619     uint32_t flags = 0;
620     int ret;
621 
622     if (dev->drm_fd < 0 || !buffer) {
623         printf("%s: invalid parameters\n", __func__);
624         return -EINVAL;
625     }
626 
627     if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
628         plane = dev->plane_primary.p;
629         plane_zpos = dev->plane_primary.zpos_max;
630         plane_prop = &dev->plane_primary.plane_prop;
631     } else {
632         plane = dev->plane_overlay.p;
633         plane_zpos = dev->plane_overlay.zpos_max;
634         plane_prop = &dev->plane_overlay.plane_prop;
635     }
636 
637     width = width == 0 ? crtc->mode.hdisplay : width;
638     height = height == 0? crtc->mode.vdisplay : height;
639 
640     req = drmModeAtomicAlloc();
641 
642 #define DRM_ATOMIC_ADD_PROP(object_id, value) \
643     ret = drmModeAtomicAddProperty(req, plane->plane_id, object_id, value); \
644     if (ret < 0) \
645         printf("Failed to add prop[%d] to [%d]", value, object_id);
646     DRM_ATOMIC_ADD_PROP(plane_prop->crtc_id, crtc->crtc_id);
647     DRM_ATOMIC_ADD_PROP(plane_prop->fb_id, buffer->fb_id);
648     DRM_ATOMIC_ADD_PROP(plane_prop->src_x, 0);
649     DRM_ATOMIC_ADD_PROP(plane_prop->src_y, 0);
650     DRM_ATOMIC_ADD_PROP(plane_prop->src_w, width << 16);
651     DRM_ATOMIC_ADD_PROP(plane_prop->src_h, height << 16);
652     DRM_ATOMIC_ADD_PROP(plane_prop->crtc_x, x_off);
653     DRM_ATOMIC_ADD_PROP(plane_prop->crtc_y, y_off);
654     DRM_ATOMIC_ADD_PROP(plane_prop->crtc_w, width);
655     DRM_ATOMIC_ADD_PROP(plane_prop->crtc_h, height);
656     //DRM_ATOMIC_ADD_PROP(plane_prop->zpos, plane_zpos);
657 
658 //    flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
659     ret = drmModeAtomicCommit(dev->drm_fd, req, flags, NULL);
660     if (ret)
661         printf("atomic: couldn't commit new state: %s\n", strerror(errno));
662 
663     drmModeAtomicFree(req);
664 
665     return ret;
666 }
667