mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-03-29 22:20:24 +00:00
Fix race condition causing hangs and EGL import errors due to concurrent snapshot() calls
This commit is contained in:
parent
0403ad147a
commit
e1771de37a
@ -558,6 +558,36 @@ namespace egl {
|
||||
return rgb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a black RGB texture of the specified image size.
|
||||
* @param img The image to use for texture sizing.
|
||||
* @return The new RGB texture.
|
||||
*/
|
||||
rgb_t
|
||||
create_blank(platf::img_t &img) {
|
||||
rgb_t rgb {
|
||||
EGL_NO_DISPLAY,
|
||||
EGL_NO_IMAGE,
|
||||
gl::tex_t::make(1)
|
||||
};
|
||||
|
||||
gl::ctx.BindTexture(GL_TEXTURE_2D, rgb->tex[0]);
|
||||
gl::ctx.TexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, img.width, img.height);
|
||||
gl::ctx.BindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
auto framebuf = gl::frame_buf_t::make(1);
|
||||
framebuf.bind(&rgb->tex[0], &rgb->tex[0] + 1);
|
||||
|
||||
GLenum attachment = GL_COLOR_ATTACHMENT0;
|
||||
gl::ctx.DrawBuffers(1, &attachment);
|
||||
const GLuint rgb_black[] = { 0, 0, 0, 0 };
|
||||
gl::ctx.ClearBufferuiv(GL_COLOR, 0, rgb_black);
|
||||
|
||||
gl_drain_errors;
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
std::optional<nv12_t>
|
||||
import_target(display_t::pointer egl_display, std::array<file_t, nv12_img_t::num_fds> &&fds, const surface_descriptor_t &r8, const surface_descriptor_t &gr88) {
|
||||
EGLAttrib img_attr_planes[2][17] {
|
||||
|
@ -268,6 +268,9 @@ namespace egl {
|
||||
display_t::pointer egl_display,
|
||||
const surface_descriptor_t &xrgb);
|
||||
|
||||
rgb_t
|
||||
create_blank(platf::img_t &img);
|
||||
|
||||
std::optional<nv12_t>
|
||||
import_target(
|
||||
display_t::pointer egl_display,
|
||||
|
@ -436,7 +436,11 @@ namespace va {
|
||||
convert(platf::img_t &img) override {
|
||||
auto &descriptor = (egl::img_descriptor_t &) img;
|
||||
|
||||
if (descriptor.sequence > sequence) {
|
||||
if (descriptor.sequence == 0) {
|
||||
// For dummy images, use a blank RGB texture instead of importing a DMA-BUF
|
||||
rgb = egl::create_blank(img);
|
||||
}
|
||||
else if (descriptor.sequence > sequence) {
|
||||
sequence = descriptor.sequence;
|
||||
|
||||
rgb = egl::rgb_t {};
|
||||
|
@ -313,6 +313,8 @@ namespace wl {
|
||||
alloc_img() override {
|
||||
auto img = std::make_shared<egl::img_descriptor_t>();
|
||||
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
img->sequence = 0;
|
||||
img->serial = std::numeric_limits<decltype(img->serial)>::max();
|
||||
img->data = nullptr;
|
||||
@ -334,16 +336,8 @@ namespace wl {
|
||||
|
||||
int
|
||||
dummy_img(platf::img_t *img) override {
|
||||
// TODO: stop cheating and give black image
|
||||
if (!img) {
|
||||
return -1;
|
||||
};
|
||||
auto pull_dummy_img_callback = [&img](std::shared_ptr<platf::img_t> &img_out) -> bool {
|
||||
img_out = img->shared_from_this();
|
||||
return true;
|
||||
};
|
||||
std::shared_ptr<platf::img_t> img_out;
|
||||
return snapshot(pull_dummy_img_callback, img_out, 1000ms, false) != platf::capture_e::ok;
|
||||
// Empty images are recognized as dummies by the zero sequence number
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::uint64_t sequence {};
|
||||
|
Loading…
x
Reference in New Issue
Block a user