405
391
static grub_err_t
406
doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front
407
__attribute__ ((unused)),
408
struct grub_video_fbrender_target *back
409
__attribute__ ((unused)))
411
int new_displayed_page;
412
struct grub_video_fbrender_target *target;
415
/* Swap the page numbers in the framebuffer struct. */
416
new_displayed_page = framebuffer.render_page;
417
framebuffer.render_page = framebuffer.displayed_page;
418
framebuffer.displayed_page = new_displayed_page;
420
err = doublebuf_pageflipping_commit ();
423
/* Restore previous state. */
424
framebuffer.render_page = framebuffer.displayed_page;
425
framebuffer.displayed_page = new_displayed_page;
429
if (framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)
430
grub_memcpy (framebuffer.ptr + framebuffer.render_page
431
* framebuffer.page_size, framebuffer.ptr
432
+ framebuffer.displayed_page * framebuffer.page_size,
433
framebuffer.page_size);
435
target = framebuffer.back_target;
436
framebuffer.back_target = framebuffer.front_target;
437
framebuffer.front_target = target;
439
err = grub_video_fb_get_active_render_target (&target);
443
if (target == framebuffer.back_target)
444
err = grub_video_fb_set_active_render_target (framebuffer.front_target);
445
else if (target == framebuffer.front_target)
446
err = grub_video_fb_set_active_render_target (framebuffer.back_target);
452
doublebuf_pageflipping_init (void)
454
/* Get video RAM size in bytes. */
455
grub_size_t vram_size = controller_info.total_memory << 16;
458
framebuffer.page_size =
459
framebuffer.mode_info.pitch * framebuffer.mode_info.height;
461
if (2 * framebuffer.page_size > vram_size)
462
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
463
"Not enough video memory for double buffering.");
465
framebuffer.displayed_page = 0;
466
framebuffer.render_page = 1;
468
framebuffer.update_screen = doublebuf_pageflipping_update_screen;
470
err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr);
474
err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target, &framebuffer.mode_info, framebuffer.ptr + framebuffer.page_size);
477
grub_video_fb_delete_render_target (framebuffer.front_target);
481
/* Set the framebuffer memory data pointer and display the right page. */
482
err = doublebuf_pageflipping_commit ();
485
grub_video_fb_delete_render_target (framebuffer.front_target);
486
grub_video_fb_delete_render_target (framebuffer.back_target);
490
return GRUB_ERR_NONE;
493
/* Select the best double buffering mode available. */
495
double_buffering_init (unsigned int mode_type, unsigned int mode_mask)
498
int updating_swap_needed;
501
= grub_video_check_mode_flag (mode_type, mode_mask,
502
GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP, 0);
504
/* Do double buffering only if it's either requested or efficient. */
505
if (grub_video_check_mode_flag (mode_type, mode_mask,
506
GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
507
!updating_swap_needed))
509
framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
510
if (updating_swap_needed)
511
framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP;
512
err = doublebuf_pageflipping_init ();
514
return GRUB_ERR_NONE;
516
framebuffer.mode_info.mode_type
517
&= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
518
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
520
grub_errno = GRUB_ERR_NONE;
523
if (grub_video_check_mode_flag (mode_type, mode_mask,
524
GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
527
framebuffer.mode_info.mode_type
528
|= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
529
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
531
err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target,
532
&framebuffer.back_target,
533
&framebuffer.update_screen,
534
framebuffer.mode_info,
538
return GRUB_ERR_NONE;
540
framebuffer.mode_info.mode_type
541
&= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
542
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
544
grub_errno = GRUB_ERR_NONE;
547
/* Fall back to no double buffering. */
548
err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr);
553
framebuffer.back_target = framebuffer.front_target;
554
framebuffer.update_screen = 0;
556
framebuffer.mode_info.mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
558
return GRUB_ERR_NONE;
564
392
grub_video_vbe_setup (unsigned int width, unsigned int height,
565
393
unsigned int mode_type, unsigned int mode_mask)
685
513
framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
687
/* Set up double buffering and targets. */
688
err = double_buffering_init (mode_type, mode_mask);
692
err = grub_video_fb_set_active_render_target (framebuffer.back_target);
516
/* Get video RAM size in bytes. */
517
grub_size_t vram_size = controller_info.total_memory << 16;
518
grub_size_t page_size; /* The size of a page in bytes. */
520
page_size = framebuffer.mode_info.pitch * framebuffer.mode_info.height;
522
if (vram_size >= 2 * page_size)
523
err = grub_video_fb_setup (mode_type, mode_mask,
524
&framebuffer.mode_info,
526
doublebuf_pageflipping_set_page,
527
framebuffer.ptr + page_size);
529
err = grub_video_fb_setup (mode_type, mode_mask,
530
&framebuffer.mode_info,
531
framebuffer.ptr, 0, 0);
697
534
/* Copy default palette to initialize emulated palette. */
698
535
err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
726
563
static grub_err_t
727
grub_video_vbe_swap_buffers (void)
730
if (!framebuffer.update_screen)
731
return GRUB_ERR_NONE;
733
err = framebuffer.update_screen (framebuffer.front_target,
734
framebuffer.back_target);
738
return GRUB_ERR_NONE;
742
grub_video_vbe_set_active_render_target (struct grub_video_render_target *target)
744
if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
745
target = framebuffer.back_target;
747
return grub_video_fb_set_active_render_target (target);
751
grub_video_vbe_get_active_render_target (struct grub_video_render_target **target)
754
err = grub_video_fb_get_active_render_target (target);
758
if (*target == framebuffer.back_target)
759
*target = GRUB_VIDEO_RENDER_TARGET_DISPLAY;
761
return GRUB_ERR_NONE;
765
564
grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info,
768
grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
769
*framebuf = (char *) framebuffer.ptr
770
+ framebuffer.displayed_page * framebuffer.page_size;
772
567
grub_free (vbe_mode_list);
773
568
vbe_mode_list = NULL;
775
grub_video_fb_fini ();
776
grub_free (framebuffer.offscreen_buffer);
778
return GRUB_ERR_NONE;
569
return grub_video_fb_get_info_and_fini (mode_info, framebuf);
781
572
static struct grub_video_adapter grub_video_vbe_adapter =
800
593
.blit_bitmap = grub_video_fb_blit_bitmap,
801
594
.blit_render_target = grub_video_fb_blit_render_target,
802
595
.scroll = grub_video_fb_scroll,
803
.swap_buffers = grub_video_vbe_swap_buffers,
596
.swap_buffers = grub_video_fb_swap_buffers,
804
597
.create_render_target = grub_video_fb_create_render_target,
805
598
.delete_render_target = grub_video_fb_delete_render_target,
806
.set_active_render_target = grub_video_vbe_set_active_render_target,
807
.get_active_render_target = grub_video_vbe_get_active_render_target,
599
.set_active_render_target = grub_video_fb_set_active_render_target,
600
.get_active_render_target = grub_video_fb_get_active_render_target,