DRM應用程式高階 (atomic crtc)

2021-09-10 23:51:20 字數 4077 閱讀 8128

為什麼叫「atomic commit」?

初學者第一次接觸到drm時,總會好奇當初開發者為什麼要起 atomic 這個名字。wiki上關於該名詞有較詳細的解釋,如果大家感興趣可以通過本篇結尾的參考資料獲取鏈結檢視。我這裡用白話簡單概括就是:本次commit操作,要麼成功,要麼保持原來的狀態不變。即如果中途操作失敗了,那些已經生效的配置需要恢復成之前的狀態,就像沒發生過commit操作似的,這就是atomic的含義。

而用commit 一詞,是因為本次操作可能會修改到多個引數,等修改好這些引數後,再一次性發起操作請求,有點類似與填表後「提交」材料的意思。

如何操作property?

需要記住一點,在libdrm中,所有的操作都是以object id來進行訪問的,因此要操作property,首先需要獲取該property的object id。

偽**:

int

main

(void

)

首先通過drmmodegetproperty()來獲取property的相關資訊,然後通過drmmodeatomicaddproperty()來修改property的值,最後通過drmmodeatomiccommit()來發起真正的修改請求。

為什麼要設定 drm_client_cap_atomic ?基於之前的《最簡單的drm應用程式(plane-test)》的參考**,我們使用atomic介面來替代原來的drmmodesetcrtc()介面,從而通過差異對比來學些atomic介面的操作。

modeset-atomic-crtc.c

#define _gnu_source

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

struct buffer_object

;struct buffer_object buf;

static

intmodeset_create_fb

(int fd,

struct buffer_object *bo)

;struct drm_mode_map_dumb map =

; create.width = bo->width;

create.height = bo->height;

create.bpp =32;

drmioctl

(fd, drm_ioctl_mode_create_dumb,

&create)

; bo->pitch = create.pitch;

bo->size = create.size;

bo->handle = create.handle;

drmmodeaddfb

(fd, bo->width, bo->height,24,

32, bo->pitch,

bo->handle,

&bo->fb_id)

; map.handle = create.handle;

drmioctl

(fd, drm_ioctl_mode_map_dumb,

&map)

; bo->vaddr =

mmap(0

, create.size, prot_read | prot_write,

map_shared, fd, map.offset)

;memset

(bo->vaddr,

0xff

, bo->size)

;return0;

}static

void

modeset_destroy_fb

(int fd,

struct buffer_object *bo)

;drmmodermfb

(fd, bo->fb_id)

;munmap

(bo->vaddr, bo->size)

; destroy.handle = bo->handle;

drmioctl

(fd, drm_ioctl_mode_destroy_dumb,

&destroy);}

static uint32_t get_property_id

(int fd, drmmodeobjectproperties *props,

const

char

*name)

return id;

}int

main

(int argc,

char

**ar**)

通過上面的**我們可以看出,原來的drmmodesetcrtc(crtc_id, fb_id, conn_id, &mode)被下面這部分**取代了:

req =

drmmodeatomicalloc()

;drmmodeatomicaddproperty

(req, crtc_id, property_active,1)

;drmmodeatomicaddproperty

(req, crtc_id, property_mode_id, blob_id)

;drmmodeatomicaddproperty

(req, conn_id, property_crtc_id, crtc_id)

;drmmodeatomiccommit

(fd, req, drm_mode_atomic_allow_modeset,

null);

drmmodeatomicfree

(req)

;

雖然**量增加了,但是應用程式的靈活性和可擴充套件性也增強了。

由於以上**沒有新增對 fb_id 的操作,因此它的作用只是初始化crtc/encoder/connector硬體,以及建立硬體鏈路的連線關係,並不會顯示framebuffer的內容,即保持黑屏狀態。framebuffer的顯示將由後面的 drmmodesetplane() 操作來完成。

以上**執行的效果如下(模擬效果):

注意:程式執行之前,請確保沒有其它應用或服務占用/dev/dri/card0節點,否則將出現permission denied錯誤。

描述:

程式執行後,螢幕顯示黑色,終端列印「drmmodeatomiccommit」資訊,表明當前已經初始化好crtc/encoder/connector硬體;

輸入回車後,螢幕顯示framebuffer的crop區域,同時終端列印「drmmodesetplane」資訊;

再次輸入回車,顯示黑屏,程式退出。

在《最簡單的drm應用程式(plane-test)》文章中曾強調過,drmmodesetplane() 呼叫之前,必須先呼叫drmmodesetcrtc() 初始化底層硬體,否則plane設定將無效。而通過上面的程式執行結果可以證明,drmmodeatomiccommit() 操作同樣可以初始化底層硬體。

wiki: atomic commit

lwn: atomic mode setting design overview, part 1, part2

android libdrm: modeset.c

drm (direct rendering manager) 學習簡介

DRM應用程式高階 (atomic plane)

plane update的atomic操作如下 drmmodeatomicaddproperty req,plane id,property crtc id,crtc id drmmodeatomicaddproperty req,plane id,property fb id,fb id drmm...

DRM應用程式高階 (atomic crtc)

為什麼叫 atomic commit 初學者第一次接觸到drm時,總會好奇當初開發者為什麼要起 atomic 這個名字。wiki上關於該名詞有較詳細的解釋,如果大家感興趣可以通過本篇結尾的參考資料獲取鏈結檢視。我這裡用白話簡單概括就是 本次commit操作,要麼成功,要麼保持原來的狀態不變。即如果中...

ios應用程式和應用程式委託

其實說白了,就是乙個類將自己不願意實現的方法以協議的方式定義,同時在這個類中包含有乙個型別為id 泛型類 的例項變數,如果另乙個類實現了這個協議,那麼另外的這個類就可以作為第乙個類的委託物件,前乙個類將自己不願意實現的類委託給後乙個類。因為第乙個類擁有第二個類的引用,所有第乙個類的例項可以直接呼叫第...