diff --git a/src/newgal/fbcon/fbvideo.c b/src/newgal/fbcon/fbvideo.c index 8f9d855b..3fb6d835 100644 --- a/src/newgal/fbcon/fbvideo.c +++ b/src/newgal/fbcon/fbvideo.c @@ -110,6 +110,88 @@ static void FB_WaitIdle(_THIS); #define FBIO_ENABLE_CACHE 0x4631 #endif +#ifdef FBCON_DEBUG +static void print_vinfo(struct fb_var_screeninfo *vinfo) +{ + fprintf(stderr, "Printing vinfo:\n"); + fprintf(stderr, "txres: %d\n", vinfo->xres); + fprintf(stderr, "tyres: %d\n", vinfo->yres); + fprintf(stderr, "txres_virtual: %d\n", vinfo->xres_virtual); + fprintf(stderr, "tyres_virtual: %d\n", vinfo->yres_virtual); + fprintf(stderr, "txoffset: %d\n", vinfo->xoffset); + fprintf(stderr, "tyoffset: %d\n", vinfo->yoffset); + fprintf(stderr, "tbits_per_pixel: %d\n", vinfo->bits_per_pixel); + fprintf(stderr, "tgrayscale: %d\n", vinfo->grayscale); + fprintf(stderr, "tnonstd: %d\n", vinfo->nonstd); + fprintf(stderr, "tactivate: %d\n", vinfo->activate); + fprintf(stderr, "theight: %d\n", vinfo->height); + fprintf(stderr, "twidth: %d\n", vinfo->width); + fprintf(stderr, "taccel_flags: %d\n", vinfo->accel_flags); + fprintf(stderr, "tpixclock: %d\n", vinfo->pixclock); + fprintf(stderr, "tleft_margin: %d\n", vinfo->left_margin); + fprintf(stderr, "tright_margin: %d\n", vinfo->right_margin); + fprintf(stderr, "tupper_margin: %d\n", vinfo->upper_margin); + fprintf(stderr, "tlower_margin: %d\n", vinfo->lower_margin); + fprintf(stderr, "thsync_len: %d\n", vinfo->hsync_len); + fprintf(stderr, "tvsync_len: %d\n", vinfo->vsync_len); + fprintf(stderr, "tsync: %d\n", vinfo->sync); + fprintf(stderr, "tvmode: %d\n", vinfo->vmode); + fprintf(stderr, "tred: %d/%d\n", vinfo->red.length, vinfo->red.offset); + fprintf(stderr, "tgreen: %d/%d\n", vinfo->green.length, vinfo->green.offset); + fprintf(stderr, "tblue: %d/%d\n", vinfo->blue.length, vinfo->blue.offset); + fprintf(stderr, "talpha: %d/%d\n", vinfo->transp.length, vinfo->transp.offset); +} + +static void print_finfo(struct fb_fix_screeninfo *finfo) +{ + fprintf(stderr, "Printing finfo:\n"); + fprintf(stderr, "tsmem_start = %p\n", (char *)finfo->smem_start); + fprintf(stderr, "tsmem_len = %d\n", finfo->smem_len); + fprintf(stderr, "ttype = %d\n", finfo->type); + fprintf(stderr, "ttype_aux = %d\n", finfo->type_aux); + fprintf(stderr, "tvisual = %d\n", finfo->visual); + fprintf(stderr, "txpanstep = %d\n", finfo->xpanstep); + fprintf(stderr, "typanstep = %d\n", finfo->ypanstep); + fprintf(stderr, "tywrapstep = %d\n", finfo->ywrapstep); + fprintf(stderr, "tline_length = %d\n", finfo->line_length); + fprintf(stderr, "tmmio_start = %p\n", (char *)finfo->mmio_start); + fprintf(stderr, "tmmio_len = %d\n", finfo->mmio_len); + fprintf(stderr, "taccel = %d\n", finfo->accel); +} +#endif /* FBCON_DEBUG */ + +static void FB_UpdateRectsPanning (_THIS, int numrects, GAL_Rect *rects) +{ + (void)this; + (void)numrects; + (void)rects; + return; +} + +static BOOL FB_SyncUpdatePanning (_THIS) +{ + currt_vinfo.yoffset = this->hidden->idx_buffer * currt_vinfo.yres; + if (ioctl(console_fd, FBIOPAN_DISPLAY, &currt_vinfo) < 0) { + _WRN_PRINTF("Failed ioctl(): FBIOPAN_DISPLAY\n"); + return FALSE; + } + + int old = this->hidden->idx_buffer; + this->hidden->idx_buffer = 1 - this->hidden->idx_buffer; + memcpy(this->hidden->buffers[this->hidden->idx_buffer], + this->hidden->buffers[old], this->hidden->len_buffer); + + int dummy = 0; + if (ioctl(console_fd, FBIO_WAITFORVSYNC, &dummy) < 0) { + _WRN_PRINTF("Failed ioctl(): FBIO_WAITFORVSYNC\n"); + return FALSE; + } + + this->hidden->real_screen->pixels = + this->hidden->buffers[this->hidden->idx_buffer]; + return TRUE; +} + static BOOL FB_SyncUpdate (_THIS) { if (IsRectEmpty (&this->hidden->dirty_rc)) @@ -375,6 +457,12 @@ static int FB_VideoInit(_THIS, GAL_PixelFormat *vformat) FB_VideoQuit(this); return(-1); } + +#ifdef FBCON_DEBUG + fprintf (stderr, "Printing original finfo:\n"); + print_finfo(&finfo); +#endif + switch (finfo.type) { case FB_TYPE_PACKED_PIXELS: /* Supported, no worries.. */ @@ -523,56 +611,6 @@ static GAL_Rect **FB_ListModes(_THIS, GAL_PixelFormat *format, Uint32 flags) return (GAL_Rect**) -1; } -#ifdef FBCON_DEBUG -static void print_vinfo(struct fb_var_screeninfo *vinfo) -{ - fprintf(stderr, "Printing vinfo:\n"); - fprintf(stderr, "txres: %d\n", vinfo->xres); - fprintf(stderr, "tyres: %d\n", vinfo->yres); - fprintf(stderr, "txres_virtual: %d\n", vinfo->xres_virtual); - fprintf(stderr, "tyres_virtual: %d\n", vinfo->yres_virtual); - fprintf(stderr, "txoffset: %d\n", vinfo->xoffset); - fprintf(stderr, "tyoffset: %d\n", vinfo->yoffset); - fprintf(stderr, "tbits_per_pixel: %d\n", vinfo->bits_per_pixel); - fprintf(stderr, "tgrayscale: %d\n", vinfo->grayscale); - fprintf(stderr, "tnonstd: %d\n", vinfo->nonstd); - fprintf(stderr, "tactivate: %d\n", vinfo->activate); - fprintf(stderr, "theight: %d\n", vinfo->height); - fprintf(stderr, "twidth: %d\n", vinfo->width); - fprintf(stderr, "taccel_flags: %d\n", vinfo->accel_flags); - fprintf(stderr, "tpixclock: %d\n", vinfo->pixclock); - fprintf(stderr, "tleft_margin: %d\n", vinfo->left_margin); - fprintf(stderr, "tright_margin: %d\n", vinfo->right_margin); - fprintf(stderr, "tupper_margin: %d\n", vinfo->upper_margin); - fprintf(stderr, "tlower_margin: %d\n", vinfo->lower_margin); - fprintf(stderr, "thsync_len: %d\n", vinfo->hsync_len); - fprintf(stderr, "tvsync_len: %d\n", vinfo->vsync_len); - fprintf(stderr, "tsync: %d\n", vinfo->sync); - fprintf(stderr, "tvmode: %d\n", vinfo->vmode); - fprintf(stderr, "tred: %d/%d\n", vinfo->red.length, vinfo->red.offset); - fprintf(stderr, "tgreen: %d/%d\n", vinfo->green.length, vinfo->green.offset); - fprintf(stderr, "tblue: %d/%d\n", vinfo->blue.length, vinfo->blue.offset); - fprintf(stderr, "talpha: %d/%d\n", vinfo->transp.length, vinfo->transp.offset); -} - -static void print_finfo(struct fb_fix_screeninfo *finfo) -{ - fprintf(stderr, "Printing finfo:\n"); - fprintf(stderr, "tsmem_start = %p\n", (char *)finfo->smem_start); - fprintf(stderr, "tsmem_len = %d\n", finfo->smem_len); - fprintf(stderr, "ttype = %d\n", finfo->type); - fprintf(stderr, "ttype_aux = %d\n", finfo->type_aux); - fprintf(stderr, "tvisual = %d\n", finfo->visual); - fprintf(stderr, "txpanstep = %d\n", finfo->xpanstep); - fprintf(stderr, "typanstep = %d\n", finfo->ypanstep); - fprintf(stderr, "tywrapstep = %d\n", finfo->ywrapstep); - fprintf(stderr, "tline_length = %d\n", finfo->line_length); - fprintf(stderr, "tmmio_start = %p\n", (char *)finfo->mmio_start); - fprintf(stderr, "tmmio_len = %d\n", finfo->mmio_len); - fprintf(stderr, "taccel = %d\n", finfo->accel); -} -#endif /* FBCON_DEBUG */ - static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags) { @@ -605,6 +643,11 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, FB_RestorePalette (this); } + if (ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0) { + GAL_SetError("NEWGAL>FBCON: Couldn't get console hardware info"); + return(NULL); + } + /* Set the video mode and get the final screen format */ if (ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) { GAL_SetError("NEWGAL>FBCON: Couldn't get console screen info\n"); @@ -612,9 +655,6 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, } #ifdef FBCON_DEBUG - fprintf (stderr, "Printing original finfo:\n"); - print_finfo(&finfo); - fprintf (stderr, "Printing original vinfo:\n"); print_vinfo(&vinfo); #endif @@ -663,7 +703,6 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, vinfo.yres_virtual = maxheight; } } - cache_vinfo = vinfo; #ifdef FBCON_DEBUG fprintf (stderr, "NEWGAL>FBCON: Printing actual vinfo:\n"); print_vinfo(&vinfo); @@ -724,6 +763,28 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, current->pitch = finfo.line_length; current->pixels = mapped_mem+mapped_offset; + /* Since 5.0.13, use FBIOPAN_DISPLAY if possible */ + this->hidden->nr_buffers = finfo.smem_len / (vinfo.yres * current->pitch); + if (this->hidden->nr_buffers > 1) { + this->hidden->nr_buffers = 2; + vinfo.yres_virtual = this->hidden->nr_buffers * vinfo.yres; + if (ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0) { + GAL_SetError("NEWGAL>FBCON: Couldn't enable virtual yres"); + this->hidden->nr_buffers = 0; + } + else { + this->hidden->len_buffer = finfo.line_length * vinfo.yres; + + this->hidden->buffers[0] = mapped_mem+mapped_offset; + this->hidden->buffers[1] = this->hidden->buffers[0] + + this->hidden->len_buffer; + + this->hidden->idx_buffer = 1; + current->pixels = this->hidden->buffers[this->hidden->idx_buffer]; + } + } + + currt_vinfo = vinfo; /* Set up the information for hardware surfaces */ surfaces_mem = (char *)current->pixels + vinfo.yres_virtual*current->pitch; @@ -764,12 +825,12 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, sigma8654_hdmi_init(); #endif + // this is a trick in order that GAL_CreateRGBSurface tries to + // allocate hardware surface first. + GAL_PublicSurface = current; + #ifdef _MGSCHEMA_COMPOSITING if (mgIsServer) { - // this is a trick in order that GAL_CreateRGBSurface tries to - // allocate hardware surface first. - GAL_PublicSurface = current; - dblbuff = TRUE; } else { @@ -795,7 +856,7 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, #endif /* create shadow screen */ - this->hidden->shadow_screen = GAL_CreateRGBSurface (GAL_HWSURFACE, + this->hidden->shadow_screen = GAL_CreateRGBSurface (GAL_SWSURFACE, current->w, current->h, current->format->BitsPerPixel, current->format->Rmask, current->format->Gmask, @@ -811,6 +872,7 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, this->UpdateRects = shadowScreen_UpdateRects; this->SyncUpdate = FB_SyncUpdate; + current->video = this; this->hidden->real_screen = current; current = this->hidden->shadow_screen; @@ -827,6 +889,10 @@ static GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current, else { this->hidden->real_screen = current; this->hidden->shadow_screen = NULL; + if (this->hidden->nr_buffers > 1) { + this->UpdateRects = FB_UpdateRectsPanning; + this->SyncUpdate = FB_SyncUpdatePanning; + } } /* We're done */ diff --git a/src/newgal/fbcon/fbvideo.h b/src/newgal/fbcon/fbvideo.h index ec2f2ea9..ceb21a7a 100644 --- a/src/newgal/fbcon/fbvideo.h +++ b/src/newgal/fbcon/fbvideo.h @@ -90,11 +90,17 @@ struct GAL_PrivateVideoData { /* end of header for shadow screen */ int console_fd; - struct fb_var_screeninfo cache_vinfo; + struct fb_var_screeninfo currt_vinfo; struct fb_var_screeninfo saved_vinfo; int saved_cmaplen; __u16 *saved_cmap; + /* Since 5.0.13, use FBIOPAN_DISPLAY if possible */ + int nr_buffers; + int idx_buffer; + unsigned len_buffer; + char *buffers[2]; + #ifdef _MGHAVE_PCIACCESS int pci_accel_driver; #endif @@ -115,13 +121,7 @@ struct GAL_PrivateVideoData { /* Old variable names */ #define console_fd (this->hidden->console_fd) -#define current_vt (this->hidden->current_vt) -#define saved_vt (this->hidden->saved_vt) -#define keyboard_fd (this->hidden->keyboard_fd) -#define saved_kbd_mode (this->hidden->saved_kbd_mode) -#define saved_kbd_termios (this->hidden->saved_kbd_termios) -#define mouse_fd (this->hidden->mouse_fd) -#define cache_vinfo (this->hidden->cache_vinfo) +#define currt_vinfo (this->hidden->currt_vinfo) #define saved_vinfo (this->hidden->saved_vinfo) #define saved_cmaplen (this->hidden->saved_cmaplen) #define saved_cmap (this->hidden->saved_cmap) diff --git a/src/newgal/shadow/shadow.c b/src/newgal/shadow/shadow.c index 9364436f..4f979850 100644 --- a/src/newgal/shadow/shadow.c +++ b/src/newgal/shadow/shadow.c @@ -160,11 +160,13 @@ static void refresh_ccw_32bpp(ShadowFBHeader* shadowfb_header, dst_height = RECTH(dst_update); BYTE line_pixels[dst_width * 4]; - /* Copy the bits from Shadow FrameBuffer to console FrameBuffer */ + /* Copy the bits from Shadow FrameBuffer to real FrameBuffer */ src_bits = (BYTE *)shadowfb_header + shadowfb_header->fb_offset; - src_bits += src_update.top * shadowfb_header->pitch + src_update.left * 4; + src_bits += src_update.top * shadowfb_header->pitch + + src_update.left * 4; + dst_line = (BYTE *)realfb_info->fb + (dst_update.bottom - 1) * + realfb_info->pitch; - dst_line = (BYTE *)realfb_info->fb + (dst_update.bottom - 1) * realfb_info->pitch; for (x = 0; x < dst_height; x++) { /* Copy the bits from vertical line to horizontal line */ const BYTE* ver_bits = src_bits; @@ -176,12 +178,53 @@ static void refresh_ccw_32bpp(ShadowFBHeader* shadowfb_header, hor_bits += 4; } - memcpy(dst_line + (dst_update.left << 2), line_pixels, dst_width << 2); + memcpy(dst_line + (dst_update.left << 2), line_pixels, + dst_width << 2); src_bits += 4; dst_line -= realfb_info->pitch; } } +static void refresh_cw_32bpp(ShadowFBHeader* shadowfb_header, + RealFBInfo* realfb_info, void* update) +{ + RECT src_update = *(RECT*)update; + RECT dst_update; + const BYTE *src_bits; + BYTE *dst_line; + int dst_width, dst_height; + int x, y; + + _get_dst_rect_cw(&dst_update, &src_update, realfb_info); + dst_width = RECTW(dst_update); + dst_height = RECTH(dst_update); + BYTE line_pixels[dst_width * 4]; + + /* Copy the bits from Shadow FrameBuffer to real FrameBuffer */ + src_bits = (BYTE *)shadowfb_header + shadowfb_header->fb_offset; + src_bits += (src_update.bottom - 1) * shadowfb_header->pitch + + src_update.left * 4; + dst_line = (BYTE *)realfb_info->fb + dst_update.top * + realfb_info->pitch; + + for (x = 0; x < dst_height; x++) { + /* Copy the bits from vertical line to horizontal line */ + const BYTE* ver_bits = src_bits; + BYTE* hor_bits = line_pixels; + + for (y = 0; y < dst_width; y++) { + *(Uint32 *)hor_bits = *(Uint32 *)ver_bits; + ver_bits -= shadowfb_header->pitch; + hor_bits += 4; + } + + memcpy(dst_line + (dst_update.left << 2), line_pixels, + dst_width << 2); + src_bits += 4; + dst_line += realfb_info->pitch; + } +} + #endif extern void refresh_normal_msb_left (ShadowFBHeader * shadowfb_header, RealFBInfo *realfb_info, void* update); @@ -382,13 +425,16 @@ static int RealEngine_GetInfo (RealFBInfo * realfb_info) realfb_info->real_device = real_device; real_device->VideoInit(realfb_info->real_device, &real_vformat); - real_device->screen = GAL_CreateRGBSurface (GAL_SWSURFACE, + GAL_Surface *prev_surf, *screen; + prev_surf = GAL_CreateRGBSurface (GAL_SWSURFACE, 0, 0, real_vformat.BitsPerPixel, real_vformat.Rmask, real_vformat.Gmask, real_vformat.Bmask, real_vformat.Amask); + real_device->screen = NULL; /* VW: SetVideoMode may return a new surface */ - real_device->screen = real_device->SetVideoMode(realfb_info->real_device, - real_device->screen, w, h, depth, GAL_HWPALETTE); + screen = real_device->SetVideoMode(realfb_info->real_device, + prev_surf, w, h, depth, GAL_HWPALETTE); + real_device->screen = (screen != NULL) ? screen : prev_surf; if (real_device->screen == NULL) { _ERR_PRINTF ("NEWGAL>SHADOW: can't create screen of real engine.\n"); return -1; @@ -539,11 +585,6 @@ static void schedule_updaters(_THIS, RECT *dirty_rc) } */ - /* wait for the finish of extra updaters */ - for (i = 0; i < this->hidden->nr_updaters; i++) { - sem_wait(&this->hidden->sync_sem); - } - /* partition the dirty rectangle horizontally */ int span = h / (this->hidden->nr_updaters); if (span == 0) { @@ -585,6 +626,11 @@ static void schedule_updaters(_THIS, RECT *dirty_rc) shadow_fb_ops.refresh(_shadowfbheader, this->hidden->realfb_info, this->hidden->dirty_rcs + this->hidden->nr_updaters); */ + + /* wait for the finish of extra updaters */ + for (i = 0; i < this->hidden->nr_updaters; i++) { + sem_wait(&this->hidden->sync_sem); + } } static BOOL SHADOW_SyncUpdateConcurrently (_THIS) @@ -844,7 +890,7 @@ static GAL_Surface *SHADOW_SetVideoMode(_THIS, GAL_Surface *current, ret = 0; bzero(&shadowfbheader, sizeof(shadowfbheader)); - realfb_info = malloc (sizeof(RealFBInfo)); + realfb_info = calloc (1, sizeof(RealFBInfo)); if (shadow_fb_ops.get_realfb_info (realfb_info)) { _ERR_PRINTF ("NEWGAL>SHADOW: " @@ -991,9 +1037,12 @@ static GAL_Surface *SHADOW_SetVideoMode(_THIS, GAL_Surface *current, } } #else - if (_shadowfbheader->depth == 32 && - this->hidden->realfb_info->flags & _ROT_DIR_CCW) - shadow_fb_ops.refresh = refresh_ccw_32bpp; + if (_shadowfbheader->depth == 32) { + if (this->hidden->realfb_info->flags & _ROT_DIR_CCW) + shadow_fb_ops.refresh = refresh_ccw_32bpp; + else if (this->hidden->realfb_info->flags & _ROT_DIR_CW) + shadow_fb_ops.refresh = refresh_cw_32bpp; + } #endif /* We're done */ diff --git a/src/newgal/shadow/shadow_refresh_msb_left.c b/src/newgal/shadow/shadow_refresh_msb_left.c index a80dbb4b..74d58730 100644 --- a/src/newgal/shadow/shadow_refresh_msb_left.c +++ b/src/newgal/shadow/shadow_refresh_msb_left.c @@ -230,7 +230,7 @@ void refresh_cw_msb_left (ShadowFBHeader *shadowfb_header, RealFBInfo *realfb_in BYTE* dst_line; int dst_width, dst_height; int x, y; - BYTE line_pixels[shadowfb_header->pitch]; + BYTE line_pixels[realfb_info->pitch]; _get_dst_rect_cw (&dst_update, &src_update, realfb_info); @@ -332,7 +332,7 @@ void refresh_ccw_msb_left (ShadowFBHeader* shadowfb_header, RealFBInfo* realfb_i BYTE* dst_line; int dst_width, dst_height; int x, y; - BYTE line_pixels[shadowfb_header->pitch]; + BYTE line_pixels[realfb_info->pitch]; _get_dst_rect_ccw (&dst_update, &src_update, realfb_info); @@ -433,7 +433,7 @@ void refresh_hflip_msb_left (ShadowFBHeader* shadowfb_header, RealFBInfo* realfb BYTE* dst_line; int src_width, src_height; int x, y; - BYTE line_pixels[shadowfb_header->pitch]; + BYTE line_pixels[realfb_info->pitch]; /* Round the update rectangle. */ round_rect(realfb_info->depth, &src_update); @@ -527,7 +527,7 @@ void refresh_vflip_msb_left (ShadowFBHeader* shadowfb_header, RealFBInfo* realfb BYTE* dst_line; int src_width, src_height; int x, y; - BYTE line_pixels[shadowfb_header->pitch]; + BYTE line_pixels[realfb_info->pitch]; /* Round the update rectangle. */ round_rect (realfb_info->depth, &src_update); diff --git a/src/newgal/shadow/shadow_refresh_msb_right.c b/src/newgal/shadow/shadow_refresh_msb_right.c index 9615719d..e813cde0 100644 --- a/src/newgal/shadow/shadow_refresh_msb_right.c +++ b/src/newgal/shadow/shadow_refresh_msb_right.c @@ -286,7 +286,7 @@ void refresh_cw_msb_right (ShadowFBHeader *shadowfb_header, BYTE* dst_line; int dst_width, dst_height; int x, y; - BYTE line_pixels[shadowfb_header->pitch]; + BYTE line_pixels[realfb_info->pitch]; _get_dst_rect_cw (&dst_update, &src_update, realfb_info); @@ -387,7 +387,7 @@ void refresh_ccw_msb_right(ShadowFBHeader* shadowfb_header, RECT dst_update; const BYTE* src_bits; BYTE* dst_line; - BYTE line_pixels[shadowfb_header->pitch]; + BYTE line_pixels[realfb_info->pitch]; int dst_width, dst_height; int x, y; @@ -500,7 +500,7 @@ void refresh_hflip_msb_right (ShadowFBHeader* shadowfb_header, RealFBInfo* realf BYTE* dst_line; int src_width, src_height; int x, y; - BYTE line_pixels[shadowfb_header->pitch]; + BYTE line_pixels[realfb_info->pitch]; /* Round the update rectangle. */ round_rect(realfb_info->depth, &src_update); @@ -603,7 +603,7 @@ void refresh_vflip_msb_right (ShadowFBHeader* shadowfb_header, RealFBInfo* realf BYTE* dst_line; int src_width, src_height; int x, y; - BYTE line_pixels[shadowfb_header->pitch]; + BYTE line_pixels[realfb_info->pitch]; /* Round the update rectangle. */ round_rect (realfb_info->depth, &src_update);