決定推出新版面。在深入探討程式設計之前 請回答以下問題,確保自己擁有一切所需:
我如何瞭解裝置和其暫存器的運作方式?
- 這通常稱為「作業理論」。製造商經常提供 含有登錄定義的資料工作表,但這些參考資料可能不會說明 裝置的實際使用方式
是否有類似董事會的驅動程式庫?
- 在可行情況下,您可以重構該程式碼並 修訂驅動程式庫的繫結規則。
裝置是否有固定的螢幕?
- 部分顯示控制器和麵板 (輸出螢幕) 是緊密耦合。 如果是新開發板的案例,請 顯示器驅動程式庫程式中的 GPIO、I2C 和其他控制項。
必要條件
本指南假設您熟悉一或多個驅動程式庫開發程序 以及作業系統同時假設您已熟悉 Fuchsia DDK-TL。
程式語言
新驅動程式必須以 C++ 編寫。已規劃支援 Rust,但效能仍相當高 實驗功能。
已安裝適當授權的驅動程式庫 若是使用 C 語言,則可直接攜碼轉移至 Fuchsia,而非 在 C++ 中實作新版本。請洽詢 graphics-dev@fuchsia.dev 再做出決定
開始使用
如果是沒有 ACPI 或 PCI 匯流排的平台,請改造圖板
驅動程式是第一步。本指南假設
現在可以使用 Jamboard 驅動程式庫,且顯示驅動程式庫的名稱為 fancy
。所有代碼
新驅動程式庫的 src/graphics/display/drivers/fancy-display/
上線。
首先請建立以下項目:
- 最簡單的 DisplayEngine 實作
- 一組繫結規則
DisplayEngine
和繫結規則的建構方案
將驅動程式庫新增至建構作業
- 在名為
BUILD.gn
的檔案中建立建構方案
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/bind/bind.gni")
import("//build/drivers.gni")
driver_bind_rules("fancy-display-bind") {
rules = "meta/fancy-display.bind"
bind_output = "fancy-display.bindbc"
tests = "meta/bind_tests.json"
deps = [
"//src/devices/bind/board_maker_company.platform",
]
}
# Factored out so that it can be used in tests.
source_set("common") {
public_deps = [
":fancy-display-bind",
]
sources = [
"fancy-display.cc",
]
}
fuchsia_driver("fancy-display") {
sources = []
deps = [
":common",
"//src/devices/lib/driver",
]
}
- 將
//src/graphics/display/drivers/fancy-display
新增為 測試產品所使用的 Jamboard。舉例來說,如果您的裝置 Khadas VIM3 開發板的一部分,請將//boards/vim3.gni
值 您的驅動程式庫新增至_common_bootfs_deps
清單。
選擇要駕駛的裝置
現在您已擁有建構方案,可以接著建立 bind 驅動程式管理器判斷驅動程式庫身分。 可與裝置搭配使用
- 在
src/graphics/display/drivers/fancy-display
中建立meta/fancy-display.bind
:
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
using fuchsia.pci;
fuchsia.BIND_PROTOCOL == fuchsia.pci.BIND_PROTOCOL.DEVICE;
fuchsia.BIND_PCI_VID == fuchsia.pci.BIND_PCI_VID.PLANK_HW_INC;
accept fuchsia.BIND_PCI_DID {
// Fancy
0x0100,
// Fancy+ series
0x0120,
0x0121,
}
對於電腦裝置,intel-螢幕繫結規則就是一個很好的例子。適用對象 固定硬體 SoC,請參閱 Amlogic 顯示規則。
極簡驅動程式庫
最後,新增簡單的骨架驅動程式庫 時間。之後,您可以使用規格書 執行特定工作
在 src/graphics/display/drivers/fancy-display
中建立 fancy-display.cc
:
#include <ddktl/device.h>
#include <fuchsia/hardware/display/controller/cpp/banjo.h>
namespace fancy_display {
class Device;
using DeviceType = ddk::Device<Device>
// A Device exposes a single display controller for use by the display
// coordinator driver in src/graphics/display/drivers/coordinator.
//
// This object is constructed once for each device that matches this
// driver's bind rules.
class Device : public DeviceType {
public:
explicit Device(zx_device_t* parent) : DeviceType(parent) {}
// If Bind() returns an error, the driver won't claim the device.
zx_status_t Bind() { return ZX_OK };
// Functionality needed by the common display driver core.
void DisplayEngineRegisterDisplayEngineListener(
const display_engine_listener_protocol* interface) {}
zx_status_t DisplayEngineImportBufferCollection(
uint64_t collection_id, zx::channel collection_token) {
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t DisplayEngineReleaseBufferCollection(
uint64_t collection_id) {
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t DisplayEngineImportImage(const image_metadata_t* image_metadata,
uint64_t collection_id, uint32_t index,
uint64_t* out_image_handle) {
return ZX_ERR_NOT_SUPPORTED;
}
void DisplayEngineReleaseImage(image_t* image) {}
config_check_result_t DisplayEngineCheckConfiguration(
const display_config_t** display_configs, size_t display_count,
client_composition_opcode_t* out_client_composition_opcodes_list, size_t client_composition_opcodes_count,
size_t* out_client_composition_opcodes_actual);
void DisplayEngineApplyConfiguration(
const display_config_t** display_config, size_t display_count) {}
zx_status_t DisplayEngineSetBufferCollectionConstraints(
const image_buffer_usage_t* usage, uint64_t collection_id) {
return ZX_ERR_NOT_SUPPORTED;
}
};
} // namespace fancy_display
// Main bind function called from dev manager.
zx_status_t fancy_display_bind(void* ctx, zx_device_t* parent) {
fbl::AllocChecker alloc_checker;
auto dev = fbl::make_unique_checked<fancy_display::Device>(
&alloc_checker, parent);
if (!alloc_checker.check()) {
return ZX_ERR_NO_MEMORY;
}
auto status = dev->Bind();
if (status == ZX_OK) {
// The driver/device manager now owns this memory.
[[maybe_unused]] auto ptr = dev.release();
}
return status;
}
// zx_driver_ops_t is the ABI between driver modules and the device manager.
// This lambda is used so that drivers can be rebuilt without compiler
// warnings if/when new fields are added to the struct.
static zx_driver_ops_t fancy_display_ops = [](){
zx_driver_ops_t ops;
ops.version = DRIVER_OPS_VERSION;
ops.bind = fancy_display_bind;
return ops;
}();
// ZIRCON_DRIVER marks the compiled driver as compatible with the zircon
// 0.1 driver ABI.
ZIRCON_DRIVER(fancy_display, fancy_display_ops, "zircon", "0.1");
顯示卡驅動程式必須實作 DisplayEngine
「通訊協定」,可公開硬體層並導入 vsync
通知。「顯示協調器」驅動程式庫多工
與顯示器驅動程式庫程式上的所有裝置專用驅動程式相互通訊
堆疊用戶端,也就是系統合成器和 Virtcon。
導入訣竅
驅動程式可決定將設定傳遞至 ApplyConfiguration
的時機和方式
就會生效。為了避免撕裂,駕駛人應
會在 vsync 後立即套用新設定。
大多數裝置會在 vsync 事件中產生中斷情形。您可以輕鬆建構
確保即時 Vsync 通知為產生單獨的執行緒,僅適用於
運作中斷即使沒有顯示任何圖片,駕駛人還是必須
為每個 vsync 呼叫 OnDisplayVsync
。
支援系統啟動載入程式的控制器
如果開機時螢幕處於啟用狀態,例如:表示已開啟的面板 隨後就能在驅動程式中快速取得基本功能。已讀 系統啟動載入程式記錄和/或來源:
- Framebuffer 的實際位址
- 用來編寫該位址的程式
- 圖片的像素尺寸,例如800x600
- 圖片的像素格式,例如RGB888、NV12 或 BGRA8888
然後︰
- 修改驅動程式庫,回報包含格式限制的顯示畫面。
- 記錄
image->handle
中任何匯入映像檔的實體位址。 - 呼叫
ApplyConfig
後,請將暫存器重新編寫程式。
如果您不知道如何觀察 Vsync,可以使用
以 60Hz 呼叫 OnDisplayVsync
。
啟動「黑暗」的控制器
要開啟顯示控制器,並沒有一套方法。 基本的系統啟動載入程式驅動程式庫。在多數情況下,規劃藍圖為: