Browse Source

linux-capture: Support linear SRGB

Well, linear SRGB for screen capture. The window capture path failed to
copy between SRGB textures for some reason, so just force nonlinear
formats instead.
jpark37 4 years ago
parent
commit
33b744270a

+ 4 - 4
plugins/linux-capture/xcompcap-main.cpp

@@ -313,11 +313,11 @@ static gs_color_format gs_format_from_tex()
 	// GS_RGBX format
 	switch (iformat) {
 	case GL_RGB:
-		return GS_BGRX;
+		return GS_BGRX_UNORM;
 	case GL_RGBA:
-		return GS_RGBA;
+		return GS_RGBA_UNORM;
 	default:
-		return GS_RGBA;
+		return GS_RGBA_UNORM;
 	}
 }
 
@@ -513,7 +513,7 @@ void XCompcapMain::updateSettings(obs_data_t *settings)
 	XFree(configs);
 
 	// Build an OBS texture to bind the pixmap to.
-	p->gltex = gs_texture_create(p->width, p->height, GS_RGBA, 1, 0,
+	p->gltex = gs_texture_create(p->width, p->height, GS_RGBA_UNORM, 1, 0,
 				     GS_GL_DUMMYTEX);
 	GLuint gltex = *(GLuint *)gs_texture_get_obj(p->gltex);
 	glBindTexture(GL_TEXTURE_2D, gltex);

+ 11 - 1
plugins/linux-capture/xcursor-xcb.c

@@ -93,9 +93,17 @@ void xcb_xcursor_render(xcb_xcursor_t *data)
 	if (!data->tex)
 		return;
 
+	const bool linear_srgb = gs_get_linear_srgb();
+
+	const bool previous = gs_framebuffer_srgb_enabled();
+	gs_enable_framebuffer_srgb(linear_srgb);
+
 	gs_effect_t *effect = gs_get_effect();
 	gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image");
-	gs_effect_set_texture(image, data->tex);
+	if (linear_srgb)
+		gs_effect_set_texture_srgb(image, data->tex);
+	else
+		gs_effect_set_texture(image, data->tex);
 
 	gs_blend_state_push();
 	gs_blend_function(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA);
@@ -108,6 +116,8 @@ void xcb_xcursor_render(xcb_xcursor_t *data)
 
 	gs_enable_color(true, true, true, true);
 	gs_blend_state_pop();
+
+	gs_enable_framebuffer_srgb(previous);
 }
 
 void xcb_xcursor_offset(xcb_xcursor_t *data, const int x_org, const int y_org)

+ 11 - 1
plugins/linux-capture/xcursor.c

@@ -108,9 +108,17 @@ void xcursor_render(xcursor_t *data, int x_offset, int y_offset)
 	if (!data->tex)
 		return;
 
+	const bool linear_srgb = gs_get_linear_srgb();
+
+	const bool previous = gs_framebuffer_srgb_enabled();
+	gs_enable_framebuffer_srgb(linear_srgb);
+
 	gs_effect_t *effect = gs_get_effect();
 	gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image");
-	gs_effect_set_texture(image, data->tex);
+	if (linear_srgb)
+		gs_effect_set_texture_srgb(image, data->tex);
+	else
+		gs_effect_set_texture(image, data->tex);
 
 	gs_blend_state_push();
 	gs_blend_function(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA);
@@ -124,6 +132,8 @@ void xcursor_render(xcursor_t *data, int x_offset, int y_offset)
 
 	gs_enable_color(true, true, true, true);
 	gs_blend_state_pop();
+
+	gs_enable_framebuffer_srgb(previous);
 }
 
 void xcursor_offset(xcursor_t *data, int_fast32_t x_org, int_fast32_t y_org)

+ 11 - 1
plugins/linux-capture/xshm-input.c

@@ -523,13 +523,23 @@ static void xshm_video_render(void *vptr, gs_effect_t *effect)
 	if (!data->texture)
 		return;
 
+	const bool linear_srgb = gs_get_linear_srgb();
+
+	const bool previous = gs_framebuffer_srgb_enabled();
+	gs_enable_framebuffer_srgb(linear_srgb);
+
 	gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image");
-	gs_effect_set_texture(image, data->texture);
+	if (linear_srgb)
+		gs_effect_set_texture_srgb(image, data->texture);
+	else
+		gs_effect_set_texture(image, data->texture);
 
 	while (gs_effect_loop(effect, "Draw")) {
 		gs_draw_sprite(data->texture, 0, 0, 0);
 	}
 
+	gs_enable_framebuffer_srgb(previous);
+
 	if (data->show_cursor) {
 		effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);