diff --git a/src/platform/linux/graphics.cpp b/src/platform/linux/graphics.cpp index b25032b3..ccdf54d4 100644 --- a/src/platform/linux/graphics.cpp +++ b/src/platform/linux/graphics.cpp @@ -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 import_target(display_t::pointer egl_display, std::array &&fds, const surface_descriptor_t &r8, const surface_descriptor_t &gr88) { EGLAttrib img_attr_planes[2][17] { diff --git a/src/platform/linux/graphics.h b/src/platform/linux/graphics.h index ee72c46e..fa658f41 100644 --- a/src/platform/linux/graphics.h +++ b/src/platform/linux/graphics.h @@ -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 import_target( display_t::pointer egl_display, diff --git a/src/platform/linux/vaapi.cpp b/src/platform/linux/vaapi.cpp index f210bba4..085ca7bb 100644 --- a/src/platform/linux/vaapi.cpp +++ b/src/platform/linux/vaapi.cpp @@ -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 {}; diff --git a/src/platform/linux/wlgrab.cpp b/src/platform/linux/wlgrab.cpp index b57b332d..8f3ef299 100644 --- a/src/platform/linux/wlgrab.cpp +++ b/src/platform/linux/wlgrab.cpp @@ -313,6 +313,8 @@ namespace wl { alloc_img() override { auto img = std::make_shared(); + img->width = width; + img->height = height; img->sequence = 0; img->serial = std::numeric_limitsserial)>::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 &img_out) -> bool { - img_out = img->shared_from_this(); - return true; - }; - std::shared_ptr 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 {};