mirror of
https://github.com/Lorenzooone/cc3dsfs.git
synced 2026-03-21 17:55:00 -05:00
Improve FPS on lower end hardware
This commit is contained in:
parent
e9084745b9
commit
83b6dd522a
|
|
@ -51,7 +51,7 @@ struct DisplayData {
|
|||
#pragma pack(push, 1)
|
||||
|
||||
struct PACKED VideoOutputData {
|
||||
uint8_t screen_data[MAX_IN_VIDEO_SIZE][4];
|
||||
uint8_t screen_data[MAX_IN_VIDEO_SIZE][3];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ private:
|
|||
volatile bool scheduled_work_on_window;
|
||||
volatile bool is_thread_done;
|
||||
|
||||
sf::Shader *in_top_shader, *in_bot_shader, *top_shader, *bot_shader;
|
||||
sf::RectangleShape m_in_rect_top, m_in_rect_bot;
|
||||
out_rect_data m_out_rect_top, m_out_rect_bot;
|
||||
ScreenType m_stype;
|
||||
|
|
@ -238,6 +239,7 @@ private:
|
|||
void prepare_screen_rendering();
|
||||
bool window_needs_work();
|
||||
void window_factory(bool is_main_thread);
|
||||
void update_texture();
|
||||
void pre_texture_conversion_processing();
|
||||
void post_texture_conversion_processing(out_rect_data &rect_data, const sf::RectangleShape &in_rect, bool actually_draw, bool is_top, bool is_debug);
|
||||
void window_bg_processing();
|
||||
|
|
|
|||
|
|
@ -265,19 +265,11 @@ void ftd3_capture_cleanup(CaptureData* capture_data) {
|
|||
}
|
||||
|
||||
static inline void convertVideoToOutputChunk(RGB83DSVideoInputData *p_in, VideoOutputData *p_out, int iters, int start_in, int start_out) {
|
||||
for(int i = 0; i < iters; i++) {
|
||||
for(int u = 0; u < 3; u++)
|
||||
p_out->screen_data[start_out + i][u] = p_in->screen_data[start_in + i][u];
|
||||
p_out->screen_data[start_out + i][3] = 0xff;
|
||||
}
|
||||
memcpy(&p_out->screen_data[start_out], &p_in->screen_data[start_in], iters * 3);
|
||||
}
|
||||
|
||||
static inline void convertVideoToOutputChunk_3D(RGB83DSVideoInputData_3D *p_in, VideoOutputData *p_out, int iters, int start_in, int start_out) {
|
||||
for(int i = 0; i < iters; i++) {
|
||||
for(int u = 0; u < 3; u++)
|
||||
p_out->screen_data[start_out + i][u] = p_in->screen_data[start_in + i][u];
|
||||
p_out->screen_data[start_out + i][3] = 0xff;
|
||||
}
|
||||
memcpy(&p_out->screen_data[start_out], &p_in->screen_data[start_in], iters * 3);
|
||||
}
|
||||
|
||||
void ftd3_convertVideoToOutput(CaptureReceived *p_in, VideoOutputData *p_out, bool enabled_3d) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "frontend.hpp"
|
||||
|
||||
#include <SFML/OpenGL.hpp>
|
||||
#include <cstring>
|
||||
#include "font_ttf.h"
|
||||
|
||||
|
|
@ -12,6 +13,17 @@
|
|||
#define FALLBACK_FS_RESOLUTION_HEIGHT 1080
|
||||
#define FALLBACK_FS_RESOLUTION_BPP 32
|
||||
|
||||
const std::string no_effect_fragment_shader = \
|
||||
"uniform sampler2D Texture0;" \
|
||||
"" \
|
||||
"void main() {" \
|
||||
" gl_FragColor = texture2D(Texture0, gl_TexCoord[0].xy);" \
|
||||
"}";
|
||||
|
||||
static bool loaded_shaders = false;
|
||||
static int n_shader_refs = 0;
|
||||
static sf::Shader *base_shader;
|
||||
|
||||
WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, AudioData* audio_data, ExtraButtonShortcuts* extra_button_shortcuts) {
|
||||
this->m_stype = stype;
|
||||
insert_basic_crops(this->possible_crops, this->m_stype, false, false);
|
||||
|
|
@ -55,6 +67,16 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp
|
|||
this->capture_status = capture_status;
|
||||
if(this->display_data->mono_app_mode && this->m_stype == ScreenType::JOINT)
|
||||
this->m_info.is_fullscreen = true;
|
||||
if(!loaded_shaders) {
|
||||
base_shader = new sf::Shader();
|
||||
base_shader->loadFromMemory(no_effect_fragment_shader, sf::Shader::Fragment);
|
||||
loaded_shaders = true;
|
||||
}
|
||||
n_shader_refs += 1;
|
||||
this->in_top_shader = base_shader;
|
||||
this->in_bot_shader = base_shader;
|
||||
this->top_shader = base_shader;
|
||||
this->bot_shader = base_shader;
|
||||
}
|
||||
|
||||
WindowScreen::~WindowScreen() {
|
||||
|
|
@ -66,6 +88,11 @@ WindowScreen::~WindowScreen() {
|
|||
FPSArrayDestroy(&this->in_fps);
|
||||
FPSArrayDestroy(&this->draw_fps);
|
||||
FPSArrayDestroy(&this->poll_fps);
|
||||
if(n_shader_refs == 1) {
|
||||
delete base_shader;
|
||||
loaded_shaders = false;
|
||||
}
|
||||
n_shader_refs -= 1;
|
||||
}
|
||||
|
||||
void WindowScreen::build() {
|
||||
|
|
@ -385,13 +412,28 @@ std::string WindowScreen::title_factory() {
|
|||
return title;
|
||||
}
|
||||
|
||||
void WindowScreen::update_texture() {
|
||||
unsigned int m_texture = this->in_tex.getNativeHandle();
|
||||
if (this->saved_buf && m_texture)
|
||||
{
|
||||
// Copy pixels from the given array to the texture
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, static_cast<GLint>(0), static_cast<GLint>(0), static_cast<GLsizei>(this->capture_status->device.width), static_cast<GLsizei>(this->capture_status->device.height), GL_RGB, GL_UNSIGNED_BYTE, this->saved_buf);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
// Force an OpenGL flush, so that the texture data will appear updated
|
||||
// in all contexts immediately (solves problems in multi-threaded apps)
|
||||
glFlush();
|
||||
}
|
||||
}
|
||||
|
||||
void WindowScreen::pre_texture_conversion_processing() {
|
||||
if(this->loaded_menu == CONNECT_MENU_TYPE)
|
||||
return;
|
||||
//Place preprocessing window-specific effects here
|
||||
if(!this->capture_status->connected)
|
||||
return;
|
||||
this->in_tex.update((uint8_t*)this->saved_buf, this->capture_status->device.width, this->capture_status->device.height, 0, 0);
|
||||
this->update_texture();
|
||||
}
|
||||
|
||||
void WindowScreen::post_texture_conversion_processing(out_rect_data &rect_data, const sf::RectangleShape &in_rect, bool actually_draw, bool is_top, bool is_debug) {
|
||||
|
|
@ -409,7 +451,10 @@ void WindowScreen::post_texture_conversion_processing(out_rect_data &rect_data,
|
|||
else {
|
||||
rect_data.out_tex.clear();
|
||||
if(this->capture_status->connected && actually_draw) {
|
||||
rect_data.out_tex.draw(in_rect);
|
||||
sf::Shader* chosen_shader = this->in_top_shader;
|
||||
if(!is_top)
|
||||
chosen_shader = this->in_bot_shader;
|
||||
rect_data.out_tex.draw(in_rect, chosen_shader);
|
||||
//Place postprocessing effects here
|
||||
}
|
||||
}
|
||||
|
|
@ -431,9 +476,9 @@ void WindowScreen::display_data_to_window(bool actually_draw, bool is_debug) {
|
|||
this->window_bg_processing();
|
||||
if(this->loaded_menu != CONNECT_MENU_TYPE) {
|
||||
if(this->m_stype != ScreenType::BOTTOM)
|
||||
this->m_win.draw(this->m_out_rect_top.out_rect);
|
||||
this->m_win.draw(this->m_out_rect_top.out_rect, this->top_shader);
|
||||
if(this->m_stype != ScreenType::TOP)
|
||||
this->m_win.draw(this->m_out_rect_bot.out_rect);
|
||||
this->m_win.draw(this->m_out_rect_bot.out_rect, this->bot_shader);
|
||||
}
|
||||
this->execute_menu_draws();
|
||||
this->notification->draw(this->m_win);
|
||||
|
|
|
|||
|
|
@ -277,7 +277,6 @@ static inline void usb_oldDSconvertVideoToOutputRGBA(USBOldDSPixelData data, uin
|
|||
target[0] = xbits_to_8bits(data.r, OLD_DS_PIXEL_R_BITS);
|
||||
target[1] = xbits_to_8bits(data.g, OLD_DS_PIXEL_G_BITS);
|
||||
target[2] = xbits_to_8bits(data.b, OLD_DS_PIXEL_B_BITS);
|
||||
target[3] = 255;
|
||||
}
|
||||
|
||||
static inline void usb_oldDSconvertVideoToOutputHalfLine(USBOldDSCaptureReceived *p_in, VideoOutputData *p_out, int input_halfline, int output_halfline) {
|
||||
|
|
@ -292,12 +291,12 @@ static inline void usb_oldDSconvertVideoToOutputHalfLine(USBOldDSCaptureReceived
|
|||
|
||||
static void usb_oldDSconvertVideoToOutput(USBOldDSCaptureReceived *p_in, VideoOutputData *p_out) {
|
||||
if(!p_in->frameinfo.valid) { //LCD was off
|
||||
memset(p_out->screen_data, 0, WIDTH_DS * (2 * HEIGHT_DS) * 4);
|
||||
memset(p_out->screen_data, 0, WIDTH_DS * (2 * HEIGHT_DS) * 3);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle first line being off, if needed
|
||||
memset(p_out->screen_data, 0, WIDTH_DS * 4);
|
||||
memset(p_out->screen_data, 0, WIDTH_DS * 3);
|
||||
|
||||
int input_halfline = 0;
|
||||
for(int i = 0; i < 2; i++) {
|
||||
|
|
@ -309,20 +308,14 @@ static void usb_oldDSconvertVideoToOutput(USBOldDSCaptureReceived *p_in, VideoOu
|
|||
if(p_in->frameinfo.half_line_flags[(i >> 3)] & (1 << (i & 7)))
|
||||
usb_oldDSconvertVideoToOutputHalfLine(p_in, p_out, input_halfline++, i);
|
||||
else { // deal with missing half-line
|
||||
memcpy(p_out->screen_data[i * (WIDTH_DS / 2)], p_out->screen_data[(i - 2) * (WIDTH_DS / 2)], (WIDTH_DS / 2) * 4);
|
||||
memcpy(p_out->screen_data[(i * (WIDTH_DS / 2)) + (WIDTH_DS * HEIGHT_DS)], p_out->screen_data[((i - 2) * (WIDTH_DS / 2)) + (WIDTH_DS * HEIGHT_DS)], (WIDTH_DS / 2) * 4);
|
||||
memcpy(p_out->screen_data[i * (WIDTH_DS / 2)], p_out->screen_data[(i - 2) * (WIDTH_DS / 2)], (WIDTH_DS / 2) * 3);
|
||||
memcpy(p_out->screen_data[(i * (WIDTH_DS / 2)) + (WIDTH_DS * HEIGHT_DS)], p_out->screen_data[((i - 2) * (WIDTH_DS / 2)) + (WIDTH_DS * HEIGHT_DS)], (WIDTH_DS / 2) * 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_3DSconvertVideoToOutput(USB3DSCaptureReceived *p_in, VideoOutputData *p_out) {
|
||||
for(int i = 0; i < IN_VIDEO_HEIGHT_3DS; i++)
|
||||
for(int j = 0; j < IN_VIDEO_WIDTH_3DS; j++) {
|
||||
int pixel = (i * IN_VIDEO_WIDTH_3DS) + j;
|
||||
for(int u = 0; u < 3; u++)
|
||||
p_out->screen_data[pixel][u] = p_in->video_in.screen_data[pixel][u];
|
||||
p_out->screen_data[pixel][3] = 255;
|
||||
}
|
||||
memcpy(p_out->screen_data, p_in->video_in.screen_data, IN_VIDEO_HEIGHT_3DS * IN_VIDEO_WIDTH_3DS * 3);
|
||||
}
|
||||
|
||||
void list_devices_usb_ds_3ds(std::vector<CaptureDevice> &devices_list) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user