mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-23 04:33:24 +00:00
Enable multiple depths in fullscreen DGA modes, i.e. add 1-bit to 16/32-bit
blitters, rewrite update_display_dga_vosf() to actually work with sub byte pixels. Factor out update_display_window_vosf() since it's long time that it is no longer checking for first column and last column that have changed.
This commit is contained in:
parent
f9e3fd28a1
commit
e8ac4897b6
@ -344,9 +344,25 @@ static void Blit_Expand_4_To_8(uint8 * dest, const uint8 * p, uint32 length)
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- 2/4/8-bit indexed to 16-bit mode color expansion --- */
|
||||
/* --- 1/2/4/8-bit indexed to 16-bit mode color expansion --- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void Blit_Expand_1_To_16(uint8 * dest, const uint8 * p, uint32 length)
|
||||
{
|
||||
uint16 *q = (uint16 *)dest;
|
||||
for (uint32 i=0; i<length; i++) {
|
||||
uint8 c = *p++;
|
||||
*q++ = -(c >> 7);
|
||||
*q++ = -((c >> 6) & 1);
|
||||
*q++ = -((c >> 5) & 1);
|
||||
*q++ = -((c >> 4) & 1);
|
||||
*q++ = -((c >> 3) & 1);
|
||||
*q++ = -((c >> 2) & 1);
|
||||
*q++ = -((c >> 1) & 1);
|
||||
*q++ = -(c & 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void Blit_Expand_2_To_16(uint8 * dest, const uint8 * p, uint32 length)
|
||||
{
|
||||
uint16 *q = (uint16 *)dest;
|
||||
@ -377,9 +393,25 @@ static void Blit_Expand_8_To_16(uint8 * dest, const uint8 * p, uint32 length)
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- 2/4/8-bit indexed to 32-bit mode color expansion --- */
|
||||
/* --- 1/2/4/8-bit indexed to 32-bit mode color expansion --- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void Blit_Expand_1_To_32(uint8 * dest, const uint8 * p, uint32 length)
|
||||
{
|
||||
uint32 *q = (uint32 *)dest;
|
||||
for (uint32 i=0; i<length; i++) {
|
||||
uint8 c = *p++;
|
||||
*q++ = -(c >> 7);
|
||||
*q++ = -((c >> 6) & 1);
|
||||
*q++ = -((c >> 5) & 1);
|
||||
*q++ = -((c >> 4) & 1);
|
||||
*q++ = -((c >> 3) & 1);
|
||||
*q++ = -((c >> 2) & 1);
|
||||
*q++ = -((c >> 1) & 1);
|
||||
*q++ = -(c & 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void Blit_Expand_2_To_32(uint8 * dest, const uint8 * p, uint32 length)
|
||||
{
|
||||
uint32 *q = (uint32 *)dest;
|
||||
@ -466,9 +498,9 @@ bool Screen_blitter_init(VisualFormat const & visual_format, bool native_byte_or
|
||||
const bool use_sdl_video = false;
|
||||
#endif
|
||||
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
||||
if (!use_sdl_video && mac_depth == 1) {
|
||||
if (mac_depth == 1 && !use_sdl_video && !visual_format.fullscreen) {
|
||||
|
||||
// 1-bit mode uses a 1-bit X image, so there's no need for special blitting routines
|
||||
// Windowed 1-bit mode uses a 1-bit X image, so there's no need for special blitting routines
|
||||
Screen_blit = Blit_Copy_Raw;
|
||||
|
||||
} else {
|
||||
@ -498,6 +530,7 @@ bool Screen_blitter_init(VisualFormat const & visual_format, bool native_byte_or
|
||||
case 15:
|
||||
case 16:
|
||||
switch (mac_depth) {
|
||||
case 1: Screen_blit = Blit_Expand_1_To_16; break;
|
||||
case 2: Screen_blit = Blit_Expand_2_To_16; break;
|
||||
case 4: Screen_blit = Blit_Expand_4_To_16; break;
|
||||
case 8: Screen_blit = Blit_Expand_8_To_16; break;
|
||||
@ -506,6 +539,7 @@ bool Screen_blitter_init(VisualFormat const & visual_format, bool native_byte_or
|
||||
case 24:
|
||||
case 32:
|
||||
switch (mac_depth) {
|
||||
case 1: Screen_blit = Blit_Expand_1_To_32; break;
|
||||
case 2: Screen_blit = Blit_Expand_2_To_32; break;
|
||||
case 4: Screen_blit = Blit_Expand_4_To_32; break;
|
||||
case 8: Screen_blit = Blit_Expand_8_To_32; break;
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
// Format of the target visual
|
||||
struct VisualFormat {
|
||||
bool fullscreen; // Full screen mode?
|
||||
int depth; // Screen depth
|
||||
uint32 Rmask, Gmask, Bmask; // RGB mask values
|
||||
uint32 Rshift, Gshift, Bshift; // RGB shift values
|
||||
|
@ -60,6 +60,7 @@
|
||||
|
||||
// Variables for Video on SEGV support
|
||||
static uint8 *the_host_buffer; // Host frame buffer in VOSF mode
|
||||
static uint32 the_host_buffer_row_bytes; // Host frame buffer number of bytes per row
|
||||
|
||||
struct ScreenPageInfo {
|
||||
int top, bottom; // Mapping between this virtual page and Mac scanlines
|
||||
@ -393,35 +394,16 @@ static inline void update_display_window_vosf(VIDEO_DRV_INIT)
|
||||
const int y2 = mainBuffer.pageInfo[page - 1].bottom;
|
||||
const int height = y2 - y1 + 1;
|
||||
|
||||
// Update the_host_buffer
|
||||
VIDEO_DRV_LOCK_PIXELS;
|
||||
|
||||
if ((int)VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) {
|
||||
|
||||
// Update the_host_buffer and copy of the_buffer
|
||||
const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES;
|
||||
const int dst_bytes_per_row = VIDEO_DRV_ROW_BYTES;
|
||||
const int pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row;
|
||||
int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j;
|
||||
for (j = y1; j <= y2; j++) {
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, VIDEO_MODE_X / pixels_per_byte);
|
||||
i1 += src_bytes_per_row;
|
||||
i2 += dst_bytes_per_row;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Update the_host_buffer and copy of the_buffer
|
||||
const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES;
|
||||
const int dst_bytes_per_row = VIDEO_DRV_ROW_BYTES;
|
||||
const int bytes_per_pixel = src_bytes_per_row / VIDEO_MODE_X;
|
||||
int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j;
|
||||
for (j = y1; j <= y2; j++) {
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, bytes_per_pixel * VIDEO_MODE_X);
|
||||
i1 += src_bytes_per_row;
|
||||
i2 += dst_bytes_per_row;
|
||||
}
|
||||
const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES;
|
||||
const int dst_bytes_per_row = VIDEO_DRV_ROW_BYTES;
|
||||
int i1 = y1 * src_bytes_per_row, i2 = y1 * dst_bytes_per_row, j;
|
||||
for (j = y1; j <= y2; j++) {
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, src_bytes_per_row);
|
||||
i1 += src_bytes_per_row;
|
||||
i2 += dst_bytes_per_row;
|
||||
}
|
||||
|
||||
VIDEO_DRV_UNLOCK_PIXELS;
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
@ -447,7 +429,9 @@ static inline void update_display_dga_vosf(void)
|
||||
{
|
||||
VIDEO_MODE_INIT;
|
||||
|
||||
int i, j;
|
||||
int page = 0;
|
||||
|
||||
for (;;) {
|
||||
const unsigned first_page = find_next_page_set(page);
|
||||
if (first_page >= mainBuffer.pageCount)
|
||||
@ -464,48 +448,73 @@ static inline void update_display_dga_vosf(void)
|
||||
// I am sure that y2 >= y1 and depth != 1
|
||||
const int y1 = mainBuffer.pageInfo[first_page].top;
|
||||
const int y2 = mainBuffer.pageInfo[page - 1].bottom;
|
||||
|
||||
|
||||
// Check for first chunk from left and first chunk from right that have changed
|
||||
typedef uint64 chunk_t;
|
||||
const int chunk_size = sizeof(chunk_t);
|
||||
const int bytes_per_row = VIDEO_MODE_ROW_BYTES;
|
||||
const int bytes_per_pixel = VIDEO_MODE_ROW_BYTES / VIDEO_MODE_X;
|
||||
int i, j;
|
||||
|
||||
// Check for first column from left and first column
|
||||
// from right that have changed
|
||||
int x1 = VIDEO_MODE_X * bytes_per_pixel - 1;
|
||||
assert((bytes_per_row % chunk_size) == 0);
|
||||
|
||||
int b1 = bytes_per_row / chunk_size;
|
||||
for (j = y1; j <= y2; j++) {
|
||||
uint8 * const p1 = &the_buffer[j * bytes_per_row];
|
||||
uint8 * const p2 = &the_buffer_copy[j * bytes_per_row];
|
||||
for (i = 0; i < x1; i++) {
|
||||
chunk_t * const p1 = (chunk_t *)(the_buffer + (j * bytes_per_row));
|
||||
chunk_t * const p2 = (chunk_t *)(the_buffer_copy + (j * bytes_per_row));
|
||||
for (i = 0; i < b1; i++) {
|
||||
if (p1[i] != p2[i]) {
|
||||
x1 = i;
|
||||
b1 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
x1 /= bytes_per_pixel;
|
||||
|
||||
int x2 = x1 * bytes_per_pixel;
|
||||
|
||||
int b2 = b1;
|
||||
for (j = y2; j >= y1; j--) {
|
||||
uint8 * const p1 = &the_buffer[j * bytes_per_row];
|
||||
uint8 * const p2 = &the_buffer_copy[j * bytes_per_row];
|
||||
for (i = VIDEO_MODE_X * bytes_per_pixel - 1; i > x2; i--) {
|
||||
chunk_t * const p1 = (chunk_t *)(the_buffer + (j * bytes_per_row));
|
||||
chunk_t * const p2 = (chunk_t *)(the_buffer_copy + (j * bytes_per_row));
|
||||
for (i = (bytes_per_row / chunk_size) - 1; i > b2; i--) {
|
||||
if (p1[i] != p2[i]) {
|
||||
x2 = i;
|
||||
b2 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
x2 /= bytes_per_pixel;
|
||||
|
||||
b2++;
|
||||
|
||||
// Convert to pixel information
|
||||
int x1, x2;
|
||||
switch (VIDEO_MODE_DEPTH) {
|
||||
case VIDEO_DEPTH_1BIT: x1 = (b1 * chunk_size) << 3; x2 = (b2 * chunk_size) << 3; break;
|
||||
case VIDEO_DEPTH_2BIT: x1 = (b1 * chunk_size) << 2; x2 = (b2 * chunk_size) << 2; break;
|
||||
case VIDEO_DEPTH_4BIT: x1 = (b1 * chunk_size) << 1; x2 = (b2 * chunk_size) << 1; break;
|
||||
case VIDEO_DEPTH_8BIT: x1 = b1 * chunk_size; x2 = b2 * chunk_size; break;
|
||||
case VIDEO_DEPTH_16BIT: x1 = (b1 * chunk_size) >> 1; x2 = (b2 * chunk_size) >> 1; break;
|
||||
case VIDEO_DEPTH_32BIT: x1 = (b1 * chunk_size) >> 2; x2 = (b2 * chunk_size) >> 2; break;
|
||||
}
|
||||
const int width = x2 - x1;
|
||||
|
||||
// Normalize bounds for for the next blit
|
||||
const int src_bytes_per_row = VIDEO_MODE_ROW_BYTES;
|
||||
const int dst_bytes_per_row = the_host_buffer_row_bytes;
|
||||
const int dst_bytes_per_pixel = dst_bytes_per_row / VIDEO_MODE_X;
|
||||
int i2 = y1 * dst_bytes_per_row + x1 * dst_bytes_per_pixel;
|
||||
int i1, n_bytes;
|
||||
if ((int)VIDEO_MODE_DEPTH < VIDEO_DEPTH_8BIT) {
|
||||
const int src_pixels_per_byte = VIDEO_MODE_X / src_bytes_per_row;
|
||||
i1 = y1 * src_bytes_per_row + x1 / src_pixels_per_byte;
|
||||
n_bytes = width / src_pixels_per_byte;
|
||||
} else {
|
||||
const int src_bytes_per_pixel = src_bytes_per_row / VIDEO_MODE_X;
|
||||
i1 = y1 * src_bytes_per_row + x1 * src_bytes_per_pixel;
|
||||
n_bytes = width * src_bytes_per_pixel;
|
||||
}
|
||||
|
||||
// Update the_host_buffer and copy of the_buffer
|
||||
// There should be at least one pixel to copy
|
||||
VIDEO_DRV_LOCK_PIXELS;
|
||||
const int width = x2 - x1 + 1;
|
||||
i = y1 * bytes_per_row + x1 * bytes_per_pixel;
|
||||
for (j = y1; j <= y2; j++) {
|
||||
Screen_blit(the_host_buffer + i, the_buffer + i, bytes_per_pixel * width);
|
||||
memcpy(the_buffer_copy + i, the_buffer + i, bytes_per_pixel * width);
|
||||
i += bytes_per_row;
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, n_bytes);
|
||||
memcpy(the_buffer_copy + i1, the_buffer + i1, n_bytes);
|
||||
i1 += src_bytes_per_row;
|
||||
i2 += dst_bytes_per_row;
|
||||
}
|
||||
VIDEO_DRV_UNLOCK_PIXELS;
|
||||
}
|
||||
|
@ -735,7 +735,8 @@ driver_window::driver_window(X11_monitor_desc &m)
|
||||
use_vosf = true;
|
||||
// Allocate memory for frame buffer (SIZE is extended to page-boundary)
|
||||
the_host_buffer = the_buffer_copy;
|
||||
the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line);
|
||||
the_host_buffer_row_bytes = img->bytes_per_line;
|
||||
the_buffer_size = page_extend((aligned_height + 2) * the_host_buffer_row_bytes);
|
||||
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size);
|
||||
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
|
||||
D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
|
||||
@ -1130,7 +1131,8 @@ driver_fbdev::driver_fbdev(X11_monitor_desc &m) : driver_dga(m)
|
||||
if (use_vosf) {
|
||||
// Allocate memory for frame buffer (SIZE is extended to page-boundary)
|
||||
the_host_buffer = the_buffer;
|
||||
the_buffer_size = page_extend((height + 2) * bytes_per_row);
|
||||
the_host_buffer_row_bytes = bytes_per_row;
|
||||
the_buffer_size = page_extend((height + 2) * the_host_buffer_row_bytes);
|
||||
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
|
||||
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size);
|
||||
}
|
||||
@ -1270,7 +1272,8 @@ driver_xf86dga::driver_xf86dga(X11_monitor_desc &m)
|
||||
if (use_vosf) {
|
||||
// Allocate memory for frame buffer (SIZE is extended to page-boundary)
|
||||
the_host_buffer = the_buffer;
|
||||
the_buffer_size = page_extend((height + 2) * bytes_per_row);
|
||||
the_host_buffer_row_bytes = bytes_per_row;
|
||||
the_buffer_size = page_extend((height + 2) * the_host_buffer_row_bytes);
|
||||
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
|
||||
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size);
|
||||
}
|
||||
@ -1412,6 +1415,7 @@ bool X11_monitor_desc::video_open(void)
|
||||
}
|
||||
|
||||
// Build up visualFormat structure
|
||||
visualFormat.fullscreen = (display_type == DISPLAY_DGA);
|
||||
visualFormat.depth = visualInfo.depth;
|
||||
visualFormat.Rmask = visualInfo.red_mask;
|
||||
visualFormat.Gmask = visualInfo.green_mask;
|
||||
|
Loading…
Reference in New Issue
Block a user