Skip to content

Commit

Permalink
Support display stride so we can do arbitrary resolutions in vmware
Browse files Browse the repository at this point in the history
This is a terrible back. We need to do things better with handling the
display, possibly so we can do support for true 24bpp modes at some
point (though this isn't high priority). Ultimately, the _fullscreen
graphics support needs to be removed and embedded into 1) a separate
library, or 2) Yutani, the only thing that does fullscreen video modes
anyway. We can continue to render into a generic graphics buffer -
double buffered for the nested modes, non-double-buffered for the full
screen mode (and then blit with surface blits). For now, however, this
is at least functioning.
  • Loading branch information
klange committed Feb 22, 2017
1 parent 729eca9 commit b03bbec
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 9 deletions.
1 change: 1 addition & 0 deletions kernel/include/video.h
Expand Up @@ -6,6 +6,7 @@
#define IO_VID_ADDR 0x5004
#define IO_VID_SIGNAL 0x5005
#define IO_VID_SET 0x5006
#define IO_VID_STRIDE 0x5007

#ifdef _KERNEL_
extern void lfb_set_resolution(uint16_t x, uint16_t y);
Expand Down
25 changes: 18 additions & 7 deletions modules/lfbvideo.c
Expand Up @@ -28,6 +28,7 @@ static void graphics_install_preset(uint16_t, uint16_t);
uint16_t lfb_resolution_x = 0;
uint16_t lfb_resolution_y = 0;
uint16_t lfb_resolution_b = 0;
uint32_t lfb_resolution_s = 0;

/* BOCHS / QEMU VBE Driver */
static void graphics_install_bochs(uint16_t, uint16_t);
Expand Down Expand Up @@ -78,6 +79,9 @@ static int ioctl_vid(fs_node_t * node, int request, void * argp) {
validate(argp);
lfb_set_resolution(((struct vid_size *)argp)->width, ((struct vid_size *)argp)->height);
return 0;
case IO_VID_STRIDE:
*((size_t *)argp) = lfb_resolution_s;
return 0;
default:
return -1; /* TODO EINV... something or other */
}
Expand All @@ -98,7 +102,7 @@ static int vignette_at(int x, int y) {

static void set_point(int x, int y, uint32_t value) {
uint32_t * disp = (uint32_t *)lfb_vid_memory;
uint32_t * cell = &disp[y * lfb_resolution_x + x];
uint32_t * cell = &disp[y * (lfb_resolution_s / 4) + x];
*cell = value;
}

Expand All @@ -125,7 +129,7 @@ static void lfb_video_panic(char ** msgs) {
uint32_t * disp = (uint32_t *)lfb_vid_memory;
for (int y = 0; y < lfb_resolution_y; y++) {
for (int x = 0; x < lfb_resolution_x; x++) {
uint32_t * cell = &disp[y * lfb_resolution_x + x];
uint32_t * cell = &disp[y * (lfb_resolution_s / 4) + x];

int r = _RED(*cell);
int g = _GRE(*cell);
Expand Down Expand Up @@ -176,8 +180,9 @@ static fs_node_t * lfb_video_device_create(void /* TODO */) {
return fnode;
}

static void finalize_graphics(uint16_t x, uint16_t y, uint16_t b) {
static void finalize_graphics(uint16_t x, uint16_t y, uint16_t b, uint32_t s) {
lfb_resolution_x = x;
lfb_resolution_s = s;
lfb_resolution_y = y;
lfb_resolution_b = b;
fs_node_t * fb_device = lfb_video_device_create();
Expand Down Expand Up @@ -250,6 +255,7 @@ static void res_change_bochs(uint16_t x, uint16_t y) {
}

lfb_resolution_x = x;
lfb_resolution_s = x * 4;
lfb_resolution_y = y;
}

Expand Down Expand Up @@ -314,7 +320,7 @@ static void graphics_install_bochs(uint16_t resolution_x, uint16_t resolution_y)
for (uintptr_t i = (uintptr_t)lfb_vid_memory; i <= (uintptr_t)lfb_vid_memory + vid_memsize; i += 0x1000) {
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
}
finalize_graphics(resolution_x, resolution_y, PREFERRED_B);
finalize_graphics(resolution_x, resolution_y, PREFERRED_B, resolution_x * 4);
}

/* }}} end bochs support */
Expand Down Expand Up @@ -367,7 +373,7 @@ static void graphics_install_preset(uint16_t w, uint16_t h) {
debug_print(WARNING, "Failed to locate video memory. This could end poorly.");

mem_found:
finalize_graphics(w,h,b);
finalize_graphics(w,h,b,w*4);

}

Expand All @@ -381,6 +387,7 @@ static void graphics_install_preset(uint16_t w, uint16_t h) {
#define SVGA_REG_WIDTH 2
#define SVGA_REG_HEIGHT 3
#define SVGA_REG_BITS_PER_PIXEL 7
#define SVGA_REG_BYTES_PER_LINE 12
#define SVGA_REG_FB_START 13

static uint32_t vmware_io = 0;
Expand All @@ -405,15 +412,17 @@ static uint32_t vmware_read(int reg) {
}

static void vmware_set_mode(uint16_t w, uint16_t h) {
w = w & ~1;
vmware_write(SVGA_REG_ENABLE, 0);
vmware_write(SVGA_REG_ID, 0);
vmware_write(SVGA_REG_WIDTH, w);
vmware_write(SVGA_REG_HEIGHT, h);
vmware_write(SVGA_REG_BITS_PER_PIXEL, 32);
vmware_write(SVGA_REG_ENABLE, 1);

uint32_t bpl = vmware_read(SVGA_REG_BYTES_PER_LINE);

lfb_resolution_x = w;
lfb_resolution_s = bpl;
lfb_resolution_y = h;

}
Expand All @@ -435,6 +444,8 @@ static void graphics_install_vmware(uint16_t w, uint16_t h) {
vmware_write(SVGA_REG_BITS_PER_PIXEL, 32);
vmware_write(SVGA_REG_ENABLE, 1);

uint32_t bpl = vmware_read(SVGA_REG_BYTES_PER_LINE);

lfb_resolution_impl = &vmware_set_mode;

uint32_t fb_addr = vmware_read(SVGA_REG_FB_START);
Expand All @@ -451,7 +462,7 @@ static void graphics_install_vmware(uint16_t w, uint16_t h) {
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
}

finalize_graphics(w,h,32);
finalize_graphics(w,h,32,bpl);
}

struct disp_mode {
Expand Down
8 changes: 6 additions & 2 deletions userspace/gui/compositor/compositor.c
Expand Up @@ -1096,8 +1096,10 @@ static void redraw_windows(yutani_globals_t * yg) {

if (!yutani_options.nested) {
reinit_graphics_fullscreen(yg->backend_ctx);
yg->stride = framebuffer_stride();
} else {
reinit_graphics_yutani(yg->backend_ctx, yg->host_window);
yg->stride = yg->backend_ctx->width * 4;
yutani_window_resize_done(yg->host_context, yg->host_window);
}
yg->width = yg->backend_ctx->width;
Expand All @@ -1108,7 +1110,7 @@ static void redraw_windows(yutani_globals_t * yg) {
yg->framebuffer_surface = cairo_image_surface_create_for_data(
yg->backend_framebuffer, CAIRO_FORMAT_ARGB32, yg->width, yg->height, stride);
yg->real_surface = cairo_image_surface_create_for_data(
yg->backend_ctx->buffer, CAIRO_FORMAT_ARGB32, yg->width, yg->height, stride);
yg->backend_ctx->buffer, CAIRO_FORMAT_ARGB32, yg->width, yg->height, yg->stride);

yg->framebuffer_ctx = cairo_create(yg->framebuffer_surface);
yg->real_ctx = cairo_create(yg->real_surface);
Expand All @@ -1134,7 +1136,7 @@ void yutani_cairo_init(yutani_globals_t * yg) {
yg->framebuffer_surface = cairo_image_surface_create_for_data(
yg->backend_framebuffer, CAIRO_FORMAT_ARGB32, yg->width, yg->height, stride);
yg->real_surface = cairo_image_surface_create_for_data(
yg->backend_ctx->buffer, CAIRO_FORMAT_ARGB32, yg->width, yg->height, stride);
yg->backend_ctx->buffer, CAIRO_FORMAT_ARGB32, yg->width, yg->height, yg->stride);

yg->framebuffer_ctx = cairo_create(yg->framebuffer_surface);
yg->real_ctx = cairo_create(yg->real_surface);
Expand Down Expand Up @@ -2015,10 +2017,12 @@ int main(int argc, char * argv[]) {
yutani_window_move(yg->host_context, yg->host_window, 50, 50);
yutani_window_advertise_icon(yg->host_context, yg->host_window, "Compositor", "compositor");
yg->backend_ctx = init_graphics_yutani_double_buffer(yg->host_window);
yg->stride = yg->backend_ctx->width * 4;
} else {
_static_yg = yg;
signal(SIGWINEVENT, yutani_display_resize_handle);
yg->backend_ctx = init_graphics_fullscreen_double_buffer();
yg->stride = framebuffer_stride();
}

if (!yg->backend_ctx) {
Expand Down
2 changes: 2 additions & 0 deletions userspace/gui/compositor/yutani_int.h
Expand Up @@ -172,6 +172,8 @@ typedef struct {
list_t * timer_subscribers;

uint32_t last_mouse_buttons;

uint32_t stride;
} yutani_globals_t;

struct key_bind {
Expand Down
6 changes: 6 additions & 0 deletions userspace/lib/graphics.c
Expand Up @@ -72,6 +72,12 @@ gfx_context_t * init_graphics_fullscreen() {
return out;
}

uint32_t framebuffer_stride(void) {
uint32_t stride;
ioctl(framebuffer_fd, IO_VID_STRIDE, &stride);
return stride;
}

gfx_context_t * init_graphics_fullscreen_double_buffer() {
gfx_context_t * out = init_graphics_fullscreen();
if (!out) return NULL;
Expand Down

0 comments on commit b03bbec

Please sign in to comment.