comparison render_fbdev.c @ 1782:b2bffd98063d

Scale H32 horizontally in fbdev backend so it has the correct aspect ratio
author Michael Pavone <pavone@retrodev.com>
date Sun, 10 Mar 2019 23:10:43 -0700
parents 2b4d5cfec6d9
children 8f2e78db0872
comparison
equal deleted inserted replaced
1781:2b4d5cfec6d9 1782:b2bffd98063d
1082 #endif 1082 #endif
1083 static pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER; 1083 static pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER;
1084 static pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER; 1084 static pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER;
1085 static uint8_t buffer_ready; 1085 static uint8_t buffer_ready;
1086 static uint32_t *copy_buffer; 1086 static uint32_t *copy_buffer;
1087 static uint32_t last_width, last_height; 1087 static uint32_t last_width, last_width_scale, last_height;
1088 static uint32_t max_multiple; 1088 static uint32_t max_multiple;
1089 static void do_buffer_copy(void) 1089 static void do_buffer_copy(void)
1090 { 1090 {
1091 uint32_t width_multiple = main_width / last_width; 1091 uint32_t width_multiple = main_width / last_width_scale;
1092 uint32_t height_multiple = main_height / last_height; 1092 uint32_t height_multiple = main_height / last_height;
1093 uint32_t multiple = width_multiple < height_multiple ? width_multiple : height_multiple; 1093 uint32_t multiple = width_multiple < height_multiple ? width_multiple : height_multiple;
1094 if (max_multiple && multiple > max_multiple) { 1094 if (max_multiple && multiple > max_multiple) {
1095 multiple = max_multiple; 1095 multiple = max_multiple;
1096 } 1096 }
1097 uint32_t *cur_line = framebuffer + (main_width - last_width * multiple)/2; 1097 uint32_t *cur_line = framebuffer + (main_width - last_width_scale * multiple)/2;
1098 cur_line += fb_stride * (main_height - last_height * multiple) / (2 * sizeof(uint32_t)); 1098 cur_line += fb_stride * (main_height - last_height * multiple) / (2 * sizeof(uint32_t));
1099 uint32_t *src_line = copy_buffer; 1099 uint32_t *src_line = copy_buffer;
1100 for (uint32_t y = 0; y < last_height; y++) 1100 if (last_width == last_width_scale) {
1101 { 1101 for (uint32_t y = 0; y < last_height; y++)
1102 for (uint32_t i = 0; i < multiple; i++)
1103 { 1102 {
1104 uint32_t *cur = cur_line; 1103 for (uint32_t i = 0; i < multiple; i++)
1105 uint32_t *src = src_line;
1106 for (uint32_t x = 0; x < last_width ; x++)
1107 { 1104 {
1108 uint32_t pixel = *(src++); 1105 uint32_t *cur = cur_line;
1109 for (uint32_t j = 0; j < multiple; j++) 1106 uint32_t *src = src_line;
1107 for (uint32_t x = 0; x < last_width ; x++)
1110 { 1108 {
1111 *(cur++) = pixel; 1109 uint32_t pixel = *(src++);
1110 for (uint32_t j = 0; j < multiple; j++)
1111 {
1112 *(cur++) = pixel;
1113 }
1112 } 1114 }
1113 } 1115
1114 1116 cur_line += fb_stride / sizeof(uint32_t);
1115 cur_line += fb_stride / sizeof(uint32_t); 1117 }
1116 } 1118 src_line += LINEBUF_SIZE;
1117 src_line += LINEBUF_SIZE; 1119 }
1120 } else {
1121 float scale_multiple = ((float)(last_width_scale * multiple)) / (float)last_width;
1122 float remaining = 0.0f;
1123 uint32_t last_pixel = 0;
1124 for (uint32_t y = 0; y < last_height; y++)
1125 {
1126 for (uint32_t i = 0; i < multiple; i++)
1127 {
1128 uint32_t *cur = cur_line;
1129 uint32_t *src = src_line;
1130 for (uint32_t x = 0; x < last_width ; x++)
1131 {
1132 uint32_t pixel = *(src++);
1133 float count = scale_multiple;
1134 if (remaining > 0.0f) {
1135 float a,b,c,d;
1136 a = (last_pixel & 255) * remaining;
1137 b = (last_pixel >> 8 & 255) * remaining;
1138 c = (last_pixel >> 16 & 255) * remaining;
1139 d = (last_pixel >> 24 & 255) * remaining;
1140 remaining = 1.0f - remaining;
1141 a += (pixel & 255) * remaining;
1142 b += (pixel >> 8 & 255) * remaining;
1143 c += (pixel >> 16 & 255) * remaining;
1144 d += (pixel >> 24 & 255) * remaining;
1145 count -= remaining;
1146 uint32_t mixed = ((int)d) << 24 | ((int)c) << 16 | ((int)b) << 8 | ((int)a);
1147 *(cur++) = mixed;
1148 }
1149 for (; count >= 1; count -= 1.0f)
1150 {
1151 *(cur++) = pixel;
1152 }
1153 remaining = count;
1154 last_pixel = pixel;
1155 }
1156
1157 cur_line += fb_stride / sizeof(uint32_t);
1158 }
1159 src_line += LINEBUF_SIZE;
1160 }
1118 } 1161 }
1119 } 1162 }
1120 static void *buffer_copy(void *data) 1163 static void *buffer_copy(void *data)
1121 { 1164 {
1122 pthread_mutex_lock(&buffer_lock); 1165 pthread_mutex_lock(&buffer_lock);
1576 if (max_multiple != 1) { 1619 if (max_multiple != 1) {
1577 if (copy_use_thread) { 1620 if (copy_use_thread) {
1578 pthread_mutex_lock(&buffer_lock); 1621 pthread_mutex_lock(&buffer_lock);
1579 buffer_ready = 1; 1622 buffer_ready = 1;
1580 last_width = width; 1623 last_width = width;
1624 last_width_scale = LINEBUF_SIZE - (overscan_left[video_standard] + overscan_right[video_standard]);
1581 last_height = height; 1625 last_height = height;
1582 copy_buffer = texture_buf + texture_off + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]; 1626 copy_buffer = texture_buf + texture_off + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard];
1583 texture_off = texture_off ? 0 : LINEBUF_SIZE * 512; 1627 texture_off = texture_off ? 0 : LINEBUF_SIZE * 512;
1584 pthread_cond_signal(&buffer_cond); 1628 pthread_cond_signal(&buffer_cond);
1585 pthread_mutex_unlock(&buffer_lock); 1629 pthread_mutex_unlock(&buffer_lock);
1586 } else { 1630 } else {
1587 last_width = width; 1631 last_width = width;
1632 last_width_scale = LINEBUF_SIZE - (overscan_left[video_standard] + overscan_right[video_standard]);
1588 last_height = height; 1633 last_height = height;
1589 copy_buffer = texture_buf + texture_off + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]; 1634 copy_buffer = texture_buf + texture_off + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard];
1590 do_buffer_copy(); 1635 do_buffer_copy();
1591 } 1636 }
1592 } 1637 }