跳转到内容

Aros/开发者/GfxDriversDev

来自 Wikibooks,开放世界中的开放书籍
Aros wikibook 的导航栏
Aros用户
Aros用户文档
Aros用户常见问题解答
Aros用户应用程序
Aros用户DOS Shell
Aros/用户/AmigaLegacy
Aros开发文档
Aros开发者文档
从AmigaOS/SDL移植软件
Zune入门
Zune .MUI 类
SDL入门
Aros开发者构建系统
特定平台
Aros x86 完整系统 HCL
Aros x86 音频/视频支持
Aros x86 网络支持
Aros Intel AMD x86 安装
Aros存储支持IDE SATA等
Aros Poseidon USB 支持
x86-64支持
摩托罗拉68k Amiga 支持
Linux和FreeBSD支持
Windows Mingw 和 MacOSX 支持
Android 支持
Arm Raspberry Pi 支持
PPC Power Architecture
其他
Aros公共许可证

扩展AmigaGFX HIDD类,这样我只需要添加尚不存在的屏幕模式。这带来了一些问题:从现有的HIDD(已经是Graphics.hidd类的子类)继承是否实用或可能?这可能,但可能不实用。没有人尝试过。AROS是一个研究操作系统,所以请随意尝试。:)

基于AmigaGFX驱动代码编写新的驱动程序会更好还是更容易?最好是将新模式的支持添加到现有的Amiga驱动程序中。我认为NatAMI芯片组是AGA的超集。多个HIDD会同时加载并共享资源吗?这是真的吗?加载 - 是的。共享资源 - 如果它们被设计为这样做,那么是。但是它可能会有问题。我想继承AmigaGFX驱动程序的原因是为了避免问题并使驱动程序更易于维护。如果扩展一个驱动程序以实现另一个驱动程序是有问题的,我将不得不修改AmigaGFX HIDD。位图HIDD的子类化在某些情况下已经完成。VESA位图是通用块状位图的子类,据我所知,AmigaGFX位图是平面位图类的子类。

isCyberModeID() 在寻找什么?它标记的是缺少Copper还是存在块状像素?块状像素格式。它如何使用?AROS本身不使用它。

当我考虑这一点时,在Indivision ECS或GraffitiGraphics/Indivision AGA 2.0支持中添加块状支持将需要类似的方法,并且还需要这些问题的答案。我已经浏览了WikiBooks上的文档,看起来这可能,但我仍然不确定。

NatAmi中没有小端模式,所以我知道我可以放弃这些模式。R8G8B8模式存储为3个字节平面,而不是纯块状3字节像素宽度,所以我不知道该怎么办,除了在modes枚举中添加混合模式。最重要的是,我需要知道如何告诉AROS硬件支持哪些模式。(我在natamirtg.h中看到一个SUPPORTMASK值,但不知道它是否只是与HIDD的其余部分进行通信,或者是否用于更全局地与CGFX.library进行通信。

我想我的主要问题是这两个:是否有更好的模板可以让我遵循?UAEGFX可能不是最佳选择,因为它有丑陋的模式ID重新映射,模式列表来自UAE,所有模式设置和blit函数都调用UAE本机代码。可能更容易先检查像vga或vesa这样的简单驱动程序,它们具有“正常”模式生成代码,并且没有任何“隐藏”代码。

如果您需要与原始AOS程序兼容的AOS式模式ID范围,可以随时添加模式ID重新映射。

最重要的是,我需要知道如何告诉AROS硬件支持哪些模式。

在gfx类的New方法中,您需要构建一个“像素格式”和“同步”的标记列表,然后将其传递给父类。请参见AROS/workbench/hidds/hidd.nouveau/nouveauclass.c,第355行

        struct TagItem modetags[] = {
        { aHidd_Gfx_PixFmtTags,    (IPTR)pftags_24bpp    },
        { aHidd_Gfx_PixFmtTags,    (IPTR)pftags_16bpp    },
        { TAG_MORE, (IPTR)syncs },  /* FIXME: sync tags will leak */
        { TAG_DONE, 0UL }
        };

        struct TagItem mytags[] = {
        { aHidd_Gfx_ModeTags,    (IPTR)modetags    },
        { TAG_MORE, (IPTR)msg->attrList }
        };

        struct pRoot_New mymsg;

        mymsg.mID = msg->mID;
        mymsg.attrList = mytags;

        msg = &mymsg;

        o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);

在workbench/hidds/hidd.name中

manu_init.c
manu_lowlevel.c
manu_i2c.c
manu_bitmap.c

name_class.c
name_memory.c
name_bios.c
name_driver.c 
name_accel.c

planarbm.c
bitmap.c
compositing_class.c

manu_bitmap.c - VOID 方法

Dispose
Get
Clear
FillRect
DrawLine
DrawRect
DrawPolygon
PutPixel
DrawPixel
DrawEllipse

ReleaseDirectAccess

PutImageLUT
PutAlphaImage
PutImage
GetImage
PutTemplate
PutPattern

name_class.c - OOP_Object 和 VOID

Show
NewBitMap
New

CopyBox
SetCursorShape
SetCursorVisible
SetCursorPos
Get 
Set
aHidd_BitMap_Width
aHidd_BitMap_Height
aHidd_BitMap_PixFmt
aHidd_PixFmt_Depth
aHidd_BitMap_FrameBuffer

aHidd_Sync_PixelClock
aHidd_Sync_HDisp
aHidd_Sync_VDisp
aHidd_Sync_HSyncStart
aHidd_Sync_VSyncStart
aHidd_Sync_HSyncEnd
aHidd_Sync_VSyncEnd
aHidd_Sync_HTotal
aHidd_Sync_VTotal

一个位图是内存位图,另一个是显示驱动程序的位图。

目前,驱动程序在这种情况下调用DoSuperMethod。我可以想象它可以被优化得更多(类似于ATI驱动程序中的PutImage方法),如果目标位图由驱动程序维护,则可以使用DMA引擎。

仅供参考:在这种情况下,内存位图在其布局上可能有一些限制(例如对齐要求)。例如,在我的Windows GDI驱动程序中,BlitColorExpansion() 与planarbm类的真实平面位图完美配合,但是在这种情况下,此位图必须使用显示HIDD的NewBitMap() 方法创建。这意味着它实际上必须是显示位图的朋友(或显示位图朋友的朋友...)。

这使我们重新审视位图友谊的含义。目前,位图继承了其朋友位图的所有特性(内部布局、像素格式和类)。如果它获得了另一个类(因为像素格式是显式指定的),那么友谊实际上就破裂了。在新情况下,这并不意味着友谊完全破裂,因为NewBitMap() 仍然可以对位图进行一些调整。它们只是一些更遥远的朋友......

但是,如果位图是在没有朋友规范的情况下创建的,并且是在没有显式显示模式规范的情况下创建的,那么它将是一个纯基于RAM的位图。图形驱动程序不太可能以加速方式处理它(因为对齐方式不正确)。所以问题是 - 实施这种机制有多安全?我们是否会最终得到速度缓慢的图形,因为设计上无法加速,因为一半的位图将在没有任何朋友规范的情况下创建。

图形驱动程序能够以加速方式处理来自任意格式位图(没有任何强制对齐等)的blit的可能性有多大?

在这种情况下,DoSuperMethod 调用很慢,但很安全,因为它将使用两个驱动程序的GetPixel/PutPixel 方法以安全的方式传输位图。当然,这种情况也可以进一步优化。

所以,卡实际上可以通过DMA相互传输数据?

fakegfxhidd(软件鼠标光标)可以支持ShowViewPorts() 吗?不需要合成/多个视窗,只需要获取视窗信息。

检查PrepareViewPorts。它始终被调用。顺便说一下,它直接获取 struct View*。您可以在视窗链中的第一个位图中记住您收集的信息。这将被传递给Show。在fakegfx中实现ShowViewPorts 似乎是有问题的,因为它与帧缓冲区无法很好地共存。顺便说一下,您也可以实现 ShowViewPorts,它执行一些准备工作并返回 FALSE。

帧缓冲区驱动程序和镜像驱动程序有什么区别?在帧缓冲区驱动程序中,实际上只有一个屏幕上的位图,该位图会不断显示,而Show 实际上是通过复制内容和替换位图对象来模拟的。镜像实际上是避免缓慢的VRAM读取。镜像驱动程序不使用VRAM来存储位图对象,而是使用镜像缓冲区,并在需要时更新VRAM。由于镜像驱动程序具有显示位图的完整副本,因此不需要模拟Show。相反,它只是将不同的镜像附加到VRAM。因此,VESA 和 VGA 驱动程序不需要标记为帧缓冲区驱动程序,因为它们使用镜像?是的,它们不需要。镜像驱动程序自己处理VRAM,它们不需要Show 模拟。打开帧缓冲区对它们来说只是浪费内存。顺便说一下,我的驱动程序在这样做时返回 NULL。这些驱动程序通过将 aHidd_Gfx_NoFrameBuffer 属性的值返回为 TRUE 来表明这一点。

尝试使合成类对驱动程序也变得可共享。这种方法有一个优点。对于镜像驱动程序来说它更快,因为您可以直接将位图合成到VRAM中。所以,从长远来看,我们可能会最终使用一个基础合成类和一系列子类来满足不同的驱动程序类型。顺便说一下,也许软件精灵模拟也可以这样做。将它的图像直接放入VRAM 中比由 fakegfx 支持的复制更快,并且闪烁更少。VESA 驱动程序现在将在一个光标大小的临时位图上叠加光标,并在之前将正确的背景部分复制到其中。我尝试过将光标直接通过 alpha blit 方式写入VRAM,但这太麻烦了,因为无法在VRAM 上使用 PutAlphaImage 来支持所有颜色深度。

此外,正如 GMA 所做的那样,驱动程序可以在 ShowViewPorts 中检测到是否只有最顶层的屏幕可见,并停用镜像,这样每个 blit 不会被重复。不幸的是,不会。镜像不仅仅是一种进行合成的方式。它的主要目的是避免缓慢的VRAM读取。如果您绕过了它,并且只是将位图放在VRAM 中(帧缓冲区方法),它会非常慢。这就是为什么在 VGA 和 VESA 中进行镜像的原因。

叠加层

[编辑 | 编辑源代码]

CreateVLayerHandleTagList() 和 DeleteVLayerHandle() 是添加到图形驱动程序类中的两个方法,以及为叠加层类开发的一些属性。目前没有叠加层基类,因为我认为在那里放什么。

Intuitions 真的需要了解物理显示器吗?将来,当我实现整个类时,它将能够维护有关它们在物理空间中的相对位置的信息。这对于正确处理多显示器输入是必要的。

其余部分是对MorphOS API的重新实现。我决定不再重新发明轮子,而是使用现有的API。我希望保持扩展之间的兼容性。

到目前为止,我们拥有干净的层:Intuition 位于 Graphics 之上,Graphics 位于 Graphics HIDD 之上。现在,我们引入了 Intuition 和 Graphics HIDD 之间的连接,以便 Monitor 类可以读取 HIDD 信息。Intuition 已经使用直接 HIDD 访问 - 在 pointerclass 中,它将调色板附加到精灵位图。是的,它有什么不好?即使是一个普通的应用程序也可能会查询 HIDD 信息,如果它想要的话。

Monitorclass 是 BOOPSI 的一部分,而 BOOPSI 又是 Intuition 的一部分。代码本身可以移到 graphics.library,但仍然需要 Intuition 才能调用 MakeClass()。

这里有些人反对添加越来越多的私有函数。我们的 graphics.library 已经为 CGX 操作提供了 7 个私有函数,还有一个 AROS 特定的 AddDisplayDriverA()。我认为这已经足够了。事实上,我做了完全按照建议做的事情——将 AROS 特定的功能移到一个新的 AROS 特定的模块。在这种情况下,这个模块已经存在——它是 graphics.hidd。在其之上运行的组件可以在需要时直接与它通信。

说实话,我只不喜欢一件事——我将 AddDisplayDriverA() 声明为公共函数。我应该从一开始就实现 monitorclass,Intuition 会在创建 monitorclass 对象时调用私有的 AddDisplayDriverA()。好吧,已经做完了。我不会重写整个东西。现在,AddDisplayDriverA() 会在驱动程序安装成功后创建 monitorclass 对象。但是,AddDisplayDriverA 不是 graphics.library 的函数吗?这意味着提供功能的模块(graphics.library)现在将依赖于使用功能的模块(intuition.library)。这就像浏览器依赖于网络堆栈,同时网络堆栈又依赖于浏览器一样。在这个更改之后,即使没有 intuition,graphics.library 还能运行吗?我认为,这也是将 monitor class 分离到另一个模块的理由。MorphOS 可能把它放在了 Intuition 中,但我们不必这样做——我们可以保留接口,但以更合适的形式实现它。

是的,在一方面。但是我不会称之为严格的依赖关系。AddDisplayDriverA() 在其末尾可能会做以下事情

if (!IntuitionBase)
     IntuitionBase = OpenLibrary("intuition.library", 50);
if (!IntuitionBase)
     return ret;

mon = NewObjectA(NULL, "monitorclass", tags);

这样,graphics.library 就不再使用 intuition.library 的任何功能。它只是为 intuition.library 提供一些信息(告诉它新的显示器)。

类似的代码已经存在于 graphics.hidd 的 sync 类中,它手动打开 graphics.library,创建 MonitorSpec 结构并将它添加到 MonitorList 中。

graphics.hidd 没有 RastPort 结构,这意味着它不与 Layers 一起工作。这意味着——没有窗口和屏幕。理论上,可以在某种简单的嵌入式系统上使用 HIDDs 进行绘图,该系统不运行多个应用程序也不需要窗口。它类似于在 AmigaOS 上手动构建 ViewPort 和 View(这也适用于 AROS)。

Linux 驱动程序

[编辑 | 编辑源代码]

Linux 驱动程序堆栈

有关编写驱动程序的信息,请参阅 Unix X 服务器图形驱动程序 并学习 源代码

Linux Radeon 构建。 博客

参考资料

[编辑 | 编辑源代码]

参见 此处

完成 状态

HIDDM_Graphics_Cmd	
HIDDM_Graphics_MCmd	
HIDDM_Graphics_MQCmd	
HIDDM_Graphics_QCmd	

HIDDV_Graphics_Cmd_CheckTOF	
HIDDV_Graphics_Cmd_Clear	
HIDDV_Graphics_Cmd_CopyArea	
HIDDV_Graphics_Cmd_CreateBitMap	
HIDDV_Graphics_Cmd_CreateGC	
HIDDV_Graphics_Cmd_DeleteBitMap	
HIDDV_Graphics_Cmd_DeleteGC	
HIDDV_Graphics_Cmd_DepthArrangeBitMap	
HIDDV_Graphics_Cmd_DrawEllipse	
HIDDV_Graphics_Cmd_DrawLine	
HIDDV_Graphics_Cmd_DrawPolygon	
HIDDV_Graphics_Cmd_DrawRect	
HIDDV_Graphics_Cmd_DrawText	
HIDDV_Graphics_Cmd_FillEllipse	
HIDDV_Graphics_Cmd_FillPolygon	
HIDDV_Graphics_Cmd_FillRect	
HIDDV_Graphics_Cmd_FillSpan	
HIDDV_Graphics_Cmd_FillText	
HIDDV_Graphics_Cmd_GetPixel	
HIDDV_Graphics_Cmd_MoveBitMap	
HIDDV_Graphics_Cmd_SetPixel	
HIDDV_Graphics_Cmd_ShowBitMap	
HIDDV_Graphics_Cmd_Special	
HIDDV_Graphics_Cmd_WaitTOF
华夏公益教科书