From 4cc3f8adc73de9d1ea1bc2ad46e6a570431d9ad2 Mon Sep 17 00:00:00 2001 From: Fabian Date: Thu, 10 Feb 2022 15:51:02 +0100 Subject: [PATCH] vga: pass buffer from emulator to frontend, remove tell-buffer, avoid storing layers in state (call update_layers in set_state instead) --- src/browser/dummy_screen.js | 7 ------ src/browser/screen.js | 40 ++++------------------------------ src/vga.js | 43 +++++++++++++++---------------------- 3 files changed, 21 insertions(+), 69 deletions(-) diff --git a/src/browser/dummy_screen.js b/src/browser/dummy_screen.js index ec688b88..5731a4bd 100644 --- a/src/browser/dummy_screen.js +++ b/src/browser/dummy_screen.js @@ -9,8 +9,6 @@ function DummyScreenAdapter(bus) { var graphic_image_data, - graphic_buffer, - graphic_buffer32, /** @type {number} */ cursor_row, @@ -123,13 +121,8 @@ function DummyScreenAdapter(bus) this.set_size_graphical = function(width, height) { - graphic_buffer = new Uint8Array(4 * width * height); - graphic_buffer32 = new Int32Array(graphic_buffer.buffer); - graphical_mode_width = width; graphical_mode_height = height; - - this.bus.send("screen-tell-buffer", [graphic_buffer32], [graphic_buffer32.buffer]); }; this.set_scale = function(s_x, s_y) diff --git a/src/browser/screen.js b/src/browser/screen.js index 46c966e5..a1a71918 100644 --- a/src/browser/screen.js +++ b/src/browser/screen.js @@ -18,9 +18,6 @@ function ScreenAdapter(screen_container, bus) cursor_element = document.createElement("div"); var - graphic_image_data, - graphic_buffer32, - /** @type {number} */ cursor_row, @@ -35,12 +32,6 @@ function ScreenAdapter(screen_container, bus) base_scale = 1, - graphical_mode_width, - graphical_mode_height, - - modified_pixel_min = 0, - modified_pixel_max = 0, - changed_rows, // are we in graphical mode now? @@ -314,22 +305,8 @@ function ScreenAdapter(screen_container, bus) graphic_screen.width = width; graphic_screen.height = height; - //graphic_screen.style.width = width * scale_x + "px"; - //graphic_screen.style.height = height * scale_y + "px"; - - // Make sure to call this here, because pixels are transparent otherwise - //screen.clear_screen(); - - graphic_image_data = graphic_context.createImageData(buffer_width, buffer_height); - graphic_buffer32 = new Int32Array(graphic_image_data.data.buffer); - - graphical_mode_width = width; - graphical_mode_height = height; - // add some scaling to tiny resolutions - if(graphical_mode_width <= 640 && - graphical_mode_width * 2 < window.innerWidth && - graphical_mode_height * 2 < window.innerHeight) + if(width <= 640 && width * 2 < window.innerWidth && width * 2 < window.innerHeight) { base_scale = 2; } @@ -338,7 +315,6 @@ function ScreenAdapter(screen_container, bus) base_scale = 1; } - this.bus.send("screen-tell-buffer", [graphic_buffer32], [graphic_buffer32.buffer]); update_scale_graphic(); }; @@ -511,19 +487,11 @@ function ScreenAdapter(screen_container, bus) { if(DEBUG_SCREEN_LAYERS) { - // Draw the entire buffer. Useful for debugging - // panning / page flipping / screen splitting code for both - // v86 developers and os developers - graphic_context.putImageData( - graphic_image_data, - 0, 0 - ); - // For each visible layer that would've been drawn, draw a // rectangle to visualise the layer instead. graphic_context.strokeStyle = "#0F0"; graphic_context.lineWidth = 4; - layers.forEach((layer) => + layers.forEach(layer => { graphic_context.strokeRect( layer.buffer_x, @@ -536,10 +504,10 @@ function ScreenAdapter(screen_container, bus) return; } - layers.forEach((layer) => + layers.forEach(layer => { graphic_context.putImageData( - graphic_image_data, + layer.image_data, layer.screen_x - layer.buffer_x, layer.screen_y - layer.buffer_y, layer.buffer_x, diff --git a/src/vga.js b/src/vga.js index 733fcbf2..362eaa3c 100644 --- a/src/vga.js +++ b/src/vga.js @@ -358,16 +358,7 @@ function VGAScreen(cpu, bus, vga_memory_size) this.diff_plot_min = this.vga_memory_size; this.diff_plot_max = 0; - this.dest_buffer = undefined; - - bus.register("screen-tell-buffer", function(data) - { - if(this.dest_buffer && data[0]) - { - data[0].set(this.dest_buffer.subarray(0, data[0].length)); - } - this.dest_buffer = data[0]; - }, this); + this.dest_buffer = null; bus.register("screen-fill-buffer", function() { @@ -410,14 +401,7 @@ VGAScreen.prototype.get_state = function() state[3] = this.cursor_scanline_end; state[4] = this.max_cols; state[5] = this.max_rows; - state[6] = this.layers.map(layer => [ - layer.screen_x, - layer.screen_y, - layer.buffer_x, - layer.buffer_y, - layer.buffer_width, - layer.buffer_height, - ]); + state[7] = this.dac_state; state[8] = this.start_address; state[9] = this.graphical_mode; @@ -484,14 +468,7 @@ VGAScreen.prototype.set_state = function(state) this.cursor_scanline_end = state[3]; this.max_cols = state[4]; this.max_rows = state[5]; - this.layers = state[6].map(layer => ({ - screen_x: layer[0], - screen_y: layer[1], - buffer_x: layer[2], - buffer_y: layer[3], - buffer_width: layer[4], - buffer_height: layer[5], - })); + this.dac_state = state[7]; this.start_address = state[8]; this.graphical_mode = state[9]; @@ -564,6 +541,7 @@ VGAScreen.prototype.set_state = function(state) else { this.update_vga_size(); + this.update_layers(); this.complete_replot(); } } @@ -1174,6 +1152,16 @@ VGAScreen.prototype.set_size_graphical = function(width, height, bpp, virtual_wi this.stats.res_x = width; this.stats.res_y = height; + if (typeof ImageData !== "undefined") + { + this.image_data = new ImageData(width, height); + this.dest_buffer = new Int32Array(this.image_data.data.buffer); + } + else + { + // TODO: nodejs + } + this.bus.send("screen-set-size-graphical", [width, height, virtual_width, virtual_height, bpp]); } }; @@ -1304,6 +1292,7 @@ VGAScreen.prototype.update_layers = function() for(var x = -start_buffer_col, y = 0; x < this.screen_width; x += this.virtual_width, y++) { this.layers.push({ + image_data: this.image_data, screen_x: x, screen_y: 0, buffer_x: 0, @@ -1323,6 +1312,7 @@ VGAScreen.prototype.update_layers = function() for(var x = -start_split_col, y = 0; x < this.screen_width; x += this.virtual_width, y++) { this.layers.push({ + image_data: this.image_data, screen_x: x, screen_y: split_screen_row, buffer_x: 0, @@ -2440,6 +2430,7 @@ VGAScreen.prototype.screen_fill_buffer = function() var max_y = end_pixel / this.svga_width | 0; this.bus.send("screen-fill-buffer-end", [{ + image_data: this.image_data, screen_x: 0, screen_y: min_y, buffer_x: 0, buffer_y: min_y, buffer_width: this.svga_width,