|
@@ -69,11 +69,20 @@ void dc_capture_init(struct dc_capture *capture, int x, int y, uint32_t width,
|
|
|
bih->biHeight = height;
|
|
|
bih->biPlanes = 1;
|
|
|
|
|
|
- capture->hdc = CreateCompatibleDC(NULL);
|
|
|
- capture->bmp =
|
|
|
- CreateDIBSection(capture->hdc, &bi, DIB_RGB_COLORS,
|
|
|
- (void **)&capture->bits, NULL, 0);
|
|
|
- capture->old_bmp = SelectObject(capture->hdc, capture->bmp);
|
|
|
+ const HDC hdc = CreateCompatibleDC(NULL);
|
|
|
+ if (hdc) {
|
|
|
+ const HBITMAP bmp = CreateDIBSection(
|
|
|
+ capture->hdc, &bi, DIB_RGB_COLORS,
|
|
|
+ (void **)&capture->bits, NULL, 0);
|
|
|
+ if (bmp) {
|
|
|
+ capture->hdc = hdc;
|
|
|
+ capture->bmp = bmp;
|
|
|
+ capture->old_bmp = SelectObject(capture->hdc,
|
|
|
+ capture->bmp);
|
|
|
+ } else {
|
|
|
+ DeleteDC(capture->hdc);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -179,48 +188,67 @@ void dc_capture_capture(struct dc_capture *capture, HWND window)
|
|
|
capture->texture_written = true;
|
|
|
}
|
|
|
|
|
|
-static void draw_texture(struct dc_capture *capture, bool texcoords_centered)
|
|
|
+void dc_capture_render(struct dc_capture *capture, bool texcoords_centered)
|
|
|
{
|
|
|
- gs_effect_t *effect = obs_get_base_effect(OBS_EFFECT_OPAQUE);
|
|
|
- gs_technique_t *tech = gs_effect_get_technique(effect, "Draw");
|
|
|
- gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image");
|
|
|
-
|
|
|
- gs_texture_t *texture = capture->texture;
|
|
|
- const bool compatibility = capture->compatibility;
|
|
|
- bool linear_sample = compatibility;
|
|
|
- if (!linear_sample && !texcoords_centered) {
|
|
|
- gs_texture_t *const extra_texture = capture->extra_texture;
|
|
|
- gs_copy_texture(extra_texture, texture);
|
|
|
- texture = extra_texture;
|
|
|
- linear_sample = true;
|
|
|
- }
|
|
|
+ if (capture->valid && capture->texture_written) {
|
|
|
+ gs_texture_t *texture = capture->texture;
|
|
|
+ const bool compatibility = capture->compatibility;
|
|
|
+ bool linear_sample = compatibility;
|
|
|
+ if (!linear_sample && !texcoords_centered) {
|
|
|
+ gs_texture_t *const extra_texture =
|
|
|
+ capture->extra_texture;
|
|
|
+ gs_copy_texture(extra_texture, texture);
|
|
|
+ texture = extra_texture;
|
|
|
+ linear_sample = true;
|
|
|
+ }
|
|
|
|
|
|
- const bool previous = gs_framebuffer_srgb_enabled();
|
|
|
- gs_enable_framebuffer_srgb(linear_sample);
|
|
|
- gs_enable_blending(false);
|
|
|
+ const char *tech_name = "Draw";
|
|
|
+ float multiplier = 1.f;
|
|
|
+ switch (gs_get_color_space()) {
|
|
|
+ case GS_CS_SRGB_16F:
|
|
|
+ case GS_CS_709_EXTENDED:
|
|
|
+ if (!linear_sample)
|
|
|
+ tech_name = "DrawSrgbDecompress";
|
|
|
+ break;
|
|
|
+ case GS_CS_709_SCRGB:
|
|
|
+ if (linear_sample)
|
|
|
+ tech_name = "DrawMultiply";
|
|
|
+ else
|
|
|
+ tech_name = "DrawSrgbDecompressMultiply";
|
|
|
+ multiplier = obs_get_video_sdr_white_level() / 80.f;
|
|
|
+ }
|
|
|
|
|
|
- if (linear_sample)
|
|
|
- gs_effect_set_texture_srgb(image, texture);
|
|
|
- else
|
|
|
- gs_effect_set_texture(image, texture);
|
|
|
+ gs_effect_t *effect = obs_get_base_effect(OBS_EFFECT_OPAQUE);
|
|
|
+ gs_technique_t *tech =
|
|
|
+ gs_effect_get_technique(effect, tech_name);
|
|
|
+ gs_eparam_t *image =
|
|
|
+ gs_effect_get_param_by_name(effect, "image");
|
|
|
|
|
|
- const uint32_t flip = compatibility ? GS_FLIP_V : 0;
|
|
|
- const size_t passes = gs_technique_begin(tech);
|
|
|
- for (size_t i = 0; i < passes; i++) {
|
|
|
- if (gs_technique_begin_pass(tech, i)) {
|
|
|
- gs_draw_sprite(texture, flip, 0, 0);
|
|
|
+ const bool previous = gs_framebuffer_srgb_enabled();
|
|
|
+ gs_enable_framebuffer_srgb(linear_sample);
|
|
|
+ gs_enable_blending(false);
|
|
|
|
|
|
- gs_technique_end_pass(tech);
|
|
|
- }
|
|
|
- }
|
|
|
- gs_technique_end(tech);
|
|
|
+ if (linear_sample)
|
|
|
+ gs_effect_set_texture_srgb(image, texture);
|
|
|
+ else
|
|
|
+ gs_effect_set_texture(image, texture);
|
|
|
|
|
|
- gs_enable_blending(true);
|
|
|
- gs_enable_framebuffer_srgb(previous);
|
|
|
-}
|
|
|
+ gs_eparam_t *multiplier_param =
|
|
|
+ gs_effect_get_param_by_name(effect, "multiplier");
|
|
|
+ gs_effect_set_float(multiplier_param, multiplier);
|
|
|
|
|
|
-void dc_capture_render(struct dc_capture *capture, bool texcoords_centered)
|
|
|
-{
|
|
|
- if (capture->valid && capture->texture_written)
|
|
|
- draw_texture(capture, texcoords_centered);
|
|
|
+ const uint32_t flip = compatibility ? GS_FLIP_V : 0;
|
|
|
+ const size_t passes = gs_technique_begin(tech);
|
|
|
+ for (size_t i = 0; i < passes; i++) {
|
|
|
+ if (gs_technique_begin_pass(tech, i)) {
|
|
|
+ gs_draw_sprite(texture, flip, 0, 0);
|
|
|
+
|
|
|
+ gs_technique_end_pass(tech);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ gs_technique_end(tech);
|
|
|
+
|
|
|
+ gs_enable_blending(true);
|
|
|
+ gs_enable_framebuffer_srgb(previous);
|
|
|
+ }
|
|
|
}
|