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:
gbeauche 2005-03-28 16:14:25 +00:00
parent f9e3fd28a1
commit e8ac4897b6
4 changed files with 108 additions and 60 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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;