125
146
/* Make sure viewport is withing screen dimensions. If viewport was set
126
147
to be out of the region, mark its size as zero. */
127
if (x > render_target->mode_info.width)
148
if (x > framebuffer.render_target->mode_info.width)
133
if (y > render_target->mode_info.height)
154
if (y > framebuffer.render_target->mode_info.height)
139
if (x + width > render_target->mode_info.width)
140
width = render_target->mode_info.width - x;
142
if (y + height > render_target->mode_info.height)
143
height = render_target->mode_info.height - y;
145
render_target->viewport.x = x;
146
render_target->viewport.y = y;
147
render_target->viewport.width = width;
148
render_target->viewport.height = height;
160
if (x + width > framebuffer.render_target->mode_info.width)
161
width = framebuffer.render_target->mode_info.width - x;
163
if (y + height > framebuffer.render_target->mode_info.height)
164
height = framebuffer.render_target->mode_info.height - y;
166
framebuffer.render_target->viewport.x = x;
167
framebuffer.render_target->viewport.y = y;
168
framebuffer.render_target->viewport.width = width;
169
framebuffer.render_target->viewport.height = height;
150
171
return GRUB_ERR_NONE;
261
282
grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
262
283
grub_uint8_t blue, grub_uint8_t alpha)
264
if ((render_target->mode_info.mode_type
285
if ((framebuffer.render_target->mode_info.mode_type
265
286
& GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
266
287
/* No alpha available in index color modes, just use
267
288
same value as in only RGB modes. */
268
289
return grub_video_fb_map_rgb (red, green, blue);
269
else if ((render_target->mode_info.mode_type
290
else if ((framebuffer.render_target->mode_info.mode_type
270
291
& GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
272
if (red == render_target->mode_info.fg_red
273
&& green == render_target->mode_info.fg_green
274
&& blue == render_target->mode_info.fg_blue
275
&& alpha == render_target->mode_info.fg_alpha)
293
if (red == framebuffer.render_target->mode_info.fg_red
294
&& green == framebuffer.render_target->mode_info.fg_green
295
&& blue == framebuffer.render_target->mode_info.fg_blue
296
&& alpha == framebuffer.render_target->mode_info.fg_alpha)
426
if ((x + width) > render_target->viewport.width)
427
width = render_target->viewport.width - x;
428
if ((y + height) > render_target->viewport.height)
429
height = render_target->viewport.height - y;
447
if ((x + width) > framebuffer.render_target->viewport.width)
448
width = framebuffer.render_target->viewport.width - x;
449
if ((y + height) > framebuffer.render_target->viewport.height)
450
height = framebuffer.render_target->viewport.height - y;
431
452
/* Add viewport offset. */
432
x += render_target->viewport.x;
433
y += render_target->viewport.y;
453
x += framebuffer.render_target->viewport.x;
454
y += framebuffer.render_target->viewport.y;
435
456
/* Use fbblit_info to encapsulate rendering. */
436
target.mode_info = &render_target->mode_info;
437
target.data = render_target->data;
457
target.mode_info = &framebuffer.render_target->mode_info;
458
target.data = framebuffer.render_target->data;
439
460
/* Try to figure out more optimized version. Note that color is already
440
461
mapped to target format so we can make assumptions based on that. */
945
966
if ((dx == 0) && (dy == 0))
946
967
return GRUB_ERR_NONE;
948
width = render_target->viewport.width - grub_abs (dx);
949
height = render_target->viewport.height - grub_abs (dy);
969
width = framebuffer.render_target->viewport.width - grub_abs (dx);
970
height = framebuffer.render_target->viewport.height - grub_abs (dy);
953
src_x = render_target->viewport.x - dx;
954
dst_x = render_target->viewport.x;
974
src_x = framebuffer.render_target->viewport.x - dx;
975
dst_x = framebuffer.render_target->viewport.x;
958
src_x = render_target->viewport.x;
959
dst_x = render_target->viewport.x + dx;
979
src_x = framebuffer.render_target->viewport.x;
980
dst_x = framebuffer.render_target->viewport.x + dx;
964
src_y = render_target->viewport.y - dy;
965
dst_y = render_target->viewport.y;
985
src_y = framebuffer.render_target->viewport.y - dy;
986
dst_y = framebuffer.render_target->viewport.y;
969
src_y = render_target->viewport.y;
970
dst_y = render_target->viewport.y + dy;
990
src_y = framebuffer.render_target->viewport.y;
991
dst_y = framebuffer.render_target->viewport.y + dy;
973
994
/* 2. Check if there is need to copy data. */
974
if ((grub_abs (dx) < render_target->viewport.width)
975
&& (grub_abs (dy) < render_target->viewport.height))
995
if ((grub_abs (dx) < framebuffer.render_target->viewport.width)
996
&& (grub_abs (dy) < framebuffer.render_target->viewport.height))
977
998
/* 3. Move data in render target. */
978
999
struct grub_video_fbblit_info target;
980
1001
int linedelta, linelen;
982
target.mode_info = &render_target->mode_info;
983
target.data = render_target->data;
1003
target.mode_info = &framebuffer.render_target->mode_info;
1004
target.data = framebuffer.render_target->data;
985
1006
linedelta = target.mode_info->pitch
986
1007
- width * target.mode_info->bytes_per_pixel;
1064
1085
/* 4a. Fill top & bottom parts. */
1066
grub_video_fb_fill_rect (color, 0, 0, render_target->viewport.width, dy);
1087
grub_video_fb_fill_rect (color, 0, 0, framebuffer.render_target->viewport.width, dy);
1067
1088
else if (dy < 0)
1069
if (render_target->viewport.height < grub_abs (dy))
1070
dy = -render_target->viewport.height;
1090
if (framebuffer.render_target->viewport.height < grub_abs (dy))
1091
dy = -framebuffer.render_target->viewport.height;
1072
grub_video_fb_fill_rect (color, 0, render_target->viewport.height + dy,
1073
render_target->viewport.width, -dy);
1093
grub_video_fb_fill_rect (color, 0, framebuffer.render_target->viewport.height + dy,
1094
framebuffer.render_target->viewport.width, -dy);
1076
1097
/* 4b. Fill left & right parts. */
1078
1099
grub_video_fb_fill_rect (color, 0, 0,
1079
dx, render_target->viewport.height);
1100
dx, framebuffer.render_target->viewport.height);
1080
1101
else if (dx < 0)
1082
if (render_target->viewport.width < grub_abs (dx))
1083
dx = -render_target->viewport.width;
1103
if (framebuffer.render_target->viewport.width < grub_abs (dx))
1104
dx = -framebuffer.render_target->viewport.width;
1085
grub_video_fb_fill_rect (color, render_target->viewport.width + dx, 0,
1086
-dx, render_target->viewport.height);
1106
grub_video_fb_fill_rect (color, framebuffer.render_target->viewport.width + dx, 0,
1107
-dx, framebuffer.render_target->viewport.height);
1089
1110
return GRUB_ERR_NONE;
1274
1300
err = grub_video_fb_create_render_target_from_pointer (back, &mode_info,
1301
framebuffer.offscreen_buffer);
1279
1305
grub_video_fb_delete_render_target (*front);
1280
grub_free (offscreen_buffer);
1306
grub_free (framebuffer.offscreen_buffer);
1307
framebuffer.offscreen_buffer = 0;
1282
1309
return grub_errno;
1284
1311
(*back)->is_allocated = 1;
1286
*update_screen = doublebuf_blit_update_screen;
1313
framebuffer.update_screen = doublebuf_blit_update_screen;
1315
return GRUB_ERR_NONE;
1319
doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front
1320
__attribute__ ((unused)),
1321
struct grub_video_fbrender_target *back
1322
__attribute__ ((unused)))
1324
int new_displayed_page;
1325
struct grub_video_fbrender_target *target;
1328
/* Swap the page numbers in the framebuffer struct. */
1329
new_displayed_page = framebuffer.render_page;
1330
framebuffer.render_page = framebuffer.displayed_page;
1331
framebuffer.displayed_page = new_displayed_page;
1333
err = framebuffer.set_page (framebuffer.displayed_page);
1336
/* Restore previous state. */
1337
framebuffer.render_page = framebuffer.displayed_page;
1338
framebuffer.displayed_page = new_displayed_page;
1342
target = framebuffer.back_target;
1343
framebuffer.back_target = framebuffer.front_target;
1344
framebuffer.front_target = target;
1346
if (framebuffer.front_target->mode_info.mode_type
1347
& GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)
1348
grub_memcpy (framebuffer.back_target->data, framebuffer.front_target->data,
1349
framebuffer.back_target->mode_info.pitch
1350
* framebuffer.back_target->mode_info.height);
1352
err = grub_video_fb_get_active_render_target (&target);
1356
if (framebuffer.render_target == framebuffer.back_target)
1357
framebuffer.render_target = framebuffer.front_target;
1358
else if (framebuffer.render_target == framebuffer.front_target)
1359
framebuffer.render_target = framebuffer.back_target;
1365
doublebuf_pageflipping_init (struct grub_video_mode_info *mode_info,
1366
volatile void *page0_ptr,
1367
grub_video_fb_set_page_t set_page_in,
1368
volatile void *page1_ptr)
1372
framebuffer.displayed_page = 0;
1373
framebuffer.render_page = 1;
1375
framebuffer.update_screen = doublebuf_pageflipping_update_screen;
1377
err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target,
1379
(void *) page0_ptr);
1383
err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target,
1385
(void *) page1_ptr);
1388
grub_video_fb_delete_render_target (framebuffer.front_target);
1392
/* Set the framebuffer memory data pointer and display the right page. */
1393
err = set_page_in (framebuffer.displayed_page);
1396
grub_video_fb_delete_render_target (framebuffer.front_target);
1397
grub_video_fb_delete_render_target (framebuffer.back_target);
1400
framebuffer.set_page = set_page_in;
1402
return GRUB_ERR_NONE;
1405
/* Select the best double buffering mode available. */
1407
grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask,
1408
struct grub_video_mode_info *mode_info,
1409
volatile void *page0_ptr,
1410
grub_video_fb_set_page_t set_page_in,
1411
volatile void *page1_ptr)
1414
int updating_swap_needed;
1416
updating_swap_needed
1417
= grub_video_check_mode_flag (mode_type, mode_mask,
1418
GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP, 0);
1420
/* Do double buffering only if it's either requested or efficient. */
1421
if (set_page_in && grub_video_check_mode_flag (mode_type, mode_mask,
1422
GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
1423
!updating_swap_needed))
1425
mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
1426
if (updating_swap_needed)
1427
mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP;
1429
err = doublebuf_pageflipping_init (mode_info, page0_ptr,
1434
framebuffer.render_target = framebuffer.back_target;
1435
return GRUB_ERR_NONE;
1438
mode_info->mode_type &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
1439
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
1441
grub_errno = GRUB_ERR_NONE;
1444
if (grub_video_check_mode_flag (mode_type, mode_mask,
1445
GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
1448
mode_info->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
1449
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
1451
err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target,
1452
&framebuffer.back_target,
1454
(void *) page0_ptr);
1458
framebuffer.render_target = framebuffer.back_target;
1459
return GRUB_ERR_NONE;
1462
mode_info->mode_type &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
1463
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
1465
grub_errno = GRUB_ERR_NONE;
1468
/* Fall back to no double buffering. */
1469
err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target,
1471
(void *) page0_ptr);
1476
framebuffer.back_target = framebuffer.front_target;
1477
framebuffer.update_screen = 0;
1479
mode_info->mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
1481
framebuffer.render_target = framebuffer.back_target;
1483
return GRUB_ERR_NONE;
1488
grub_video_fb_swap_buffers (void)
1491
if (!framebuffer.update_screen)
1492
return GRUB_ERR_NONE;
1494
err = framebuffer.update_screen (framebuffer.front_target,
1495
framebuffer.back_target);
1499
return GRUB_ERR_NONE;
1503
grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info,
1506
grub_memcpy (mode_info, &(framebuffer.front_target->mode_info),
1507
sizeof (*mode_info));
1508
*framebuf = framebuffer.front_target->data;
1510
grub_video_fb_fini ();
1288
1512
return GRUB_ERR_NONE;