/*************************************************************************** * Copyright (c) 2012, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: * * Revision History: * * $brcm_Log: $ * ***************************************************************************/ #include "nexus_surface.h" #include "nexus_graphics2d.h" #include "nexus_display.h" #include "nexus_platform.h" #include "nexus_core_utils.h" #include "bstd.h" #include "bkni.h" #include "bsettop_display.h" #include "bsettop_graphics.h" #include "bsettop_display_n_priv.h" BDBG_MODULE(bgraphics); struct bgraphics { NEXUS_Graphics2DHandle gfx; NEXUS_SurfaceHandle offscreen; NEXUS_SurfaceHandle back; NEXUS_SurfaceHandle overlay; NEXUS_SurfaceHandle osd[2]; /* frame buffer */ NEXUS_SurfaceMemory mem[2]; NEXUS_SurfaceMemory off_mem; NEXUS_SurfaceMemory overlay_mem; BKNI_EventHandle event; NEXUS_DisplayHandle display[eBDISPLAY_ID_MAX]; NEXUS_VideoFormat osd_format; struct bsettop_surf surf_off; struct bsettop_surf surf_overlay; }; struct bgraphics s_graphics; NEXUS_DisplayHandle bdisplay_p_get_handle(bdisplay_t disp, int id); void bgraphics_checkpoint(void); static void bgraphics_complete(void *data, int unused) { BSTD_UNUSED(unused); BKNI_SetEvent((BKNI_EventHandle)data); } bgraphics_t bgraphics_open(int id, bdisplay_t p_disp) { NEXUS_SurfaceCreateSettings createSettings; NEXUS_SurfaceMemory mem; NEXUS_Graphics2DOpenSettings openSettings; NEXUS_Graphics2DSettings gfxSettings; NEXUS_GraphicsSettings graphicsSettings; NEXUS_VideoFormatInfo oinfo, vinfo; NEXUS_DisplaySettings dsettings; int i; BSTD_UNUSED(id); BKNI_Memset(&s_graphics, 0, sizeof(s_graphics)); s_graphics.osd_format = NEXUS_VideoFormat_eNtsc; NEXUS_VideoFormat_GetInfo(s_graphics.osd_format, &oinfo); for (i=0; iosd[eBDISPLAY_HDMI]; blitSettings.output.rect.width = 720; blitSettings.output.rect.height = 480; if (!overlay) { blitSettings.source.surface = graphics->offscreen; blitSettings.source.rect = blitSettings.output.rect; blitSettings.colorOp = NEXUS_BlitColorOp_eCopySource; blitSettings.alphaOp = NEXUS_BlitAlphaOp_eCopySource; } else { blitSettings.source.surface = graphics->overlay; blitSettings.source.rect = blitSettings.output.rect; blitSettings.dest.surface = graphics->offscreen; blitSettings.dest.rect = blitSettings.source.rect; blitSettings.alphaOp = NEXUS_BlitAlphaOp_eCombine; blitSettings.colorOp = NEXUS_BlitColorOp_eUseSourceAlpha; } NEXUS_FlushCache(graphics->off_mem.buffer, 2880*480); NEXUS_FlushCache(graphics->mem[0].buffer, 2880*480); NEXUS_Graphics2D_Blit(graphics->gfx, &blitSettings); } if (id & eGRAPHICS_SD) { NEXUS_Graphics2D_GetDefaultBlitSettings(&blitSettings); if (!overlay) { blitSettings.output.surface = graphics->osd[eBDISPLAY_COMPOSITE]; blitSettings.output.rect.width = 720; blitSettings.output.rect.height = 480; blitSettings.source.surface = graphics->offscreen; blitSettings.source.rect = blitSettings.output.rect; blitSettings.conversionMatrixEnabled = true; blitSettings.conversionMatrix = s_matrix_RGBtoYCbCr; blitSettings.colorOp = NEXUS_BlitColorOp_eCopySource; blitSettings.alphaOp = NEXUS_BlitAlphaOp_eCopySource; NEXUS_FlushCache(graphics->mem[1].buffer, 2880*480); NEXUS_Graphics2D_Blit(graphics->gfx, &blitSettings); } else { blitSettings.source.surface = graphics->overlay; blitSettings.dest.surface = graphics->offscreen; blitSettings.output.surface = graphics->back; blitSettings.source.rect.width = 720; blitSettings.source.rect.height = 480; blitSettings.dest.rect = blitSettings.source.rect; blitSettings.output.rect = blitSettings.source.rect; blitSettings.colorOp = NEXUS_BlitColorOp_eUseSourceAlpha; blitSettings.alphaOp = NEXUS_BlitAlphaOp_eCombine; NEXUS_FlushCache(graphics->mem[1].buffer, 2880*480); NEXUS_Graphics2D_Blit(graphics->gfx, &blitSettings); blitSettings.source.surface = graphics->back; blitSettings.dest.surface = NULL; blitSettings.output.surface = graphics->osd[eBDISPLAY_COMPOSITE]; blitSettings.colorOp = NEXUS_BlitColorOp_eCopySource; blitSettings.alphaOp = NEXUS_BlitAlphaOp_eCopySource; blitSettings.conversionMatrixEnabled = true; blitSettings.conversionMatrix = s_matrix_RGBtoYCbCr; NEXUS_Graphics2D_Blit(graphics->gfx, &blitSettings); } } bgraphics_checkpoint(); return 0; } bresult bgraphics_sync(bgraphics_t graphics, bool overlay) { return bgraphics_osd_flush(graphics, eGRAPHICS_BOTH, overlay); } bresult bgraphics_sync_partial(bgraphics_t graphics, bgraphics_id id, bool overlay) { if (!(id&eGRAPHICS_BOTH)) id = eGRAPHICS_BOTH; return bgraphics_osd_flush(graphics, id, overlay); } void bgraphics_checkpoint(void) { NEXUS_Error rc ; rc = NEXUS_Graphics2D_Checkpoint(s_graphics.gfx, NULL); if (rc == NEXUS_GRAPHICS2D_QUEUED) { BKNI_WaitForEvent(s_graphics.event, 0xFFFFFFFF); } } bresult bgraphics_p_format_change(NEXUS_DisplayHandle display, int id) { NEXUS_DisplaySettings dsettings; NEXUS_GraphicsSettings gsettings; NEXUS_VideoFormatInfo vinfo, oinfo; NEXUS_Display_GetSettings(display, &dsettings); NEXUS_VideoFormat_GetInfo(dsettings.format, &vinfo); NEXUS_VideoFormat_GetInfo(s_graphics.osd_format, &oinfo); NEXUS_Display_GetGraphicsSettings(display, &gsettings); gsettings.position.width = vinfo.digitalWidth; gsettings.position.height = vinfo.digitalHeight; gsettings.clip.width = oinfo.digitalWidth; gsettings.clip.height = oinfo.digitalHeight; NEXUS_Display_SetGraphicsSettings(display, &gsettings); NEXUS_Display_SetGraphicsFramebuffer(display, s_graphics.osd[id]); return b_ok; } void bgraphics_get(bgraphics_settings *settings) { BSTD_UNUSED(settings); } bresult bgraphics_get_osd_params(bgraphics_t graphics, bsettop_surf_t *p_osd_surf, void **osd_buffer, bsettop_surf_t *p_overlay_surf, void **overlay_mem) { if (p_osd_surf && osd_buffer) { *p_osd_surf = &graphics->surf_off; *osd_buffer = graphics->off_mem.buffer; } if (p_overlay_surf && overlay_mem) { *p_overlay_surf = &graphics->surf_overlay; *overlay_mem = graphics->overlay_mem.buffer; } return b_ok; } bresult bgraphics_set(const bgraphics_settings *settings) { BSTD_UNUSED(settings); return b_ok; } bresult bgraphics_get_framebuffer(bgraphics_t graphics, void **buffer, unsigned int **palette, int *width, int *height, int *pitch) { NEXUS_VideoFormatInfo oinfo; NEXUS_VideoFormat_GetInfo(graphics->osd_format, &oinfo); *buffer = graphics->off_mem.buffer; *pitch = graphics->off_mem.pitch; *width = oinfo.digitalWidth; *height = oinfo.digitalHeight; *palette = NULL; return b_ok; } bresult bgraphics_load_palette(bgraphics_t graphics) { BSTD_UNUSED(graphics); return b_ok; } bresult bgraphics_get_overlay(bgraphics_t graphics, void **buffer) { NEXUS_SurfaceMemory mem; NEXUS_Surface_GetMemory(graphics->overlay, &mem); *buffer = mem.buffer; return b_ok; } bresult bsurface_fill(bsettop_surf_t surface, bsettop_rect *rect, bgraphics_pixel pixel) { NEXUS_Graphics2DFillSettings fillSettings; NEXUS_Graphics2D_GetDefaultFillSettings(&fillSettings); fillSettings.surface = surface->hSurface; fillSettings.rect.x = rect->x; fillSettings.rect.y = rect->y; fillSettings.rect.width = rect->width; fillSettings.rect.height = rect->height; fillSettings.color = pixel; fillSettings.colorOp = NEXUS_FillOp_eCopy; fillSettings.alphaOp = NEXUS_FillOp_eCopy; NEXUS_Surface_Flush(surface->hSurface); NEXUS_Graphics2D_Fill(s_graphics.gfx, &fillSettings); bgraphics_checkpoint(); return b_ok; } bresult bsurface_create_surface(uint32_t width, uint32_t height, bgraphics_pixel_format format, uint8_t **mem, uint32_t *pitch, bsettop_surf_t *surface) { NEXUS_SurfaceCreateSettings createSettings; NEXUS_SurfaceHandle handle; NEXUS_SurfaceMemory smem; *surface = BKNI_Malloc(sizeof(struct bsettop_surf)); NEXUS_Surface_GetDefaultCreateSettings(&createSettings); createSettings.pixelFormat = (format==bgraphics_pixel_format_a8_r8_g8_b8)?NEXUS_PixelFormat_eA8_R8_G8_B8:NEXUS_PixelFormat_eA8_Y8_Cb8_Cr8; createSettings.width = width; createSettings.height = height; createSettings.heap = NEXUS_Platform_GetFramebufferHeap(0); handle = NEXUS_Surface_Create(&createSettings); if (!handle ) { BDBG_WRN(("fail to create surface (%dx%d)",width, height)); return -1; } NEXUS_Surface_GetMemory(handle, &smem); (*surface)->format = createSettings.pixelFormat; (*surface)->width = width; (*surface)->height = height; (*surface)->hSurface = handle; BKNI_Memset(smem.buffer, 0, height*smem.pitch); *pitch = smem.pitch; *mem = smem.buffer; return b_ok; } bresult bsurface_blit_surface( bsettop_surf_t src_surf, bsettop_rect *src_r, bsettop_surf_t dst_surf, bsettop_rect *dst_r, bsettop_surf_t out_surf, bsettop_rect *out_r) { NEXUS_Graphics2DBlitSettings blitSettings; NEXUS_Graphics2D_GetDefaultBlitSettings(&blitSettings); blitSettings.source.surface = src_surf->hSurface; blitSettings.source.rect.x = src_r->x; blitSettings.source.rect.y = src_r->y; blitSettings.source.rect.width = src_r->width; blitSettings.source.rect.height = src_r->height; blitSettings.output.surface = out_surf->hSurface; blitSettings.output.rect.x = out_r->x; blitSettings.output.rect.y = out_r->y; blitSettings.output.rect.width = out_r->width; blitSettings.output.rect.height = out_r->height; if (dst_surf && dst_r) { blitSettings.dest.surface = dst_surf->hSurface; blitSettings.dest.rect.x = dst_r->x; blitSettings.dest.rect.y = dst_r->y; blitSettings.dest.rect.width = dst_r->width; blitSettings.dest.rect.height = dst_r->height; } blitSettings.colorOp = NEXUS_BlitColorOp_eCopySource; blitSettings.alphaOp = NEXUS_BlitAlphaOp_eCopySource; NEXUS_Surface_Flush(src_surf->hSurface); NEXUS_Surface_Flush(out_surf->hSurface); if (dst_surf && (dst_surf->hSurface != out_surf->hSurface)) { NEXUS_Surface_Flush(dst_surf->hSurface); } NEXUS_Graphics2D_Blit(s_graphics.gfx, &blitSettings); bgraphics_checkpoint(); return b_ok; }