Fix multi-monitor setup with KMSgrab

This commit is contained in:
loki 2021-09-04 18:16:36 +02:00
parent 4ca2c0e740
commit d73a4a38e5
2 changed files with 39 additions and 11 deletions

View File

@ -69,6 +69,13 @@ frame_buf_t frame_buf_t::make(std::size_t count) {
return frame_buf;
}
void frame_buf_t::copy(int id, int texture, int offset_x, int offset_y, int width, int height) {
gl::ctx.BindFramebuffer(GL_FRAMEBUFFER, (*this)[id]);
gl::ctx.ReadBuffer(GL_COLOR_ATTACHMENT0 + id);
gl::ctx.BindTexture(GL_TEXTURE_2D, texture);
gl::ctx.CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, offset_x, offset_y, width, height);
}
std::string shader_t::err_str() {
int length;
ctx.GetShaderiv(handle(), GL_INFO_LOG_LENGTH, &length);
@ -730,19 +737,37 @@ void sws_t::load_ram(platf::img_t &img) {
gl::ctx.TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.width, img.height, GL_BGRA, GL_UNSIGNED_BYTE, img.data);
}
void sws_t::load_vram(cursor_t &img, int offset_x, int offset_y, int texture) {
if(img.data) {
void sws_t::load_vram(img_descriptor_t &img, int offset_x, int offset_y, int texture) {
// When only a sub-part of the image must be encoded...
const bool copy = offset_x || offset_y || img.sd.width != in_width || img.sd.height != in_height;
if(copy) {
auto framebuf = gl::frame_buf_t::make(1);
framebuf.bind(&texture, &texture + 1);
loaded_texture = tex[0];
framebuf.copy(0, loaded_texture, offset_x, offset_y, in_width, in_height);
}
else {
loaded_texture = texture;
}
if(img.data) {
GLenum attachment = GL_COLOR_ATTACHMENT0;
gl::ctx.BindTexture(GL_TEXTURE_2D, texture);
gl::ctx.BindFramebuffer(GL_FRAMEBUFFER, cursor_framebuffer[0]);
gl::ctx.UseProgram(program[2].handle());
// When a copy has already been made...
if(!copy) {
gl::ctx.BindTexture(GL_TEXTURE_2D, texture);
gl::ctx.DrawBuffers(1, &attachment);
gl::ctx.UseProgram(program[2].handle());
gl::ctx.Viewport(offset_x, offset_y, in_width, in_height);
gl::ctx.Viewport(0, 0, in_width, in_height);
gl::ctx.DrawArrays(GL_TRIANGLES, 0, 3);
loaded_texture = tex[0];
}
gl::ctx.BindTexture(GL_TEXTURE_2D, tex[1]);
if(serial != img.serial) {
serial = img.serial;
@ -770,9 +795,6 @@ void sws_t::load_vram(cursor_t &img, int offset_x, int offset_y, int texture) {
gl::ctx.BindTexture(GL_TEXTURE_2D, 0);
gl::ctx.BindFramebuffer(GL_FRAMEBUFFER, 0);
}
else {
loaded_texture = texture;
}
}
int sws_t::convert(nv12_t &nv12) {

View File

@ -80,6 +80,11 @@ public:
++x;
});
}
/**
* Copies a part of the framebuffer to texture
*/
void copy(int id, int texture, int offset_x, int offset_y, int width, int height);
};
class shader_t {
@ -275,7 +280,7 @@ public:
int convert(nv12_t &nv12);
void load_ram(platf::img_t &img);
void load_vram(cursor_t &img, int offset_x, int offset_y, int texture);
void load_vram(img_descriptor_t &img, int offset_x, int offset_y, int texture);
void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range);
@ -285,6 +290,7 @@ public:
// The cursor image will be blended into this framebuffer
gl::frame_buf_t cursor_framebuffer;
gl::frame_buf_t copy_framebuffer;
// Y - shader, UV - shader, Cursor - shader
gl::program_t program[3];