Broadcom Nexus学习(一):Graphics

0. Broadcom Nexus介绍:

Nexus是Broadcom提供的一套开发中间件,以标准API形式为Digital TV 和Set-Top boxes上层程序提供标准接口,它将不同的底层与上层开发隔绝开来,以达到上层开发与底层无关的目的。所有Interface的用法和思路基本上是一致的。最先接触到的Nexus模块就是 Graphics.

 

1. Nexus Platform 接口和初始化:

Nexus有个API初始化各个模块以及硬件(NEXUS_Platform_Init())。应用程序也可以利用其参数定制初始化哪些模块以及动作。通常使用NEXUS_Platform_GetDefaultSettings()得到缺省的setting.修改想要修改的内容,之后再调用NEXUS_Platform_Init()初始化Platform. 

NEXUS_PlatformSettings platformSettings; NEXUS_Platform_GetDefaultSettings(&platformSettings); //.... 修改必要的设置 NEXUS_Platform_Init(&platformSettings);

NEXUS_PlatformSettings结构体中可选择的选项通常有:I2C channel是否打开,是否FPGA channel打开,是否打开output等。

 

NEXUS_Platform_Init()会自动地打开和配置Interface.(如各种output等)。应用程序不应该再次去打开它,而是使用NEXUS_Platform_GetConfiguration()重新得到Handle.

NEXUS_PlatformConfiguration platformConfiguration; NEXUS_Platform_GetConfiguration(&platformConfiguration);

NEXUS_PlatformConfiguration结构体包含如下内容:

typedef struct NEXUS_PlatformConfiguration { NEXUS_ComponentOutputHandle component[NEXUS_NUM_COMPONENT_OUTPUTS]; NEXUS_CompositeOutputHandle composite[NEXUS_NUM_COMPOSITE_OUTPUTS]; NEXUS_RfmHandle rfm[NEXUS_NUM_RFM_OUTPUTS]; NEXUS_SvideoOutputHandle svideo[NEXUS_NUM_SVIDEO_OUTPUTS]; NEXUS_AudioDacHandle audioDacs[NEXUS_NUM_AUDIO_DACS]; NEXUS_SpdifOutputHandle spdif[NEXUS_NUM_SPDIF_OUTPUTS]; NEXUS_I2sOutputHandle i2s[NEXUS_NUM_I2S_OUTPUTS]; NEXUS_HdmiOutputHandle hdmi[NEXUS_NUM_HDMI_OUTPUTS]; NEXUS_Ccir656OutputHandle ccir656[NEXUS_NUM_656_OUTPUTS]; } outputs;

我们通常最关心的是output Handle,分量,混合和Svideo output handle就在其中。

 

 

2. Graphics 具体讲解:

Nexus graphics 包含几个Interface. 各个Interface各自提供一些能力,应用程序可以将它们组合起来使用。

Interface包含如下:

 

Display: 是Graphics模块的核心,它指定哪个surface为framebuffer(当前显示的)。指定哪几个output会输出(composite,svideo等),以及如何将framebuffer合成到video上。

 

Surface: 其实就是一块内存。创建Surface时用参数指定:width, height, pitch, pixel format。长度x宽度x每个象素的长度就决定了Surface大小。可创建surface的个数限制于分配给Nexus的堆大小。

 

Graphics2D: 提供从一块surface blit(整块copy)到另一块surface的能力。提供填充一块surface 使用某种颜色和Alpha的能力。

 

Graphics3D: 提供适配一个3D graphics到Surface的能力。

 

VideoImageInput:Route graphics through the video feeder hardware (MFD)

 

2.1. Surface的创建(NEXUS_Surface_Create):

Surface使用NEXUS_Surface_Create创建。Surface的长度,宽度,深度,pixel format则可以由参数决定。

具体过程如下:

NEXUS_SurfaceHandle surface; NEXUS_SurfaceCreateSettings createSettings; NEXUS_Surface_GetDefaultCreateSettings(&createSettings); createSettings.pixelFormat = NEXUS_PixelFormat_eA8_R8_G8_B8; createSettings.width = 720; createSettings.height = 480; surface = NEXUS_Surface_Create(&createSettings);

NEXUS_SurfaceCreateSettings:结构体中包含了Surface的一些关键点:象素格式,调色板格式,surface长度,宽度。倾斜度(缺省为:象素长度x宽度,也就是每行的字节数)

 

2.2:Display的建立和配置:

 

2.2.1: Display的创建:

与Surface创建相同,Display创建时,也需要参数来指定Display的创建模式。

NEXUS_DisplaySettings displaySettings; NEXUS_DisplayHandle display; NEXUS_Display_GetDefaultSettings(&displaySettings); displaySettings.format = NEXUS_VideoFormat_eNtsc; display = NEXUS_Display_Open(0, &displaySettings);

NEXUS_DisplaySettings 结构体中包含Display的一些选项。其中format表明此Display将要输出的制式。它决定了TV中显示的宽,高。

 

2.2.2:Display显示输出channel的配置:

如前所述,在Platform初始化时,Output Interface已经被打开。此时需要得到它们的Handle. 给Display添加Output .

NEXUS_PlatformConfiguration platformConfig; NEXUS_Platform_GetConfiguration(&platformConfig); NEXUS_Display_AddOutput(display, NEXUS_ComponentOutput_GetConnector(platformConfig.outputs.component[0])); NEXUS_Display_AddOutput(display, NEXUS_CompositeOutput_GetConnector(platformConfig.outputs.composite[0]));

此处Display添加了分量和混合2种输出。

 

2.2.3:Display Frame buffer的指定:

只有将某个Surface指定为Frame buffer, Surface中的内容才会按格式和设置显示到TV上。所以应用程序可以创建2-3个surface,轮流指定为Frame Buffer来加快速度。

NEXUS_Display_SetGraphicsFramebuffer(display, surface);

  

3. Graphics2D的建立和使用:

3.1:Graphics2D的建立:

Graphics2D的建立与其它Interface相同,需要参数指定Graphics2D的特征。

NEXUS_Graphics2DHandle gfx; NEXUS_Graphics2DOpenSettings openSettings; openSettings.preAllocPacketMemory = true; //if maxOperations is non-zero, this must be true. openSettings.maxOperations = 100; //同步,异步blit的最大次数。如果是异步blit,则需要在blit次数超此次数之前使用NEXUS_Graphics2D_Checkpoint()。 gfx = NEXUS_Graphics2D_Open(0, &openSettings);

3.3: Graphics2D Setting:

NEXUS_Graphics2DSettings gfxSettings; NEXUS_Graphics2D_GetSettings(gfx, &gfxSettings); gfxSettings.checkpointCallback.callback = complete; gfxSettings.checkpointCallback.context = event; NEXUS_Graphics2D_SetSettings(gfx, &gfxSettings);

NEXUS_Graphics2DSettings比较重要的参数有:

 

bool blockedSync; //如果为true,则所有fill,blit会阻塞直到动作完成。(只有简单的程序会这么用)

此时,不需要NEXUS_Graphics2D_Checkpoint。

如果为false,则fill,blit不会被阻塞。所以需要NEXUS_Graphics2D_Checkpoint()来检测fill或blit动作是否已经完成。

 

NEXUS_CallbackDesc checkpointCallback;  在异步时使用,NEXUS_Graphics2D_Checkpoint()会调用它的callback。第一个参数为context.

 

callback function通常的处理是:BKNI_SetEvent(),发送一个event.

 

3.4:Graphics2D Fill:

在使用Fill功能时,需要先指定Surface. fill的颜色,Fill Surface的区域,color和alpha方式等。

NEXUS_Graphics2D_GetDefaultFillSettings(&fillSettings); fillSettings.surface = framebuffer; //指定surface. fillSettings.rect.width = createSettings.width; //如果要fill整个surface. x,y=0. width,height与surface宽高相同。 fillSettings.rect.height = createSettings.height; fillSettings.color = 0; //色彩方式 NEXUS_Graphics2D_Fill(gfx, &fillSettings);

如果为异步方式(3.3中讲过),Fill后,必须加上NEXUS_Graphics2D_Checkpoint(gfx, NULL); 以确认Fill动作已真的完成。

注意:此处NEXUS_Graphics2D_Checkpoint(gfx, NULL); 只是察看Graphics Hardware是否正在Blit或Fill. 如果返回值为Success.表明当前硬件没有Blit或Fill. 如果返NEXUS_GRAPHICS2D_QUEUED,则表明此时有Fill或Blit在排队。此时,当Blit或Fill完成时NEXUS_Graphics2DSettings::checkpointCallback 会被调用。

 

如3.3所讲,NEXUS_Graphics2D_Checkpoint()如果返回Success,则表明Fill完成,如果返回NEXUS_GRAPHICS2D_QUEUED,则在Fill动作完成后,自动调用callback function. Callback function又发送了一个event. 所以可以在NEXUS_Graphics2D_Checkpoint(gfx, NULL); 后添加:BKNI_WaitForEvent();来确认Fill动作的完成。

 

3.5: Graphics2D Blit:

与其它动作类似,Blit也需要得到setting. 并设置想要blit的源sruface和目标surface. 以及各自的区域。

NEXUS_Graphics2DBlitSettings blitSettings; NEXUS_Graphics2D_GetDefaultBlitSettings(&blitSettings); blitSettings.source.surface = surface; blitSettings.source.rect.x = 0; blitSettings.source.rect.y = 0; blitSettings.source.rect.width = 100; blitSettings.source.rect.height = 140; blitSettings.output.surface = surface; blitSettings.output.rect.x = (rand() % (createSettings.width-120)) + 100; blitSettings.output.rect.y = (rand() % (createSettings.height-20)); blitSettings.output.rect.width = 20; blitSettings.output.rect.height = 20; blitSettings.colorOp = NEXUS_BlitColorOp_eCopySource; blitSettings.alphaOp = NEXUS_BlitAlphaOp_eCopySource; rc = NEXUS_Graphics2D_Blit(gfx, &blitSettings);

 

4. Surface的长度,宽度的决定:

看到这个条目,可能会觉得有些奇怪,Surface的长宽,不是由自己指定的吗。呵呵,其实意思是决定Surface长宽的因素总结。

 

Surface如果想全屏显示于Display当前的video format下。则需要与video format长宽相同。

NEXUS_VideoFormat_GetInfo(displaySettings.format, &videoFormatInfo); //从display video 取出信息 createSettings.pixelFormat = NEXUS_PixelFormat_eA8_R8_G8_B8; createSettings.width = videoFormatInfo.width; //讲长度宽度设置为与video format相同 createSettings.height = videoFormatInfo.height; surface = NEXUS_Surface_Create(&createSettings);

还有一种情况比较特殊,下一节统一讲。

 

5.Display 如何放置Graphics Frame buffer于Video Window相关知识:

Display可以指定某个Surface为Graphics Frame buffer.但是Surface是否要全部显示,以及显示在TV屏幕的哪个位置,这是可设定的。下面就详细分析这个议题。

首先,有4个宽高值需要注意:

1. VideoWindow的宽高。

2. GraphicsFramebuffer的宽高。

3. Surface的宽高。

4. Display video format的宽高。

 

Display的video format决定了TV屏幕的大小,也就是VideoWindow的大小。所以Dispaly Video format的宽高等同于VideoWindow的宽高。

GraphicsFramebuffer的大小应该是个虚值,可能与它指定的Surface相同。

Surface的大小可以自己定义,但哪一部份显示则由Display指定。

 

结构体NEXUS_GraphicsSettings中的值决定了Display如何将Graphics Frame buffer匹配于VideoWindow.也就是说将Graphics Frame Buffer如何放置于TV 屏幕。放置在什么位置,显示哪一部份Frame buffer内容等等。(所以前面说surface指定为framebuffer并不意味着它能全部显示)

NEXUS_Rect position; NEXUS_Rect clip; typedef struct NEXUS_Rect { int16_t x; int16_t y; uint16_t width; uint16_t height; } NEXUS_Rect;

NEXUS_Rect结构体是个矩形,x,y表示左上角位置。

position: 顾名思义,是说Display中Surface显示的部分。换句话说,Video Window(TV屏幕)的这一部分用来显示Framebuffer(Surface)。

clip: Surface 中想要显示的部分。

 

当Display想要将surface显示于一个Video Window时,其实是将Surface中clip部分显示于Video window的Position部分。

 

我们会很快想到,如果position与clip大小不同怎么办?

当clip的宽度小于position的宽度时(高度相同),会将其水平拉伸。

当clip的高度小于position时(宽度相同),则无法显示。

 

当clip的宽度大于position的宽度时,则只显示一部分。

当clip的高度大于position的高度时,则只显示position部分。

你可能感兴趣的:(Broadcom,Nexus)