KMS(2)
KMS核心結(jié)構(gòu)和函數(shù)
struct drm_mode_config_funcs
提供模式設(shè)置功能的基本驅(qū)動(dòng)程序
定義
struct drm_mode_config_funcs {
struct drm_framebuffer *(*fb_create)(struct drm_device *dev,struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd);
const struct drm_format_info *(*get_format_info)(const struct drm_mode_fb_cmd2 *mode_cmd);
void (*output_poll_changed)(struct drm_device *dev);
enum drm_mode_status (*mode_valid)(struct drm_device *dev, const struct drm_display_mode *mode);
int (*atomic_check)(struct drm_device *dev, struct drm_atomic_state *state);
int (*atomic_commit)(struct drm_device *dev,struct drm_atomic_state *state, bool nonblock);
struct drm_atomic_state *(*atomic_state_alloc)(struct drm_device *dev);
void (*atomic_state_clear)(struct drm_atomic_state *state);
void (*atomic_state_free)(struct drm_atomic_state *state);
};
成員
fb_create
創(chuàng)建一個(gè)新的framebuffer對(duì)象。核心對(duì)請(qǐng)求的元數(shù)據(jù)進(jìn)行基本檢查,但大部分檢查留給驅(qū)動(dòng)程序。詳見(jiàn)結(jié)構(gòu)drm_mode_fb_cmd2。
為了驗(yàn)證像素格式和修飾符,驅(qū)動(dòng)程序可以使用drm_any_plane_has_format()來(lái)確保至少有一個(gè)平面支持請(qǐng)求的值。注意,如果請(qǐng)求沒(méi)有指定modifier,即當(dāng)(mode_cmd->flags & DRM_MODE_FB_MODIFIERS) == 0,驅(qū)動(dòng)程序必須首先確定實(shí)際使用的修飾符。
重要提示:如果修飾符啟用了超出fourcc像素格式代碼的額外plane,這些原來(lái)用戶空間傳遞給內(nèi)核的隱含修飾符必須存儲(chǔ)在drm_framebuffer結(jié)構(gòu)中,包括所有相關(guān)的元數(shù)據(jù),如drm_framebuffer.pitches和drm_framebuffer.offsets。這是GETFB2 ioctl所需要的。
如果參數(shù)被認(rèn)為是有效的,并且底層內(nèi)存管理器中的后備存儲(chǔ)對(duì)象都存在,那么驅(qū)動(dòng)程序分配一個(gè)新的drm_framebuffer結(jié)構(gòu),子類化以包含驅(qū)動(dòng)程序特定的信息(如內(nèi)部本地緩沖區(qū)對(duì)象引用)。它還需要填寫(xiě)所有相關(guān)的元數(shù)據(jù),這應(yīng)該通過(guò)調(diào)用drm_helper_mode_fill_fb_struct()來(lái)完成。
初始化通過(guò)調(diào)用drm_framebuffer_init()來(lái)完成,drm_framebuffer_init()注冊(cè)framebuffer并使其他線程可以訪問(wèn)它。
返回值
一個(gè)新的framebuffer,其初始引用計(jì)數(shù)為1或一個(gè)用ERR_PTR()編碼的負(fù)錯(cuò)誤碼。
get_format_info
允許驅(qū)動(dòng)程序返回特定fb布局的自定義格式信息(例如帶有輔助壓縮控制平面的信息)。
返回值
特定于給定fb元數(shù)據(jù)的格式信息,如果沒(méi)有找到,則為NULL。
output_poll_changed
helper程序使用回調(diào)函數(shù)通知驅(qū)動(dòng)程序輸出配置已經(jīng)更改。
通過(guò)helper程序?qū)崿F(xiàn)此函數(shù)的驅(qū)動(dòng)程序可以從這個(gè)鉤子調(diào)用drm_fb_helper_hotplug_changed來(lái)通知fbdev助手輸出配置發(fā)生了變化。
FIXME:除了設(shè)備級(jí)helper回調(diào)沒(méi)有虛表之外,這沒(méi)有理由是一個(gè)核心函數(shù)。
mode_valid
具體設(shè)備的顯示模式驗(yàn)證。可用于拒絕永遠(yuǎn)不支持的模式。只有設(shè)備范圍的限制可以在這里檢查。對(duì)于每個(gè)特定的對(duì)象,應(yīng)該在.mode_valid()鉤子中檢查特定的crtc/encoder/bridge/connector約束。
atomic_check
這是驗(yàn)證原子模式集更新的唯一鉤子。該函數(shù)必須拒絕硬件或驅(qū)動(dòng)程序不支持的任何模式集和狀態(tài)更改。這包括但當(dāng)然不限于:
檢查模式、幀緩沖區(qū)、縮放和放置需求等是否在硬件的限制范圍內(nèi);
檢查任何隱藏的共享資源是否超額使用。這可以共享pll,共享通道,總體內(nèi)存帶寬,顯示fifo空間(在planes之間共享,甚至crtc);
檢查導(dǎo)出到用戶空間的虛擬化資源是否超額使用。出于各種原因,我們可以導(dǎo)出比實(shí)際硬件更多的planes、crtcs或encoders。一個(gè)例子是雙管道操作(通常應(yīng)該從用戶空間隱藏,和硬件保持一致),plane可能需要1個(gè)硬件plane(如果它只是一個(gè)管道),2個(gè)硬件plane(當(dāng)它跨越兩個(gè)管道)甚至和第二平面共享硬件平面(如果有一個(gè)其他管道要求的兼容的plane);
檢查任何過(guò)渡狀態(tài)是否可能,如果有請(qǐng)求,更新確實(shí)可以在vblank期間完成,而不會(huì)暫時(shí)禁用一些功能。
檢查驅(qū)動(dòng)程序或硬件可能有的任何其他約束;
這個(gè)回調(diào)函數(shù)還需要正確地填寫(xiě)這個(gè)更新中的drm_crtc_state,以確保drm_atomic_crtc_needs_modeset()反映了可能更新的性質(zhì),并且當(dāng)且僅當(dāng)在該CRTC上的一個(gè)vblank中沒(méi)有被刪除而不能應(yīng)用更新時(shí)返回true。如果用戶空間在其請(qǐng)求中不允許更新,核心將使用這些信息來(lái)拒絕需要完整模式集的更新(即,屏蔽屏幕,或至少暫停更新相當(dāng)長(zhǎng)的時(shí)間);
驅(qū)動(dòng)程序也不需要像對(duì)相應(yīng)的遺留入口點(diǎn)那樣重復(fù)基本的輸入驗(yàn)證。core在調(diào)用這個(gè)鉤子之前做這個(gè)。
請(qǐng)參閱atomic_commit的文檔,了解不需要在這個(gè)回調(diào)中檢查的詳盡錯(cuò)誤列表。
請(qǐng)參閱結(jié)構(gòu)drm_atomic_state的文檔,了解如何準(zhǔn)確地描述原子模式集更新。
使用原子幫助程序的驅(qū)動(dòng)程序可以使用drm_atomic_helper_check()或它導(dǎo)出的子函數(shù)之一來(lái)實(shí)現(xiàn)這個(gè)鉤子函數(shù)。
返回值
0表示成功,或者下面的負(fù)錯(cuò)誤碼之一:
-EINVAL,如果違反上述任何約束。
當(dāng)試圖通過(guò)drm_modeset_lock()獲取額外的drm_modeset_lock時(shí)返回-EDEADLK。
-ENOMEM,如果由于缺乏內(nèi)存而分配額外的狀態(tài)子結(jié)構(gòu)失敗。
-EINTR、-EAGAIN或-ERESTARTSYS,如果IOCTL需要重新啟動(dòng)。這可能是由于一個(gè)待定的信號(hào),或者因?yàn)轵?qū)動(dòng)程序需要完全退出,以從異常情況下恢復(fù),如GPU掛起。從用戶空間的角度來(lái)看,所有的錯(cuò)誤都是平等對(duì)待的。
atomic_commit
這是提交原子模式集更新的唯一鉤子。核心保證在調(diào)用這個(gè)函數(shù)之前已經(jīng)成功地調(diào)用了atomic_check,并且在此期間沒(méi)有任何更改。
請(qǐng)參閱結(jié)構(gòu)drm_atomic_state的文檔,了解如何準(zhǔn)確地描述原子模式集更新。
使用原子幫助程序的驅(qū)動(dòng)程序可以使用drm_atomic_helper_commit()或它導(dǎo)出的子函數(shù)之一來(lái)實(shí)現(xiàn)這個(gè)鉤子。
非阻塞提交(用nonblock參數(shù)表示)必須在回調(diào)的上下文中做任何可能導(dǎo)致不成功提交的準(zhǔn)備工作。唯一的例外是導(dǎo)致-EIO的硬件錯(cuò)誤。但即使在這種情況下,驅(qū)動(dòng)程序也必須確保顯示管道至少正在運(yùn)行,以避免當(dāng)pageflips不起作用時(shí)compositors崩潰。其他任何事情,特別是將更新提交給硬件,都應(yīng)該在不阻塞調(diào)用者的情況下完成。對(duì)于不需要修改模式設(shè)置的更新操作,必須保證這一點(diǎn)。
在執(zhí)行flip之前,驅(qū)動(dòng)程序必須等待framebuffer的渲染完成。如果底層緩沖區(qū)是共享dma-buf,它還應(yīng)該等待來(lái)自其他驅(qū)動(dòng)程序的未完成的渲染完成。非阻塞提交絕不能在這個(gè)回調(diào)的上下文中等待渲染。
當(dāng)原子提交完成時(shí),應(yīng)用程序可以請(qǐng)求得到通知。這些事件是針對(duì)每個(gè)CRTC的,可以通過(guò)drm_event提供給用戶空間的CRTC索引來(lái)區(qū)分不同的crtc.
drm核心將在每個(gè)CRTC的drm_crtc_state.event中提供一個(gè)結(jié)構(gòu)drm_event。請(qǐng)參閱drm_crtc_state.event以獲取有關(guān)此事件的精確語(yǔ)義的更多細(xì)節(jié)。
驅(qū)動(dòng)程序不允許關(guān)閉任何通過(guò)原子提交成功啟用的顯示管道。如果因?yàn)楣艿狸P(guān)閉而突然拒絕page flip,那么這樣做可能會(huì)導(dǎo)致合成器崩潰。
返回:
0表示成功,或者下面的負(fù)錯(cuò)誤碼之一:
-EBUSY,如果請(qǐng)求了一個(gè)非阻塞更新,并且有一個(gè)較早的更新等待處理。允許驅(qū)動(dòng)程序支持一個(gè)未完成更新隊(duì)列,但目前還沒(méi)有驅(qū)動(dòng)程序支持。注意,如果請(qǐng)求同步更新,驅(qū)動(dòng)程序必須等待之前的更新完成,在這種情況下,它們不允許提交失敗。
-ENOMEM,如果驅(qū)動(dòng)分配內(nèi)存失敗。特別地,當(dāng)試圖固定framebuffer時(shí)可能會(huì)發(fā)生這種情況,而這只能在提交狀態(tài)時(shí)才能完成.
-ENOSPC,作為更通用的-ENOMEM的一個(gè)改進(jìn),表明驅(qū)動(dòng)程序已經(jīng)用完vram, iommu空間或幀緩沖區(qū)所需的類似GPU地址空間。
-EIO,如果硬件完全死機(jī)。
-EINTR、-EAGAIN或-ERESTARTSYS,如果IOCTL需要重新啟動(dòng)。這可能是由于一個(gè)待定的信號(hào),或者因?yàn)轵?qū)動(dòng)程序需要完全卸載,以從異常情況下恢復(fù),如GPU掛起。從用戶空間的角度來(lái)看,所有的錯(cuò)誤都是平等對(duì)待的。
這個(gè)列表是詳盡無(wú)遺的。特別地,這個(gè)鉤子不允許返回-EINVAL(任何無(wú)效的請(qǐng)求都應(yīng)該被atomic_check捕獲)或-EDEADLK(這個(gè)函數(shù)不能獲得額外的modesset鎖)。
atomic_state_alloc
這個(gè)可選的鉤子可以被那些想要繼承drm_atomic_state結(jié)構(gòu)的驅(qū)動(dòng)程序使用,以便能夠輕松地跟蹤它們自己的驅(qū)動(dòng)私有全局狀態(tài)。如果實(shí)現(xiàn)了這個(gè)鉤子,驅(qū)動(dòng)程序也必須實(shí)現(xiàn)atomic_state_clear和atomic_state_free。
不贊成繼承drm_atomic_state,而贊成使用drm_private_state和drm_private_obj。
返回值
成功時(shí)返回drm_atomic_state,失敗時(shí)為NULL。
atomic_state_clear
這個(gè)鉤子必須清除任何復(fù)制到傳入drm_atomic_state的驅(qū)動(dòng)程序私有狀態(tài)。這個(gè)鉤子在調(diào)用者遇到drm_modeset_lock死鎖時(shí)被調(diào)用,并且需要?jiǎng)h除所有已經(jīng)獲得的鎖,作為drm_modeset_backoff()中實(shí)現(xiàn)的避免死鎖操作的一部分。
任何復(fù)制的狀態(tài)都必須是無(wú)效的,因?yàn)椴l(fā)的原子更新可能會(huì)更改它,而且當(dāng)當(dāng)前狀態(tài)更改后,drm原子接口總是應(yīng)用更新。
實(shí)現(xiàn)這個(gè)的驅(qū)動(dòng)程序必須調(diào)用drm_atomic_state_default_clear()來(lái)清除公共狀態(tài)。
不贊成繼承drm_atomic_state,而贊成使用drm_private_state和drm_private_obj。
atomic_state_free
這個(gè)鉤子需要驅(qū)動(dòng)程序私有資源和drm_atomic_state本身。注意,核心首先調(diào)用drm_atomic_state_clear()來(lái)避免clear和free鉤子之間的代碼重復(fù)。
實(shí)現(xiàn)這個(gè)的驅(qū)動(dòng)程序必須調(diào)用drm_atomic_state_default_release()來(lái)釋放公共資源。
不贊成繼承drm_atomic_state,而贊成使用drm_private_state和drm_private_obj.
總結(jié)
- 上一篇: corn表达式
- 下一篇: wget命令3(转载)