核心客戶端

此庫為在核心中執行的客戶端提供支援,例如 fbdev 和 bootsplash。

支援提供基於 GEM 的啞緩衝區和虛擬地址的 GEM 驅動程式。

struct drm_client_funcs

DRM 客戶端回撥

定義:

struct drm_client_funcs {
    struct module *owner;
    void (*unregister)(struct drm_client_dev *client);
    int (*restore)(struct drm_client_dev *client);
    int (*hotplug)(struct drm_client_dev *client);
    int (*suspend)(struct drm_client_dev *client, bool holds_console_lock);
    int (*resume)(struct drm_client_dev *client, bool holds_console_lock);
};

成員

owner

模組所有者

unregister

drm_device 被登出時呼叫。 客戶端應使用 drm_client_release() 釋放其資源來響應。

此回撥是可選的。

restore

在 drm_lastclose() 上呼叫。 列表中第一個返回零的客戶端有權恢復,不再呼叫更多客戶端。 在呼叫 unregister 後,不會呼叫此回撥。

請注意,核心不保證排除併發的 drm_open()。 客戶端需要自己確保這一點,例如透過使用 drm_master_internal_acquire() 和 drm_master_internal_release()。

此回撥是可選的。

hotplug

drm_kms_helper_hotplug_event() 上呼叫。 在呼叫 unregister 後,不會呼叫此回撥。

此回撥是可選的。

suspend

暫停裝置時呼叫。

此回撥是可選的。

FIXME:一些呼叫者在呼叫此函式時持有控制檯鎖

功能。 這會干擾 fbdev 模擬,fbdev 模擬也試圖獲取該鎖。 將控制檯鎖推入回撥中,並刪除“holds_console_lock”。

resume

從暫停狀態恢復裝置時呼叫。

此回撥是可選的。

FIXME:一些呼叫者在呼叫此函式時持有控制檯鎖

功能。 這會干擾 fbdev 模擬,fbdev 模擬也試圖獲取該鎖。 將控制檯鎖推入回撥中,並刪除“holds_console_lock”。

struct drm_client_dev

DRM 客戶端例項

定義:

struct drm_client_dev {
    struct drm_device *dev;
    const char *name;
    struct list_head list;
    const struct drm_client_funcs *funcs;
    struct drm_file *file;
    struct mutex modeset_mutex;
    struct drm_mode_set *modesets;
    bool suspended;
    bool hotplug_pending;
    bool hotplug_failed;
};

成員

dev

DRM 裝置

name

客戶端名稱。

list

DRM 裝置的所有客戶端的列表,連結到 drm_device.clientlist 中。 受 drm_device.clientlist_mutex 保護。

funcs

DRM 客戶端函式(可選)

file

DRM 檔案

modeset_mutex

保護 modesets

modesets

CRTC 配置

suspended

客戶端已被暫停。

hotplug_pending

客戶端暫停時已收到熱插拔事件。 恢復後重試。

hotplug_failed

如果熱插拔之前失敗,則由客戶端熱插拔助手設定。 通常不會再次嘗試。

struct drm_client_buffer

DRM 客戶端緩衝區

定義:

struct drm_client_buffer {
    struct drm_client_dev *client;
    u32 pitch;
    struct drm_gem_object *gem;
    struct iosys_map map;
    struct drm_framebuffer *fb;
};

成員

client

DRM 客戶端

pitch

緩衝區 pitch

gem

支援此緩衝區的 GEM 物件

FIXME:此處不需要依賴 GEM,我們可以將驅動程式控制代碼轉換為 dma-buf,並使用後端無關的 dma-buf vmap 支援。 這將需要重新設計 handle2fd prime ioctl,以從驅動程式後端掛鉤中拉出 fd_install 步驟,以使最終步驟對於內部使用者是可選的。

map

緩衝區的虛擬地址

fb

DRM 幀緩衝區

drm_client_for_each_modeset

drm_client_for_each_modeset (modeset, client)

迭代客戶端模式集

引數

modeset

drm_mode_set 迴圈游標

client

DRM 客戶端

drm_client_for_each_connector_iter

drm_client_for_each_connector_iter (connector, iter)

connector_list 迭代器宏

引數

connector

struct drm_connector 用作游標的指標

iter

struct drm_connector_list_iter

描述

這會迭代可用於內部客戶端的聯結器(不包括 writeback 聯結器)。

有關更多資訊,請參見 drm_for_each_connector_iter()

int drm_client_init(struct drm_device *dev, struct drm_client_dev *client, const char *name, const struct drm_client_funcs *funcs)

初始化 DRM 客戶端

引數

struct drm_device *dev

DRM 裝置

struct drm_client_dev *client

DRM 客戶端

const char *name

客戶端名稱

const struct drm_client_funcs *funcs

DRM 客戶端函式(可選)

描述

這會初始化客戶端並開啟一個 drm_file。 使用 drm_client_register() 完成該過程。 呼叫方需要在呼叫此函式之前對 dev 持有引用。 當 drm_device 被登出時,客戶端將被釋放。 請參見 drm_client_release()

返回

成功時返回零,失敗時返回負錯誤程式碼。

void drm_client_register(struct drm_client_dev *client)

註冊客戶端

引數

struct drm_client_dev *client

DRM 客戶端

描述

將客戶端新增到 drm_device 客戶端列表以啟用其回撥。 必須透過呼叫 drm_client_init() 初始化 client。 在 drm_client_register() 之後,不再允許直接呼叫 drm_client_release()(在登出回撥之外),而是將在驅動程式解除安裝時自動進行清理。

註冊客戶端會生成一個熱插拔事件,該事件允許客戶端從預先存在的輸出中設定其顯示。 客戶端必須已初始化其狀態才能成功處理熱插拔事件。

void drm_client_release(struct drm_client_dev *client)

釋放 DRM 客戶端資源

引數

struct drm_client_dev *client

DRM 客戶端

描述

透過關閉由 drm_client_init() 開啟的 drm_file 來釋放資源。 如果 _未_ 設定 drm_client_funcs.unregister 回撥,則會自動呼叫它。

此函式應僅從登出回撥中呼叫。 例外是 fbdev,如果使用者空間有開啟的檔案描述符,則無法釋放緩衝區。

注意

客戶端無法自行啟動釋放。 這樣做是為了簡化程式碼。 驅動程式必須在客戶端可以解除安裝之前解除安裝。

int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer, struct iosys_map *map_copy)

將 DRM 客戶端緩衝區對映到地址空間中

引數

struct drm_client_buffer *buffer

DRM 客戶端緩衝區

struct iosys_map *map_copy

返回對映記憶體的地址

描述

此函式將客戶端緩衝區對映到核心地址空間中。 如果該緩衝區已經對映,則它將返回現有對映的地址。

客戶端緩衝區對映沒有引用計數。 每次呼叫 drm_client_buffer_vmap_local() 之後,都應緊跟呼叫 drm_client_buffer_vunmap_local()。 有關長期對映,請參見 drm_client_buffer_vmap()

返回的地址是內部值的副本。 與其他 vmap 介面相反,客戶端的 vunmap 函式不需要它。 因此,您可以在 blit 和繪製操作期間隨意修改它。

返回

成功時返回 0,否則返回負 errno 程式碼。

void drm_client_buffer_vunmap_local(struct drm_client_buffer *buffer)

取消對映 DRM 客戶端緩衝區

引數

struct drm_client_buffer *buffer

DRM 客戶端緩衝區

描述

此函式刪除使用 drm_client_buffer_vunmap_local() 建立的客戶端緩衝區的記憶體對映。 只有自行管理其緩衝區對映的客戶端才需要呼叫此函式。

int drm_client_buffer_vmap(struct drm_client_buffer *buffer, struct iosys_map *map_copy)

將 DRM 客戶端緩衝區對映到地址空間中

引數

struct drm_client_buffer *buffer

DRM 客戶端緩衝區

struct iosys_map *map_copy

返回對映記憶體的地址

描述

此函式將客戶端緩衝區對映到核心地址空間中。 如果該緩衝區已經對映,則它將返回現有對映的地址。

客戶端緩衝區對映沒有引用計數。 每次呼叫 drm_client_buffer_vmap() 之後,都應緊跟呼叫 drm_client_buffer_vunmap();或者應在其整個生命週期中對映客戶端緩衝區。

返回的地址是內部值的副本。 與其他 vmap 介面相反,客戶端的 vunmap 函式不需要它。 因此,您可以在 blit 和繪製操作期間隨意修改它。

返回

成功時返回 0,否則返回負 errno 程式碼。

void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)

取消對映 DRM 客戶端緩衝區

引數

struct drm_client_buffer *buffer

DRM 客戶端緩衝區

描述

此函式刪除客戶端緩衝區的記憶體對映。 只有自行管理其緩衝區對映的客戶端才需要呼叫此函式。

struct drm_client_buffer *drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)

建立客戶端幀緩衝區

引數

struct drm_client_dev *client

DRM 客戶端

u32 width

幀緩衝區寬度

u32 height

幀緩衝區高度

u32 format

緩衝區格式

描述

此函式建立一個 drm_client_buffer,它由啞緩衝區支援的 drm_framebuffer 組成。 呼叫 drm_client_framebuffer_delete() 以釋放緩衝區。

返回

指向客戶端緩衝區的指標,如果失敗,則指向錯誤指標。

void drm_client_framebuffer_delete(struct drm_client_buffer *buffer)

刪除客戶端幀緩衝區

引數

struct drm_client_buffer *buffer

DRM 客戶端緩衝區(可以為 NULL)

int drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect)

手動重新整理客戶端幀緩衝區

引數

struct drm_client_buffer *buffer

DRM 客戶端緩衝區(可以為 NULL)

struct drm_rect *rect

損壞矩形(如果為 NULL,則重新整理所有)

描述

這會呼叫 drm_framebuffer_funcs->dirty(如果存在),為需要它的驅動程式重新整理緩衝區更改。

返回

成功時返回零,失敗時返回負錯誤程式碼。

int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height)

探測顯示器

引數

struct drm_client_dev *client

DRM 客戶端

unsigned int width

最大顯示模式寬度(可選)

unsigned int height

最大顯示模式高度(可選)

描述

此函式為啟用的聯結器設定顯示管道,並將配置儲存在客戶端的 modeset 陣列中。

返回

成功時返回零,失敗時返回負錯誤程式碼。

bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation)

檢查初始旋轉值

引數

struct drm_mode_set *modeset

DRM modeset

unsigned int *rotation

返回的旋轉值

描述

此函式檢查 **modeset** 中的主平面是否可以進行硬體旋轉,以匹配其聯結器上所需的旋轉。

注意

目前僅支援 0 度和 180 度。

返回

如果平面可以進行旋轉,則為 True;否則為 false。

int drm_client_modeset_check(struct drm_client_dev *client)

檢查 modeset 配置

引數

struct drm_client_dev *client

DRM 客戶端

描述

檢查 modeset 配置。

返回

成功時返回零,失敗時返回負錯誤程式碼。

int drm_client_modeset_commit_locked(struct drm_client_dev *client)

強制提交 CRTC 配置

引數

struct drm_client_dev *client

DRM 客戶端

描述

將 modeset 配置提交到 crtc,而不檢查是否存在 DRM 主裝置。 假設呼叫者已經持有透過 drm_master_internal_acquire() 獲取的內部 DRM 主裝置引用。

返回

成功時返回零,失敗時返回負錯誤程式碼。

int drm_client_modeset_commit(struct drm_client_dev *client)

提交 CRTC 配置

引數

struct drm_client_dev *client

DRM 客戶端

描述

將 modeset 配置提交到 crtc。

返回

成功時返回零,失敗時返回負錯誤程式碼。

int drm_client_modeset_dpms(struct drm_client_dev *client, int mode)

設定 DPMS 模式

引數

struct drm_client_dev *client

DRM 客戶端

int mode

DPMS 模式

注意

對於原子驅動程式,**mode** 簡化為開/關。

返回

成功時返回零,失敗時返回負錯誤程式碼。

void drm_client_dev_unregister(struct drm_device *dev)

登出客戶端

引數

struct drm_device *dev

DRM 裝置

描述

此函式透過呼叫每個客戶端的 drm_client_funcs.unregister 回撥來釋放所有客戶端。回撥函式負責釋放所有資源,包括客戶端本身。

輔助函式 drm_dev_unregister() 呼叫此函式。 使用它的驅動程式無需自行呼叫此函式。

void drm_client_dev_hotplug(struct drm_device *dev)

向客戶端傳送熱插拔事件

引數

struct drm_device *dev

DRM 裝置

描述

此函式呼叫附加客戶端上的 drm_client_funcs.hotplug 回撥。

drm_kms_helper_hotplug_event() 呼叫此函式,因此使用它的驅動程式無需自行呼叫此函式。