plane update的atomic操作如下:
drmmodeatomicaddproperty
(req, plane_id, property_crtc_id, crtc_id)
;drmmodeatomicaddproperty
(req, plane_id, property_fb_id, fb_id)
;drmmodeatomicaddproperty
(req, plane_id, property_crtc_x, crtc_x)
;drmmodeatomicaddproperty
(req, plane_id, property_crtc_y, crtc_y)
;drmmodeatomicaddproperty
(req, plane_id, property_crtc_w, crtc_w)
;drmmodeatomicaddproperty
(req, plane_id, property_crtc_h, crtc_h)
;drmmodeatomicaddproperty
(req, plane_id, property_src_x, src_x)
;drmmodeatomicaddproperty
(req, plane_id, property_src_y, src_y)
;drmmodeatomicaddproperty
(req, plane_id, property_src_w, src_w <<16)
;drmmodeatomicaddproperty
(req, plane_id, property_src_h, src_h <<16)
;drmmodeatomiccommit
(fd, req, flags,
null
);
以上各項引數與drmmodesetplane() 的引數一一對應:
drmmodesetplane
(fd, plane_id, crtc_id, fb_id, flags,
crtc_x, crtc_y, crtc_w, crtc_h,
src_x <<
16, src_y <<
16, src_w <<
16, src_h <<
16)
其中,引數 flags 可以是如下值的組合:
當然,flags 引數為0也是可以的。
drmmodeatomiccommit() 與 drmmodesetplane() 對比,具有如下優勢:
drmmodeatomiccommit
drmmodesetplane
支援非同步呼叫
只能同步呼叫
一次呼叫可以更新多個plane
每次呼叫只能更新1個plane
支援test功能,提前預知呼叫結果
不支援如果你從事過android底層開發,你會發現在android external/libdrm 的某些release分支上,會多出drmmodepropertysetadd()
、drmmodepropertysetcommit()
等這類函式介面,而在libdrm的社群主線倉庫mesa/drm中,其實是找不到這樣的介面的。該介面最初由ville syrjälä 和 sean paul於2023年提交到libdrm的乙個臨時分支上,後來又被cherry-pick到android的libdrm倉庫中,點此鏈結檢視提交記錄。
偽**
pset =
drmmodepropertysetalloc()
;drmmodepropertysetadd
(pset, object_id, property_id, property_value)
;drmmodepropertysetcommit
(fd, flags, data, pset)
;drmmodepropertysetfree
(pset)
;
由於這些介面的用法同主線中的atomic介面大同小異,因此不做詳細描述。
modeset-atomic-plane.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**)
上面的兩次 drmmodeatomiccommit() 操作可以合併成一次;以上**執行的效果如下(模擬效果):無需頻繁呼叫 drmmodeatomicalloc() 、drmmodeatomicfree() ,可以在第一次commit之前alloc,在最後一次commit之後free,也沒問題;
plane update操作時,可以只add發生變化的property,其它未發生變化的properties即使沒有被add,在commit時底層驅動仍然會取上一次的值來配置硬體暫存器。
注意:程式執行之前,請確保沒有其它應用或服務占用/dev/dri/card0節點,否則將出現permission denied錯誤。描述:程式執行後,螢幕顯示黑色,終端列印「drmmodeatomiccommit setcrtc」資訊,表明當前已經初始化好crtc/encoder/connector硬體;
輸入回車後,螢幕顯示framebuffer的crop區域,同時終端列印「drmmodeatomiccommit setplane」;
再次輸入回車,顯示黑屏,程式退出
android libdrm: atomictest.c
google chrome: drm-tests/atomictest.c
libdrm mainline: mesa/drm
drm (direct rendering manager) 學習簡介
DRM應用程式高階 (atomic crtc)
為什麼叫 atomic commit 初學者第一次接觸到drm時,總會好奇當初開發者為什麼要起 atomic 這個名字。wiki上關於該名詞有較詳細的解釋,如果大家感興趣可以通過本篇結尾的參考資料獲取鏈結檢視。我這裡用白話簡單概括就是 本次commit操作,要麼成功,要麼保持原來的狀態不變。即如果中...
DRM應用程式高階 (atomic crtc)
為什麼叫 atomic commit 初學者第一次接觸到drm時,總會好奇當初開發者為什麼要起 atomic 這個名字。wiki上關於該名詞有較詳細的解釋,如果大家感興趣可以通過本篇結尾的參考資料獲取鏈結檢視。我這裡用白話簡單概括就是 本次commit操作,要麼成功,要麼保持原來的狀態不變。即如果中...
ios應用程式和應用程式委託
其實說白了,就是乙個類將自己不願意實現的方法以協議的方式定義,同時在這個類中包含有乙個型別為id 泛型類 的例項變數,如果另乙個類實現了這個協議,那麼另外的這個類就可以作為第乙個類的委託物件,前乙個類將自己不願意實現的類委託給後乙個類。因為第乙個類擁有第二個類的引用,所有第乙個類的例項可以直接呼叫第...