From e51dc25c01280a7fabf0b7afdb43d54edac9460d Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Wed, 11 Mar 2020 17:10:57 +0800 Subject: [PATCH] use double buffering for compositing schema --- src/newgal/fbcon/fbvideo.c | 77 +++++++++++++++++++++++++++++++++++--- src/newgal/fbcon/fbvideo.h | 49 +++++++++++++----------- 2 files changed, 98 insertions(+), 28 deletions(-) diff --git a/src/newgal/fbcon/fbvideo.c b/src/newgal/fbcon/fbvideo.c index dc50f34a..7376fdb7 100644 --- a/src/newgal/fbcon/fbvideo.c +++ b/src/newgal/fbcon/fbvideo.c @@ -15,7 +15,7 @@ * and Graphics User Interface (GUI) support system for embedded systems * and smart IoT devices. * - * Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd. + * Copyright (C) 2002~2020, Beijing FMSoft Technologies Co., Ltd. * Copyright (C) 1998~2002, WEI Yongming * * This program is free software: you can redistribute it and/or modify @@ -86,19 +86,40 @@ extern int sigma8654_hdmi_quit(); static int FB_GetFBInfo(VIDEO_MEM_INFO *video_mem_info); static int FB_VideoInit(_THIS, GAL_PixelFormat *vformat); static GAL_Rect **FB_ListModes(_THIS, GAL_PixelFormat *format, Uint32 flags); -static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags); +static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, + int width, int height, int bpp, Uint32 flags); static int FB_SetColors(_THIS, int firstcolor, int ncolors, GAL_Color *colors); static void FB_VideoQuit(_THIS); /* Hardware surface functions */ static int FB_InitHWSurfaces(_THIS, GAL_Surface *screen, char *base, int size); static void FB_FreeHWSurfaces(_THIS); -static void FB_RequestHWSurface (_THIS, const REQ_HWSURFACE* request, REP_HWSURFACE* reply); +static void FB_RequestHWSurface (_THIS, const REQ_HWSURFACE* request, + REP_HWSURFACE* reply); static int FB_AllocHWSurface(_THIS, GAL_Surface *surface); static void FB_FreeHWSurface(_THIS, GAL_Surface *surface); static void FB_WaitVBL(_THIS); static void FB_WaitIdle(_THIS); +#ifdef _MGSCHEMA_COMPOSITING + +#include "../shadow-screen.h" +#include "debug.h" + +static BOOL FB_SyncUpdate (_THIS) +{ + if (IsRectEmpty (&this->hidden->dirty_rc)) + return FALSE; + + if (shadowScreen_BlitToReal (this) == 0) + return TRUE; + else + _WRN_PRINTF ("failed to call shadowScreen_BlitToReal\n"); + + return FALSE; +} +#endif /* _MGSCHEMA_COMPOSITING */ + #if 0 static int FB_LockHWSurface(_THIS, GAL_Surface *surface); static void FB_UnlockHWSurface(_THIS, GAL_Surface *surface); @@ -155,6 +176,11 @@ static GAL_VideoDevice *FB_CreateDevice(int devindex) return(0); } memset(this->hidden, 0, (sizeof *this->hidden)); + /* For compositing schema, we force to use double buffering */ +#ifdef _MGSCHEMA_COMPOSITING + this->hidden->magic = MAGIC_SHADOW_SCREEN_HEADER; + this->hidden->version = 0; +#endif wait_vbl = FB_WaitVBL; wait_idle = FB_WaitIdle; @@ -561,7 +587,6 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, return(NULL); } #endif - /* Restore the original palette */ FB_RestorePalette (this); } @@ -724,8 +749,43 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, sigma8654_hdmi_init(); #endif +#ifdef _MGSCHEMA_COMPOSITING + if (mgIsServer) { + /* create shadow screen */ + this->hidden->shadow_screen = GAL_CreateRGBSurface (GAL_HWSURFACE, + current->w, current->h, + current->format->BitsPerPixel, + current->format->Rmask, current->format->Gmask, + current->format->Bmask, current->format->Amask); + + if (this->hidden->shadow_screen) { + this->info.hw_cursor = 1; + this->hidden->cursor = NULL; + this->SetCursor = shadowScreen_SetCursor; + this->MoveCursor = shadowScreen_MoveCursor; + this->UpdateRects = shadowScreen_UpdateRects; + this->SyncUpdate = FB_SyncUpdate; + + this->hidden->real_screen = current; + current = this->hidden->shadow_screen; + + GAL_SetClipRect (this->hidden->real_screen, NULL); + GAL_SetColorKey (this->hidden->shadow_screen, 0, 0); + GAL_SetAlpha (this->hidden->shadow_screen, 0, 0); + } + else { + this->hidden->real_screen = NULL; + this->hidden->shadow_screen = NULL; + } + } + else { + // client never call SetVideoMode + assert (0); + } +#endif /* _MGSCHEMA_COMPOSITING */ + /* We're done */ - return(current); + return (current); } #ifdef FBACCEL_DEBUG @@ -1181,6 +1241,12 @@ static void FB_VideoQuit(_THIS) } } +#ifdef _MGSCHEMA_COMPOSITING + if (mgIsServer && this->hidden->shadow_screen) { + GAL_FreeSurface (this->hidden->shadow_screen); + } +#endif + /* Clean up the memory bucket list */ #ifdef _MGRM_PROCESSES if (mgIsServer) @@ -1231,6 +1297,5 @@ static void FB_VideoQuit(_THIS) #endif sigma8654_hdmi_quit(); #endif - } diff --git a/src/newgal/fbcon/fbvideo.h b/src/newgal/fbcon/fbvideo.h index ab1e6c26..ed572e56 100644 --- a/src/newgal/fbcon/fbvideo.h +++ b/src/newgal/fbcon/fbvideo.h @@ -68,22 +68,26 @@ typedef struct vidmem_bucket { /* Private display data */ struct GAL_PrivateVideoData { + /* For compositing schema, we force to use double buffering */ +#ifdef _MGSCHEMA_COMPOSITING + /* start of header for shadow screen */ + int magic, version; + GAL_Surface *real_screen, *shadow_screen; + RECT dirty_rc; + + /* Used to simulate the hardware cursor. */ + GAL_Surface *cursor; + int csr_x, csr_y; + int hot_x, hot_y; + /* end of header for shadow screen */ +#endif /* _MGSCHEMA_COMPOSITING */ + int console_fd; struct fb_var_screeninfo cache_vinfo; struct fb_var_screeninfo saved_vinfo; int saved_cmaplen; __u16 *saved_cmap; -#if 0 - int current_vt; - int saved_vt; - int keyboard_fd; - int saved_kbd_mode; - struct termios saved_kbd_termios; - - int mouse_fd; -#endif - #ifdef _MGHAVE_PCIACCESS int pci_accel_driver; #endif @@ -93,8 +97,6 @@ struct GAL_PrivateVideoData { int mapped_offset; char *mapped_io; long mapped_iolen; - int flip_page; - char *flip_address[2]; vidmem_bucket surfaces; int surfaces_memtotal; @@ -102,6 +104,13 @@ struct GAL_PrivateVideoData { void (*wait_vbl)(_THIS); void (*wait_idle)(_THIS); + +#if 0 /* deprecated code */ + int flip_page; + char *flip_address[2]; +#define flip_page (this->hidden->flip_page) +#define flip_address (this->hidden->flip_address) +#endif }; /* Old variable names */ @@ -121,8 +130,6 @@ struct GAL_PrivateVideoData { #define mapped_offset (this->hidden->mapped_offset) #define mapped_io (this->hidden->mapped_io) #define mapped_iolen (this->hidden->mapped_iolen) -#define flip_page (this->hidden->flip_page) -#define flip_address (this->hidden->flip_address) #define surfaces (this->hidden->surfaces) #define surfaces_memtotal (this->hidden->surfaces_memtotal) #define surfaces_memleft (this->hidden->surfaces_memleft) @@ -132,13 +139,11 @@ struct GAL_PrivateVideoData { #ifdef _MGHAVE_PCIACCESS #define pci_accel_driver (this->hidden->pci_accel_driver) - /* Defined in pcivideo.c */ -extern int FB_ProbePCIAccelDriver (_THIS, const struct fb_fix_screeninfo* fb_finfo); +extern int FB_ProbePCIAccelDriver (_THIS, const struct fb_fix_screeninfo* finfo); extern int FB_InitPCIAccelDriver (_THIS, const GAL_Surface* current); extern int FB_CleanupPCIAccelDriver (_THIS); -#endif - +#endif /* _MGHAVE_PCIACCESS */ /* Accelerator types that are supported by the driver, but are not necessarily in the kernel headers on the system we compile on. @@ -156,17 +161,17 @@ extern void FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area); /* These are utility functions for working with video surfaces */ -static __inline__ void FB_AddBusySurface(GAL_Surface *surface) +static inline void FB_AddBusySurface(GAL_Surface *surface) { ((vidmem_bucket *)surface->hwdata)->dirty = 1; } -static __inline__ int FB_IsSurfaceBusy(GAL_Surface *surface) +static inline int FB_IsSurfaceBusy(GAL_Surface *surface) { return ((vidmem_bucket *)surface->hwdata)->dirty; } -static __inline__ void FB_WaitBusySurfaces(_THIS) +static inline void FB_WaitBusySurfaces(_THIS) { vidmem_bucket *bucket; @@ -179,7 +184,7 @@ static __inline__ void FB_WaitBusySurfaces(_THIS) } } -static __inline__ void FB_dst_to_xy(_THIS, GAL_Surface *dst, int *x, int *y) +static inline void FB_dst_to_xy(_THIS, GAL_Surface *dst, int *x, int *y) { *x = (long)((char *)dst->pixels - mapped_mem)%this->screen->pitch; *y = (long)((char *)dst->pixels - mapped_mem)/this->screen->pitch;