Fix race condition causing hangs and EGL import errors due to concurrent snapshot() calls

This commit is contained in:
Cameron Gutman 2024-01-03 15:42:12 -06:00
parent 0403ad147a
commit e1771de37a
4 changed files with 42 additions and 11 deletions

View File

@ -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] {

View File

@ -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,

View File

@ -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 {};

View File

@ -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 {};