This commit is contained in:
Romain Vimont 2021-02-21 22:07:51 +01:00
commit da44fa4476
3 changed files with 89 additions and 4 deletions

View file

@ -643,6 +643,7 @@ guess_record_format(const char *filename) {
static bool static bool
parse_scale_filter(const char *optarg, enum sc_scale_filter *filter) { parse_scale_filter(const char *optarg, enum sc_scale_filter *filter) {
// TODO store in a map and loop over the entries instead
if (!strcmp(optarg, "none")) { if (!strcmp(optarg, "none")) {
*filter = SC_SCALE_FILTER_NONE; *filter = SC_SCALE_FILTER_NONE;
return true; return true;
@ -651,8 +652,49 @@ parse_scale_filter(const char *optarg, enum sc_scale_filter *filter) {
*filter = SC_SCALE_FILTER_TRILINEAR; *filter = SC_SCALE_FILTER_TRILINEAR;
return true; return true;
} }
if (!strcmp(optarg, "bilinear")) {
*filter = SC_SCALE_FILTER_BILINEAR;
return true;
}
if (!strcmp(optarg, "bicubic")) {
*filter = SC_SCALE_FILTER_BICUBIC;
return true;
}
if (!strcmp(optarg, "x")) {
*filter = SC_SCALE_FILTER_X;
return true;
}
if (!strcmp(optarg, "point")) {
*filter = SC_SCALE_FILTER_POINT;
return true;
}
if (!strcmp(optarg, "area")) {
*filter = SC_SCALE_FILTER_AREA;
return true;
}
if (!strcmp(optarg, "bicublin")) {
*filter = SC_SCALE_FILTER_BICUBLIN;
return true;
}
if (!strcmp(optarg, "gauss")) {
*filter = SC_SCALE_FILTER_GAUSS;
return true;
}
if (!strcmp(optarg, "sinc")) {
*filter = SC_SCALE_FILTER_SINC;
return true;
}
if (!strcmp(optarg, "lanczos")) {
*filter = SC_SCALE_FILTER_LANCZOS;
return true;
}
if (!strcmp(optarg, "spline")) {
*filter = SC_SCALE_FILTER_SPLINE;
return true;
}
LOGE("Unsupported scale filter: %s " LOGE("Unsupported scale filter: %s "
"(expected \"none\" or \"trilinear\")", optarg); "(expected one of [TODO])", optarg);
return false; return false;
} }

View file

@ -213,7 +213,7 @@ create_texture(struct screen *screen) {
return NULL; return NULL;
} }
if (screen->mipmaps) { if (screen->scale_filter == SC_SCALE_FILTER_TRILINEAR) {
struct sc_opengl *gl = &screen->gl; struct sc_opengl *gl = &screen->gl;
SDL_GL_BindTexture(texture, NULL, NULL); SDL_GL_BindTexture(texture, NULL, NULL);
@ -229,6 +229,12 @@ create_texture(struct screen *screen) {
return texture; return texture;
} }
static inline bool
is_swscale(enum sc_scale_filter scale_filter) {
return scale_filter != SC_SCALE_FILTER_NONE
&& scale_filter != SC_SCALE_FILTER_TRILINEAR;
}
bool bool
screen_init_rendering(struct screen *screen, const char *window_title, screen_init_rendering(struct screen *screen, const char *window_title,
struct size frame_size, bool always_on_top, struct size frame_size, bool always_on_top,
@ -301,10 +307,10 @@ screen_init_rendering(struct screen *screen, const char *window_title,
2, 0 /* OpenGL ES 2.0+ */); 2, 0 /* OpenGL ES 2.0+ */);
if (supports_mipmaps) { if (supports_mipmaps) {
LOGI("Trilinear filtering enabled"); LOGI("Trilinear filtering enabled");
screen->mipmaps = true;
} else { } else {
LOGW("Trilinear filtering disabled " LOGW("Trilinear filtering disabled "
"(OpenGL 3.0+ or ES 2.0+ required)"); "(OpenGL 3.0+ or ES 2.0+ required)");
scale_filter = SC_SCALE_FILTER_NONE;
} }
} else { } else {
LOGI("Trilinear filtering disabled"); LOGI("Trilinear filtering disabled");
@ -313,6 +319,29 @@ screen_init_rendering(struct screen *screen, const char *window_title,
LOGD("Trilinear filtering disabled (not an OpenGL renderer)"); LOGD("Trilinear filtering disabled (not an OpenGL renderer)");
} }
screen->use_swscale = is_swscale(scale_filter);
if (screen->use_swscale) {
bool ok = sc_resizer_init(&screen->resizer, screen->vb,
&screen->resizer_vb, scale_filter,
window_size);
if (!ok) {
LOGE("Could not create resizer");
SDL_DestroyRenderer(screen->renderer);
SDL_DestroyWindow(screen->window);
return false;
}
ok = sc_resizer_start(&screen->resizer);
if (!ok) {
LOGE("Could not start resizer");
sc_resizer_destroy(&screen->resizer);
SDL_DestroyRenderer(screen->renderer);
SDL_DestroyWindow(screen->window);
}
}
screen->scale_filter = scale_filter;
SDL_Surface *icon = read_xpm(icon_xpm); SDL_Surface *icon = read_xpm(icon_xpm);
if (icon) { if (icon) {
SDL_SetWindowIcon(screen->window, icon); SDL_SetWindowIcon(screen->window, icon);
@ -348,6 +377,11 @@ screen_show_window(struct screen *screen) {
void void
screen_destroy(struct screen *screen) { screen_destroy(struct screen *screen) {
if (screen->use_swscale) {
sc_resizer_stop(&screen->resizer);
sc_resizer_join(&screen->resizer);
sc_resizer_destroy(&screen->resizer);
}
if (screen->texture) { if (screen->texture) {
SDL_DestroyTexture(screen->texture); SDL_DestroyTexture(screen->texture);
} }
@ -448,7 +482,7 @@ update_texture(struct screen *screen, const AVFrame *frame) {
frame->data[1], frame->linesize[1], frame->data[1], frame->linesize[1],
frame->data[2], frame->linesize[2]); frame->data[2], frame->linesize[2]);
if (screen->mipmaps) { if (screen->scale_filter == SC_SCALE_FILTER_TRILINEAR) {
SDL_GL_BindTexture(screen->texture, NULL, NULL); SDL_GL_BindTexture(screen->texture, NULL, NULL);
screen->gl.GenerateMipmap(GL_TEXTURE_2D); screen->gl.GenerateMipmap(GL_TEXTURE_2D);
SDL_GL_UnbindTexture(screen->texture); SDL_GL_UnbindTexture(screen->texture);

View file

@ -9,7 +9,9 @@
#include "coords.h" #include "coords.h"
#include "opengl.h" #include "opengl.h"
#include "resizer.h"
#include "scrcpy.h" #include "scrcpy.h"
#include "video_buffer.h"
struct video_buffer; struct video_buffer;
@ -37,6 +39,13 @@ struct screen {
bool fullscreen; bool fullscreen;
bool maximized; bool maximized;
bool mipmaps; bool mipmaps;
enum sc_scale_filter scale_filter;
bool use_swscale;
// For swscale resizing
struct video_buffer resizer_vb;
struct sc_resizer resizer;
}; };
// initialize default values // initialize default values