]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
WIP: rotate. phcoder/rotate
authorVladimir Serbinenko <phcoder@gmail.com>
Thu, 9 Feb 2017 01:25:12 +0000 (02:25 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Thu, 9 Feb 2017 01:25:12 +0000 (02:25 +0100)
grub-core/video/fb/fbblit.c
grub-core/video/fb/fbblit_rot.c [new file with mode: 0644]
grub-core/video/fb/fbfill.c
grub-core/video/fb/video_fb.c
include/grub/video.h

index d55924837de6e8679ded4e8ff7e3a0314101fef6..cc7a60c83c304124fe375e2ed78aada5d4302162 100644 (file)
 #include <grub/types.h>
 #include <grub/video.h>
 
-/* Generic replacing blitter (slow).  Works for every supported format.  */
-static void
-grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
-                          struct grub_video_fbblit_info *src,
-                          int x, int y, int width, int height,
-                          int offset_x, int offset_y)
+static inline grub_uint8_t
+alpha_dilute (grub_uint8_t bg, grub_uint8_t fg, grub_uint8_t alpha)
 {
-  int i;
-  int j;
-  grub_uint8_t src_red;
-  grub_uint8_t src_green;
-  grub_uint8_t src_blue;
-  grub_uint8_t src_alpha;
-  grub_video_color_t src_color;
-  grub_video_color_t dst_color;
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-       {
-         src_color = get_pixel (src, i + offset_x, j + offset_y);
+  grub_uint16_t s;
+  grub_uint16_t h, l;
+  s = (fg * alpha) + (bg * (255 ^ alpha));
+  /* Optimised division by 255.  */
+  h = s >> 8;
+  l = s & 0xff;
+  if (h + l >= 255)
+    h++;
+  return h;
+}
 
-         grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
-                                        &src_blue, &src_alpha);
+#define SUFFIX(x) x
+#define ADD_X 0
+#define ADD_Y 0
+#define TRANS_X(x, y) x
+#define TRANS_Y(x, y) y
+#include "fbblit_rot.c"
 
-         dst_color = grub_video_fb_map_rgba (src_red, src_green,
-                                             src_blue, src_alpha);
+#define SUFFIX(x) x ## _90
+#define TRANS_X(x, y) (y)
+#define TRANS_Y(x, y) (-(x))
+#include "fbblit_rot.c"
 
-         set_pixel (dst, x + i, y + j, dst_color);
-       }
-    }
-}
+#define SUFFIX(x) x ## _270
+#define TRANS_X(x, y) (-(y))
+#define TRANS_Y(x, y) (x)
+#include "fbblit_rot.c"
 
 /* Block copy replacing blitter.  Works with modes multiple of 8 bits.  */
 static void
@@ -1145,78 +1143,6 @@ grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
     }
 }
 
-static inline grub_uint8_t
-alpha_dilute (grub_uint8_t bg, grub_uint8_t fg, grub_uint8_t alpha)
-{
-  grub_uint16_t s;
-  grub_uint16_t h, l;
-  s = (fg * alpha) + (bg * (255 ^ alpha));
-  /* Optimised division by 255.  */
-  h = s >> 8;
-  l = s & 0xff;
-  if (h + l >= 255)
-    h++;
-  return h;
-}
-
-/* Generic blending blitter.  Works for every supported format.  */
-static void
-grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
-                        struct grub_video_fbblit_info *src,
-                        int x, int y, int width, int height,
-                        int offset_x, int offset_y)
-{
-  int i;
-  int j;
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t src_red;
-          grub_uint8_t src_green;
-          grub_uint8_t src_blue;
-          grub_uint8_t src_alpha;
-          grub_uint8_t dst_red;
-          grub_uint8_t dst_green;
-          grub_uint8_t dst_blue;
-          grub_uint8_t dst_alpha;
-          grub_video_color_t src_color;
-          grub_video_color_t dst_color;
-
-          src_color = get_pixel (src, i + offset_x, j + offset_y);
-          grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
-                                        &src_blue, &src_alpha);
-
-          if (src_alpha == 0)
-            continue;
-
-          if (src_alpha == 255)
-            {
-              dst_color = grub_video_fb_map_rgba (src_red, src_green,
-                                                 src_blue, src_alpha);
-              set_pixel (dst, x + i, y + j, dst_color);
-              continue;
-            }
-
-          dst_color = get_pixel (dst, x + i, y + j);
-
-          grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
-                                        &dst_green, &dst_blue, &dst_alpha);
-
-          dst_red = alpha_dilute (dst_red, src_red, src_alpha);
-          dst_green = alpha_dilute (dst_green, src_green, src_alpha);
-          dst_blue = alpha_dilute (dst_blue, src_blue, src_alpha);
-
-          dst_alpha = src_alpha;
-          dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
-                                             dst_alpha);
-
-          set_pixel (dst, x + i, y + j, dst_color);
-        }
-    }
-}
-
 /* Optimized blending blitter for RGBA8888 to BGRA8888.  */
 static void
 grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
@@ -1936,6 +1862,45 @@ grub_video_fb_dispatch_blit (struct grub_video_fbblit_info *target,
                             unsigned int width, unsigned int height,
                             int offset_x, int offset_y)
 {
+  if (target->mode_info->rotation == GRUB_VIDEO_ROTATE_90)
+    {
+      int nx = y;
+      int ny = target->mode_info->width - x;
+      if (oper == GRUB_VIDEO_BLIT_REPLACE)
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  */
+         grub_video_fbblit_replace_90 (target, source, nx, ny, width, height,
+                                       offset_x, offset_y);
+         return;
+       }
+      else
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  */
+         grub_video_fbblit_blend_90 (target, source, nx, ny, width, height,
+                                     offset_x, offset_y);
+         return;
+       }
+    }
+  if (target->mode_info->rotation == GRUB_VIDEO_ROTATE_270)
+    {
+      int nx = target->mode_info->height - y;
+      int ny = x;
+      if (oper == GRUB_VIDEO_BLIT_REPLACE)
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  */
+         grub_video_fbblit_replace_270 (target, source, nx, ny, width, height,
+                                        offset_x, offset_y);
+         return;
+       }
+      else
+       {
+         /* No optimized replace operator found, use default (slow) blitter.  */
+         grub_video_fbblit_blend_270 (target, source, nx, ny, width, height,
+                                      offset_x, offset_y);
+         return;
+       }
+    }
+
   if (oper == GRUB_VIDEO_BLIT_REPLACE)
     {
       /* Try to figure out more optimized version for replace operator.  */
diff --git a/grub-core/video/fb/fbblit_rot.c b/grub-core/video/fb/fbblit_rot.c
new file mode 100644 (file)
index 0000000..49ccffb
--- /dev/null
@@ -0,0 +1,96 @@
+/* Generic replacing blitter (slow).  Works for every supported format.  */
+static void
+SUFFIX(grub_video_fbblit_replace) (struct grub_video_fbblit_info *dst,
+                                  struct grub_video_fbblit_info *src,
+                                  int x, int y, int width, int height,
+                                  int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t src_red;
+  grub_uint8_t src_green;
+  grub_uint8_t src_blue;
+  grub_uint8_t src_alpha;
+  grub_video_color_t src_color;
+  grub_video_color_t dst_color;
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+       {
+         src_color = get_pixel (src, i + offset_x, j + offset_y);
+
+         grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+                                        &src_blue, &src_alpha);
+
+         dst_color = grub_video_fb_map_rgba (src_red, src_green,
+                                             src_blue, src_alpha);
+
+         set_pixel (dst, x + TRANS_X(i, j), y + TRANS_Y(i, j), dst_color);
+       }
+    }
+}
+
+/* Generic blending blitter.  Works for every supported format.  */
+static void
+SUFFIX(grub_video_fbblit_blend) (struct grub_video_fbblit_info *dst,
+                                struct grub_video_fbblit_info *src,
+                                int x, int y, int width, int height,
+                                int offset_x, int offset_y)
+{
+  int i;
+  int j;
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t src_red;
+          grub_uint8_t src_green;
+          grub_uint8_t src_blue;
+          grub_uint8_t src_alpha;
+          grub_uint8_t dst_red;
+          grub_uint8_t dst_green;
+          grub_uint8_t dst_blue;
+          grub_uint8_t dst_alpha;
+          grub_video_color_t src_color;
+          grub_video_color_t dst_color;
+
+          src_color = get_pixel (src, i + offset_x, j + offset_y);
+          grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+                                        &src_blue, &src_alpha);
+
+          if (src_alpha == 0)
+            continue;
+
+          if (src_alpha == 255)
+            {
+              dst_color = grub_video_fb_map_rgba (src_red, src_green,
+                                                 src_blue, src_alpha);
+              set_pixel (dst, x + TRANS_X(i, j), y + TRANS_Y(i, j), dst_color);
+              continue;
+            }
+
+          dst_color = get_pixel (dst, x + TRANS_X(i, j), y + TRANS_Y(i, j));
+
+          grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
+                                        &dst_green, &dst_blue, &dst_alpha);
+
+          dst_red = alpha_dilute (dst_red, src_red, src_alpha);
+          dst_green = alpha_dilute (dst_green, src_green, src_alpha);
+          dst_blue = alpha_dilute (dst_blue, src_blue, src_alpha);
+
+          dst_alpha = src_alpha;
+          dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
+                                             dst_alpha);
+
+          set_pixel (dst, x + TRANS_X(i, j), y + TRANS_Y(i, j), dst_color);
+        }
+    }
+}
+
+#undef SUFFIX
+#undef ADD_X
+#undef ADD_Y
+#undef TRANS_X
+#undef TRANS_Y
index 11816d07a0b09c0b379e252061567874d92403ba..8c7fad9cd6aae86c02cb38f0ace426789a7e9cc6 100644 (file)
@@ -32,6 +32,7 @@
 #include <grub/fbutil.h>
 #include <grub/types.h>
 #include <grub/video.h>
+#include <grub/misc.h>
 
 /* Generic filler that works for every supported mode.  */
 static void
index 1a602c8b251f88bcfa6e5504e1b7f527071ec2a5..439a198d021ae285be2346c7e18a0d98da8ab9a6 100644 (file)
@@ -830,7 +830,7 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
 }
 
 static void
-dirty (int y, int height)
+dirty_untrans (int y, int height)
 {
   if (framebuffer.render_target != framebuffer.back_target)
     return;
@@ -840,6 +840,66 @@ dirty (int y, int height)
     framebuffer.current_dirty.last_line = y + height;
 }
 
+static void
+dirty (int x, int width, int y, int height)
+{
+  if (framebuffer.render_target != framebuffer.back_target)
+    return;
+  if (framebuffer.render_target->mode_info.rotation == GRUB_VIDEO_ROTATE_90
+      || framebuffer.render_target->mode_info.rotation == GRUB_VIDEO_ROTATE_270)
+    {
+      if (framebuffer.current_dirty.first_line > x)
+       framebuffer.current_dirty.first_line = x;
+      if (framebuffer.current_dirty.last_line < x + width)
+       framebuffer.current_dirty.last_line = x + width;
+    }
+  else
+    {
+      if (framebuffer.current_dirty.first_line > y)
+       framebuffer.current_dirty.first_line = y;
+      if (framebuffer.current_dirty.last_line < y + height)
+       framebuffer.current_dirty.last_line = y + height;
+    }
+}
+
+static void
+grub_video_fb_fill_rect_untrans (grub_video_color_t color, int x, int y,
+                                unsigned int width, unsigned int height)
+{
+  struct grub_video_fbblit_info target;
+
+  target.mode_info = &framebuffer.render_target->mode_info;
+  target.data = framebuffer.render_target->data;
+
+  grub_video_fb_fill_dispatch (&target, color, x, y,
+                              width, height);
+  dirty_untrans (y, height);
+}
+
+static grub_video_rect_t
+grub_video_transform_rectangle (grub_video_rect_t r, const struct grub_video_mode_info *mode_info)
+{
+  grub_video_rect_t n;
+  switch (mode_info->rotation)
+    {
+    case GRUB_VIDEO_ROTATE_NONE:
+      return r;
+    case GRUB_VIDEO_ROTATE_90:
+      n.width = r.height;
+      n.height = r.width;
+      n.x = r.y;
+      n.y = mode_info->width - r.x - r.width;
+      return n;
+    case GRUB_VIDEO_ROTATE_270:
+      n.width = r.height;
+      n.height = r.width;
+      n.x = mode_info->height - r.y - r.height;
+      n.y = r.x;
+      return n;
+    }
+  return r;
+}
+
 grub_err_t
 grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
                         unsigned int width, unsigned int height)
@@ -895,14 +955,22 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
   x += area_x;
   y += area_y;
 
-  dirty (y, height);
+  dirty (x, width, y, height);
 
   /* Use fbblit_info to encapsulate rendering.  */
   target.mode_info = &framebuffer.render_target->mode_info;
   target.data = framebuffer.render_target->data;
 
-  grub_video_fb_fill_dispatch (&target, color, x, y,
-                              width, height);
+  grub_video_rect_t orig = {
+    .x = x,
+    .y = y,
+    .width = width,
+    .height = height
+  };
+  grub_video_rect_t tran = grub_video_transform_rectangle (orig, &framebuffer.render_target->mode_info);
+
+  grub_video_fb_fill_dispatch (&target, color, tran.x, tran.y,
+                              tran.width, tran.height);
   return GRUB_ERR_NONE;
 }
 
@@ -1008,7 +1076,7 @@ grub_video_fb_blit_source (struct grub_video_fbblit_info *source,
   target.data = framebuffer.render_target->data;
 
   /* Do actual blitting.  */
-  dirty (y, height);
+  dirty (x, width, y, height);
   grub_video_fb_dispatch_blit (&target, source, oper, x, y, width, height,
                                offset_x, offset_y);
 
@@ -1052,42 +1120,70 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
   int src_y;
   int dst_x;
   int dst_y;
+  grub_video_rect_t transformed_viewport;
 
   /* 1. Check if we have something to do.  */
   if ((dx == 0) && (dy == 0))
     return GRUB_ERR_NONE;
 
-  width = framebuffer.render_target->viewport.width - grub_abs (dx);
-  height = framebuffer.render_target->viewport.height - grub_abs (dy);
+  transformed_viewport = grub_video_transform_rectangle (framebuffer.render_target->viewport,
+                                                        &framebuffer.render_target->mode_info);
 
-  dirty (framebuffer.render_target->viewport.y,
-        framebuffer.render_target->viewport.height);
+  dirty (transformed_viewport.x,
+        transformed_viewport.width,
+        transformed_viewport.y,
+        transformed_viewport.height);
+
+  switch (framebuffer.render_target->mode_info.rotation)
+    {
+    case GRUB_VIDEO_ROTATE_NONE:
+      break;
+    case GRUB_VIDEO_ROTATE_90:
+      {
+       int ndx = dy;
+       int ndy = -dx;
+       dx = ndx;
+       dy = ndy;
+      }
+      break;
+    case GRUB_VIDEO_ROTATE_270:
+      {
+       int ndx = -dy;
+       int ndy = dx;
+       dx = ndx;
+       dy = ndy;
+      }
+      break;
+    }
+
+  width = transformed_viewport.width - grub_abs (dx);
+  height = transformed_viewport.height - grub_abs (dy);
 
   if (dx < 0)
     {
-      src_x = framebuffer.render_target->viewport.x - dx;
-      dst_x = framebuffer.render_target->viewport.x;
+      src_x = transformed_viewport.x - dx;
+      dst_x = transformed_viewport.x;
     }
   else
     {
-      src_x = framebuffer.render_target->viewport.x;
-      dst_x = framebuffer.render_target->viewport.x + dx;
+      src_x = transformed_viewport.x;
+      dst_x = transformed_viewport.x + dx;
     }
 
   if (dy < 0)
     {
-      src_y = framebuffer.render_target->viewport.y - dy;
-      dst_y = framebuffer.render_target->viewport.y;
+      src_y = transformed_viewport.y - dy;
+      dst_y = transformed_viewport.y;
     }
   else
     {
-      src_y = framebuffer.render_target->viewport.y;
-      dst_y = framebuffer.render_target->viewport.y + dy;
+      src_y = transformed_viewport.y;
+      dst_y = transformed_viewport.y + dy;
     }
 
   /* 2. Check if there is need to copy data.  */
-  if ((grub_abs (dx) < framebuffer.render_target->viewport.width)
-       && (grub_abs (dy) < framebuffer.render_target->viewport.height))
+  if ((grub_abs (dx) < transformed_viewport.width)
+       && (grub_abs (dy) < transformed_viewport.height))
     {
       /* 3. Move data in render target.  */
       struct grub_video_fbblit_info target;
@@ -1109,7 +1205,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
          src = (void *) grub_video_fb_get_video_ptr (&target,       \
                                                      src_x, src_y); \
          /* 3a. Move data upwards.  */                              \
-         for (j = 0; j < height; j++)                               \
+         for (j = 0; j < height; j++)                            \
            {                                                        \
              for (i = 0; i < linelen; i++)                          \
                *(dst++) = *(src++);                                 \
@@ -1128,7 +1224,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
                                             src_y + height - 1);    \
          dst--;                                                     \
           src--;                                                     \
-         for (j = 0; j < height; j++)                               \
+         for (j = 0; j < height; j++)                            \
            {                                                        \
              for (i = 0; i < linelen; i++)                          \
                *(dst--) = *(src--);                                 \
@@ -1178,27 +1274,27 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
 
   /* 4a. Fill top & bottom parts.  */
   if (dy > 0)
-    grub_video_fb_fill_rect (color, 0, 0, framebuffer.render_target->viewport.width, dy);
+    grub_video_fb_fill_rect_untrans (color, 0, 0, transformed_viewport.width, dy);
   else if (dy < 0)
     {
-      if (framebuffer.render_target->viewport.height < grub_abs (dy))
-        dy = -framebuffer.render_target->viewport.height;
+      if (transformed_viewport.height < grub_abs (dy))
+        dy = -transformed_viewport.height;
 
-      grub_video_fb_fill_rect (color, 0, framebuffer.render_target->viewport.height + dy,
-                                framebuffer.render_target->viewport.width, -dy);
+      grub_video_fb_fill_rect_untrans (color, 0, transformed_viewport.height + dy,
+                                      transformed_viewport.width, -dy);
     }
 
   /* 4b. Fill left & right parts.  */
   if (dx > 0)
-    grub_video_fb_fill_rect (color, 0, 0,
-                              dx, framebuffer.render_target->viewport.height);
+    grub_video_fb_fill_rect_untrans (color, 0, 0,
+                              dx, transformed_viewport.height);
   else if (dx < 0)
     {
-      if (framebuffer.render_target->viewport.width < grub_abs (dx))
-        dx = -framebuffer.render_target->viewport.width;
+      if (transformed_viewport.width < grub_abs (dx))
+        dx = -transformed_viewport.width;
 
-      grub_video_fb_fill_rect (color, framebuffer.render_target->viewport.width + dx, 0,
-                                -dx, framebuffer.render_target->viewport.height);
+      grub_video_fb_fill_rect_untrans (color, transformed_viewport.width + dx, 0,
+                                      -dx, transformed_viewport.height);
     }
 
   return GRUB_ERR_NONE;
@@ -1228,6 +1324,8 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
   /* TODO: Implement other types too.
      Currently only 32bit render targets are supported.  */
 
+  target->mode_info.rotation = GRUB_VIDEO_ROTATE_NONE;
+
   /* Mark render target as allocated.  */
   target->is_allocated = 1;
 
@@ -1253,6 +1351,8 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
   /* Setup render target format.  */
   target->mode_info.width = width;
   target->mode_info.height = height;
+  target->mode_info.original_width = width;
+  target->mode_info.original_height = height;
   switch (mode_type)
     {
     case GRUB_VIDEO_MODE_TYPE_INDEX_COLOR
@@ -1336,6 +1436,17 @@ grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_targ
 
   grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info));
 
+  target->mode_info.rotation = GRUB_VIDEO_ROTATE_270; ///!!!
+  target->mode_info.original_width = target->mode_info.width;
+  target->mode_info.original_height = target->mode_info.height;
+
+  if (target->mode_info.rotation == GRUB_VIDEO_ROTATE_90
+      || target->mode_info.rotation == GRUB_VIDEO_ROTATE_270)
+    {
+      target->mode_info.width = target->mode_info.original_height;
+      target->mode_info.height = target->mode_info.original_width;
+    }
+
   /* Reset viewport, region and area to match new mode.  */
   target->viewport.x = 0;
   target->viewport.y = 0;
@@ -1356,9 +1467,9 @@ grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_targ
   target->area_offset_y = 0;
 
   /* Clear render target with black and maximum transparency.  */
-  for (y = 0; y < mode_info->height; y++)
+  for (y = 0; y < target->mode_info.original_height; y++)
     grub_memset (target->data + mode_info->pitch * y, 0,
-                mode_info->bytes_per_pixel * mode_info->width);
+                mode_info->bytes_per_pixel * target->mode_info.original_width);
 
   /* Save result to caller.  */
   *result = target;
@@ -1427,7 +1538,7 @@ doublebuf_blit_update_screen (void)
                 * (framebuffer.current_dirty.last_line
                    - framebuffer.current_dirty.first_line));
   framebuffer.current_dirty.first_line
-    = framebuffer.back_target->mode_info.height;
+    = framebuffer.back_target->mode_info.original_height;
   framebuffer.current_dirty.last_line = 0;
 
   return GRUB_ERR_NONE;
@@ -1636,7 +1747,7 @@ grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask,
   framebuffer.render_page = 0;
   framebuffer.set_page = 0;
   framebuffer.current_dirty.first_line
-    = framebuffer.back_target->mode_info.height;
+    = framebuffer.back_target->mode_info.original_height;
   framebuffer.current_dirty.last_line = 0;
 
   mode_info->mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
@@ -1668,6 +1779,9 @@ grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info,
   grub_memcpy (mode_info, &(framebuffer.back_target->mode_info),
               sizeof (*mode_info));
 
+  mode_info->width = framebuffer.back_target->mode_info.original_width;
+  mode_info->height = framebuffer.back_target->mode_info.original_height;
+
   /* We are about to load a kernel.  Switch back to page zero, since some
      kernel drivers expect that.  */
   if (framebuffer.set_page && framebuffer.displayed_page != 0)
index 52c3fd71e10e44d68968f38d1422b8e7d3f5eaa0..49d23fc1712e68cc6f0fccb45f0e86836033476b 100644 (file)
@@ -75,6 +75,13 @@ typedef enum grub_video_mode_type
     GRUB_VIDEO_MODE_TYPE_INFO_MASK        = 0x00FF0000,
   } grub_video_mode_type_t;
 
+enum grub_video_rotation
+  {
+    GRUB_VIDEO_ROTATE_NONE,
+    GRUB_VIDEO_ROTATE_90,
+    GRUB_VIDEO_ROTATE_270,
+  };
+
 /* The basic render target representing the whole display.  This always
    renders to the back buffer when double-buffering is in use.  */
 #define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
@@ -122,12 +129,20 @@ enum grub_video_blit_operators
 
 struct grub_video_mode_info
 {
-  /* Width of the screen.  */
+  /* Width of the screen, before the rotation.  */
+  unsigned int original_width;
+
+  /* Height of the screen, before the rotation.  */
+  unsigned int original_height;
+
+  /* Width of the screen, after the rotation.  */
   unsigned int width;
 
-  /* Height of the screen.  */
+  /* Height of the screen, after the rotation.  */
   unsigned int height;
 
+  enum grub_video_rotation rotation;
+
   /* Mode type bitmask.  Contains information like is it Index color or
      RGB mode.  */
   grub_video_mode_type_t mode_type;