📄 compo_rect.c
字号:
*******************************************************************************/static void CreateBaseScreenRect(stcompo_Overlay_t* Overlay_p, STGXOBJ_Rectangle_t* Rect_p, U32 Complexity){ stcompo_Device_t* Device_p = (stcompo_Device_t*)Overlay_p->CompoHandle; stcompo_ScreenRect_t* NextRect_p; stcompo_ScreenRect_t* PrevRect_p; /* Screen Rect list reallocation if no more element available */ if (Device_p->NextScreenRect_p == Device_p->LastScreenRect_p) { stcompo_ScreenRect_t* Next_p; U32 Last; /* Convert pointers to offsets for realloc */ Last = Device_p->LastScreenRect_p - Device_p->FirstScreenRect_p; Device_p->FirstScreenRect_p = (stcompo_ScreenRect_t *) realloc(Device_p->FirstScreenRect_p, (Last + DEFAULT_SCREENRECTS) * sizeof(stcompo_ScreenRect_t)); /* Convert offsets back into pointers */ Device_p->LastScreenRect_p = Device_p->FirstScreenRect_p + Last + DEFAULT_SCREENRECTS; Device_p->NextScreenRect_p = Device_p->FirstScreenRect_p + Last; /* Initialized Overlay_pp because all screen rect address have changed */ for (Next_p = Device_p->FirstScreenRect_p; Next_p != Device_p->LastScreenRect_p; Next_p++) { Next_p->Overlay_pp = Next_p->Overlays; } } /* At this point, NextScreenRect element is available */ /* Allocate larger overlay pointer array if complexity bigger than default one */ if (Complexity > DEFAULT_COMPLEXITY) { Device_p->NextScreenRect_p->Overlay_pp = (stcompo_Overlay_t **) memory_allocate(Device_p->CPUPartition_p, Complexity * sizeof(stcompo_Overlay_t *)); } Device_p->NextScreenRect_p->Overlay_pp[Complexity - 1] = Overlay_p; Device_p->NextScreenRect_p->Rect = *Rect_p; Device_p->NextScreenRect_p->Complexity = Complexity; Device_p->NextScreenRect_p->SrcSliceNbr = 0; Device_p->NextScreenRect_p->ContainVideo = FALSE; Device_p->NextScreenRect_p->Decomposed = FALSE; if (Overlay_p == &(Device_p->BackgroundOverlay)) { /* Tile related */ Device_p->NextScreenRect_p->TileWidth = Rect_p->Width; Device_p->NextScreenRect_p->TileHeight = Rect_p->Height; } else { U32 TileWidth, TileHeight; /* Tile related */ HALCOMPO_GetOverlayTileSize(Overlay_p->HalOverlay,&TileWidth, &TileHeight); Device_p->NextScreenRect_p->TileWidth = TileWidth; Device_p->NextScreenRect_p->TileHeight = TileHeight; } /* Overwrite support */ /* Link the new screen Rect with previous and next Rects */ NextRect_p = Device_p->NextScreenRect_p; PrevRect_p = Device_p->NextScreenRect_p; if (PrevRect_p != Device_p->FirstScreenRect_p) { PrevRect_p--; Device_p->NextScreenRect_p->PrevRect_p = PrevRect_p; } Device_p->NextScreenRect_p++; NextRect_p->NextRect_p = Device_p->NextScreenRect_p;}/*******************************************************************************Name : CreateScreenRectListDescription : This function performs the screen analysis work. It intersects the rectangle it is provided with the current overlay rectangle producing up to 4 rectangular regions that this overlay doesn't contribute to and a single screen rectangle that it does contribute to.Parameters :Assumptions : recursive function.Limitations :Returns :*******************************************************************************/static void CreateScreenRectList(stcompo_Overlay_t *Overlay_p, STGXOBJ_Rectangle_t *Clip_p, U32 Complexity){ STGXOBJ_Rectangle_t *DstRect_p, Temp; S32 Left, Top, Right, Bottom; stcompo_Device_t* Device_p = (stcompo_Device_t*)Overlay_p->CompoHandle; halcompo_Overlay_t* HalOverlay_p = (halcompo_Overlay_t*) Overlay_p->HalOverlay; if (Overlay_p == &(Device_p->BackgroundOverlay)) { CreateBaseScreenRect(Overlay_p, Clip_p, Complexity + 1); return; } DstRect_p = &Overlay_p->ReadParams.DstRect; /* The following variables will form out intersection rectangle on the way through this function */ Left = Clip_p->PositionX; Right = Clip_p->PositionX + Clip_p->Width; Top = Clip_p->PositionY; Bottom = Clip_p->PositionY + Clip_p->Height; /* First check to see if our overlay is included in the clip rectangle and overlay is enabled */ if ( ( DstRect_p->PositionX >= Right ) || ( DstRect_p->PositionY >= Bottom ) || ( Left >= (S32) (DstRect_p->PositionX + DstRect_p->Width) ) || ( Top >= (S32) (DstRect_p->PositionY + DstRect_p->Height) ) || ( Overlay_p->ReadParams.Flags & STCOMPO_OVERLAY_MODE_DISABLE ) || ( ( Overlay_p->ReadParams.Flags & STCOMPO_OVERLAY_MODE_CONSTANT_ALPHA ) && ( ( HalOverlay_p->ReadParams.Bitmap1_p->ColorType != STGXOBJ_COLOR_TYPE_ARGB1555 ) && (Overlay_p->ReadParams.ConstantAlpha == 0) ))) { /* Just pass down to the next overlay */ CreateScreenRectList((stcompo_Overlay_t*)Overlay_p->ReadParams.Behind, Clip_p, Complexity); return; } /* We know we have an intersection of some kind now. Calculate our intersection and pass down rectangles inside clip but outside our overlay */ if (Left < DstRect_p->PositionX) { /* Pass down any rectangle to the left of our overlay and reduce our intersection rectangle */ Temp.PositionY = Top; Temp.Height = Bottom - Top; Temp.PositionX = Left; Temp.Width = DstRect_p->PositionX - Left; Left = DstRect_p->PositionX; CreateScreenRectList((stcompo_Overlay_t*)Overlay_p->ReadParams.Behind, &Temp, Complexity); } if ((DstRect_p->PositionX + DstRect_p->Width) < Right) { /* Pass down any rectangle to the right of our overlay and reduce our intersection rectangle */ Temp.PositionY = Top; Temp.Height = Bottom - Top; Temp.PositionX = DstRect_p->PositionX + DstRect_p->Width; Temp.Width = Right - Temp.PositionX; Right = Temp.PositionX; CreateScreenRectList((stcompo_Overlay_t*)Overlay_p->ReadParams.Behind, &Temp, Complexity); } if (Top < DstRect_p->PositionY) { /* Pass down any rectangle above our overlay and reduce our intersection rectangle */ Temp.PositionY = Top; Temp.Height = DstRect_p->PositionY - Top; Temp.PositionX = Left; Temp.Width = Right - Left; Top = DstRect_p->PositionY; CreateScreenRectList((stcompo_Overlay_t*)Overlay_p->ReadParams.Behind, &Temp, Complexity); } if ((DstRect_p->PositionY + DstRect_p->Height) < Bottom) { /* Pass down any rectangle below our overlay and reduce our intersection rectangle */ Temp.PositionY = DstRect_p->PositionY + DstRect_p->Height; Temp.Height = Bottom - Temp.PositionY; Temp.PositionX = Left; Temp.Width = Right - Left; Bottom = Temp.PositionY; CreateScreenRectList((stcompo_Overlay_t*)Overlay_p->ReadParams.Behind, &Temp, Complexity); } Temp.PositionX = Left; Temp.Width = Right - Left; Temp.PositionY = Top; Temp.Height = Bottom - Top; if (Overlay_p->ReadParams.Flags & (STCOMPO_OVERLAY_MODE_CONSTANT_ALPHA | STCOMPO_OVERLAY_MODE_PERPIXEL_ALPHA)) { U32 TileWidth, TileHeight; /* This overaly may be transparent - so we have to compose it on top of the planes underneath. Record our current rectangle pointer and call the layers below to create the ScreenRect structures. Then we just add our overlay to each new screenrect. */ U32 SubRect = Device_p->NextScreenRect_p - Device_p->FirstScreenRect_p; CreateScreenRectList((stcompo_Overlay_t*)Overlay_p->ReadParams.Behind, &Temp, Complexity+1); while (&(Device_p->FirstScreenRect_p[SubRect]) != Device_p->NextScreenRect_p) { HALCOMPO_GetOverlayTileSize(Overlay_p->HalOverlay,&TileWidth, &TileHeight); /* Track minimum preferred width */ if (Device_p->FirstScreenRect_p[SubRect].TileWidth > TileWidth) { Device_p->FirstScreenRect_p[SubRect].TileWidth = TileWidth; } if (Device_p->FirstScreenRect_p[SubRect].TileHeight > TileHeight) { Device_p->FirstScreenRect_p[SubRect].TileHeight = TileHeight; } Device_p->FirstScreenRect_p[SubRect].Overlay_pp[Complexity] = Overlay_p; SubRect++; } return; } else { /* If we are a base overlay (ie nothing can be seen beneath us), then we are at base complexity - just create a rectangle structure suitable to describe the complexity and then fill in our record and pass it back up. */ CreateBaseScreenRect(Overlay_p, &Temp, Complexity + 1); return; }}/*******************************************************************************Name : BlendOverlaysDescription : Setup the operations to generate the tile on the screenParameters :Assumptions : Complexity > 1 if Complexity = 2 then no backgound color overlay involved!Limitations :Returns :*******************************************************************************/static void BlendOverlays(stcompo_Device_t* Device_p, stcompo_ScreenRect_t *ScreenRect_p, STGXOBJ_Bitmap_t *FinalBitmap_p, STGXOBJ_Rectangle_t *FinalRect_p, STGXOBJ_Bitmap_t *CacheBitmap_p, BOOL IsTopField, BOOL UseNonRecurrentCompositionList){ STCOMPO_QueueUsed_t QueueUsed; stcompo_Overlay_t *Overlay_Video_p, *Overlay_Osd_p; BOOL UseOnePassBlend = FALSE; if ((Device_p->HalComposeScreen) == HALCOMPO_ComposeScreenCQ) { QueueUsed = STCOMPO_MAIN; } else { QueueUsed = STCOMPO_AUX; } /* Check which blend method will be used for this composition mode */ if (Device_p->CompositionType == STCOMPO_COMPOSITION_FIELD_SDRAM) { UseOnePassBlend = TRUE; } else if ((Device_p->CompositionType == STCOMPO_COMPOSITION_FRAME) || (Device_p->CompositionType == STCOMPO_COMPOSITION_FIELD) || (Device_p->CompositionType == STCOMPO_COMPOSITION_FIELD_COMBINED)) { UseOnePassBlend = FALSE; } else /* STCOMPO_COMPOSITION_FIELD_COMBINED_SDRAM */ { BOOL UseAFapproximationByVF; Overlay_Video_p = ScreenRect_p->Overlay_pp[1]; Overlay_Osd_p = ScreenRect_p->Overlay_pp[0]; /* Test whether Flicker Filter is enabled for this viewport */ UseAFapproximationByVF = HALCOMPO_IsFlickerFilterEnabled(Overlay_Osd_p->HalOverlay); if (UseAFapproximationByVF == TRUE) { UseOnePassBlend = FALSE; } else { UseOnePassBlend = TRUE; } } /* Apply the selected blend method*/ if (UseOnePassBlend == TRUE) { /* One pass blend : video on S2 and OSD on S1 */ HALCOMPO_OnePassBlend(Overlay_Video_p->HalOverlay,Overlay_Osd_p->HalOverlay, FinalRect_p,FinalBitmap_p, QueueUsed, IsTopField, ScreenRect_p->SrcSliceNbr, Device_p->ReadParams.ScreenHeight, UseNonRecurrentCompositionList); } else { stcompo_Overlay_t* Overlay_p; U32 Passes = ScreenRect_p->Complexity - 1; Overlay_p = ScreenRect_p->Overlay_pp[Passes]; if (Overlay_p == &(Device_p->BackgroundOverlay)) { /* Base layer is the background */ Passes--; Overlay_p = ScreenRect_p->Overlay_pp[Passes]; HALCOMPO_FillBlendRectangle(Overlay_p->HalOverlay,CacheBitmap_p, FinalRect_p, TRUE, QueueUsed, IsTopField, ScreenRect_p->SrcSliceNbr, Device_p->ReadParams.ScreenHeight, UseNonRecurrentCompositionList); } else { /* Just copy the image into the cache and use the cache as the background. Copy will handle scaling, filtering etc */ HALCOMPO_CopyRectangle(Overlay_p->HalOverlay,CacheBitmap_p, FinalRect_p,TRUE, QueueUsed, IsTopField, ScreenRect_p->SrcSliceNbr, Device_p->ReadParams.ScreenHeight, UseNonRecurrentCompositionList); } while (Passes--) { Overlay_p = ScreenRect_p->Overlay_pp[Passes]; if (Passes != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -