@@ -247,17 +247,105 @@ static void update_framebuffer_from_bo(struct ra_ctx *ctx, struct gbm_bo *bo)
247247 p -> fb = fb ;
248248}
249249
250+ static bool crtc_setup_atomic (struct ra_ctx * ctx , drmModeModeInfo mode )
251+ {
252+ struct priv * p = ctx -> priv ;
253+
254+ struct drm_atomic_context * atomic_ctx = p -> kms -> atomic_context ;
255+ drmModeAtomicReqPtr request = drmModeAtomicAlloc ();
256+ if (request ) {
257+ drm_object_set_property (request , atomic_ctx -> connector , "CRTC_ID" , p -> kms -> crtc_id );
258+
259+ uint32_t blob_id ;
260+ if (drmModeCreatePropertyBlob (p -> kms -> fd , & mode , sizeof (drmModeModeInfo ),
261+ & blob_id ) != 0 ) {
262+ MP_ERR (ctx -> vo , "Failed to DRM mode blob\n" );
263+ return 0 ;
264+ }
265+ drm_object_set_property (request , atomic_ctx -> crtc , "MODE_ID" , blob_id );
266+ drm_object_set_property (request , atomic_ctx -> crtc , "ACTIVE" , 1 );
267+
268+ drm_object_set_property (request , atomic_ctx -> osd_plane , "SRC_X" , 0 );
269+ drm_object_set_property (request , atomic_ctx -> osd_plane , "SRC_Y" , 0 );
270+ drm_object_set_property (request , atomic_ctx -> osd_plane , "SRC_W" , p -> osd_size .width << 16 );
271+ drm_object_set_property (request , atomic_ctx -> osd_plane , "SRC_H" , p -> osd_size .height << 16 );
272+ drm_object_set_property (request , atomic_ctx -> osd_plane , "CRTC_X" , 0 );
273+ drm_object_set_property (request , atomic_ctx -> osd_plane , "CRTC_Y" , 0 );
274+ drm_object_set_property (request , atomic_ctx -> osd_plane , "CRTC_W" , mode .hdisplay );
275+ drm_object_set_property (request , atomic_ctx -> osd_plane , "CRTC_H" , mode .vdisplay );
276+
277+ int ret = drmModeAtomicCommit (p -> kms -> fd , request ,
278+ DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT
279+ | DRM_MODE_ATOMIC_ALLOW_MODESET , NULL );
280+
281+ if (ret )
282+ MP_WARN (ctx -> vo , "Failed to commit ModeSetting atomic request (%d)\n" , ret );
283+
284+ drmModeAtomicFree (request );
285+
286+ return ret == 0 ;
287+ } else {
288+ MP_ERR (ctx -> vo , "Failed to allocate drm atomic request\n" );
289+ }
290+
291+ return false;
292+ }
293+
294+ static bool crtc_release_atomic (struct ra_ctx * ctx )
295+ {
296+ struct priv * p = ctx -> priv ;
297+
298+ struct drm_atomic_context * atomic_ctx = p -> kms -> atomic_context ;
299+ drmModeAtomicReqPtr request = drmModeAtomicAlloc ();
300+ if (request ) {
301+ drm_object_set_property (request , atomic_ctx -> connector , "CRTC_ID" , p -> old_crtc -> crtc_id );
302+
303+ uint32_t blob_id ;
304+ if (drmModeCreatePropertyBlob (p -> kms -> fd , & p -> old_crtc -> mode , sizeof (drmModeModeInfo ),
305+ & blob_id ) != 0 ) {
306+ MP_ERR (ctx -> vo , "Failed to DRM mode blob\n" );
307+ return 0 ;
308+ }
309+ drm_object_set_property (request , atomic_ctx -> crtc , "MODE_ID" , blob_id );
310+ drm_object_set_property (request , atomic_ctx -> crtc , "ACTIVE" , 1 );
311+ drm_object_set_property (request , atomic_ctx -> osd_plane , "FB_ID" , p -> old_crtc -> buffer_id );
312+
313+ int ret = drmModeAtomicCommit (p -> kms -> fd , request ,
314+ DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT
315+ | DRM_MODE_ATOMIC_ALLOW_MODESET , NULL );
316+
317+ if (ret )
318+ MP_WARN (ctx -> vo , "Failed to commit ModeSetting atomic request (%d)\n" , ret );
319+
320+ drmModeAtomicFree (request );
321+
322+ return ret == 0 ;
323+ } else {
324+ MP_ERR (ctx -> vo , "Failed to allocate drm atomic request\n" );
325+ }
326+
327+ return false;
328+ }
329+
250330static bool crtc_setup (struct ra_ctx * ctx )
251331{
252332 struct priv * p = ctx -> priv ;
253333 if (p -> active )
254334 return true;
255335 p -> old_crtc = drmModeGetCrtc (p -> kms -> fd , p -> kms -> crtc_id );
256- int ret = drmModeSetCrtc (p -> kms -> fd , p -> kms -> crtc_id , p -> fb -> id ,
257- 0 , 0 , & p -> kms -> connector -> connector_id , 1 ,
258- & p -> kms -> mode );
259- p -> active = true;
260- return ret == 0 ;
336+
337+ if (p -> kms -> atomic_context ) {
338+ int ret = crtc_setup_atomic (ctx , p -> kms -> mode );
339+ p -> active = true;
340+ return ret ;
341+
342+ } else {
343+ int ret = drmModeSetCrtc (p -> kms -> fd , p -> kms -> crtc_id , p -> fb -> id ,
344+ 0 , 0 , & p -> kms -> connector -> connector_id , 1 ,
345+ & p -> kms -> mode );
346+ p -> active = true;
347+ return ret == 0 ;
348+ }
261349}
262350
263351static void crtc_release (struct ra_ctx * ctx )
@@ -278,12 +366,17 @@ static void crtc_release(struct ra_ctx *ctx)
278366 }
279367
280368 if (p -> old_crtc ) {
281- drmModeSetCrtc (p -> kms -> fd ,
282- p -> old_crtc -> crtc_id , p -> old_crtc -> buffer_id ,
283- p -> old_crtc -> x , p -> old_crtc -> y ,
284- & p -> kms -> connector -> connector_id , 1 ,
285- & p -> old_crtc -> mode );
286- drmModeFreeCrtc (p -> old_crtc );
369+ if (p -> kms -> atomic_context ) {
370+ if (!crtc_release_atomic (ctx ))
371+ MP_ERR (ctx -> vo , "Failed to restore previous mode\n" );
372+ } else {
373+ drmModeSetCrtc (p -> kms -> fd ,
374+ p -> old_crtc -> crtc_id , p -> old_crtc -> buffer_id ,
375+ p -> old_crtc -> x , p -> old_crtc -> y ,
376+ & p -> kms -> connector -> connector_id , 1 ,
377+ & p -> old_crtc -> mode );
378+ }
379+ drmModeFreeCrtc (p -> old_crtc );
287380 p -> old_crtc = NULL ;
288381 }
289382}
0 commit comments