gles2: Use buffer damage to partially update texture
This commit is contained in:
parent
2019be737f
commit
b675b59e3b
|
@ -29,7 +29,7 @@ use crate::backend::egl::{
|
||||||
use crate::backend::SwapBuffersError;
|
use crate::backend::SwapBuffersError;
|
||||||
|
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
use crate::wayland::compositor::SurfaceAttributes;
|
use crate::wayland::compositor::{SurfaceAttributes, Damage};
|
||||||
#[cfg(feature = "wayland_frontend")]
|
#[cfg(feature = "wayland_frontend")]
|
||||||
use wayland_server::protocol::{wl_buffer, wl_shm};
|
use wayland_server::protocol::{wl_buffer, wl_shm};
|
||||||
|
|
||||||
|
@ -436,6 +436,7 @@ impl Gles2Renderer {
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer: &wl_buffer::WlBuffer,
|
buffer: &wl_buffer::WlBuffer,
|
||||||
cache: &mut Option<Gles2Texture>,
|
cache: &mut Option<Gles2Texture>,
|
||||||
|
mut damage: Option<crate::utils::Rectangle>,
|
||||||
) -> Result<Gles2Texture, Gles2Error> {
|
) -> Result<Gles2Texture, Gles2Error> {
|
||||||
use crate::wayland::shm::with_buffer_contents;
|
use crate::wayland::shm::with_buffer_contents;
|
||||||
|
|
||||||
|
@ -465,6 +466,8 @@ impl Gles2Renderer {
|
||||||
let texture = cache.as_ref().cloned().unwrap_or_else(|| {
|
let texture = cache.as_ref().cloned().unwrap_or_else(|| {
|
||||||
let mut tex = 0;
|
let mut tex = 0;
|
||||||
unsafe { self.gl.GenTextures(1, &mut tex) };
|
unsafe { self.gl.GenTextures(1, &mut tex) };
|
||||||
|
// new texture, upload in full
|
||||||
|
damage = None;
|
||||||
Gles2Texture(Rc::new(Gles2TextureInternal {
|
Gles2Texture(Rc::new(Gles2TextureInternal {
|
||||||
texture: tex,
|
texture: tex,
|
||||||
texture_kind: shader_idx,
|
texture_kind: shader_idx,
|
||||||
|
@ -476,6 +479,11 @@ impl Gles2Renderer {
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// new buffer has a different format, upload in full
|
||||||
|
if shader_idx != texture.0.texture_kind {
|
||||||
|
damage = None;
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
self.gl.BindTexture(ffi::TEXTURE_2D, texture.0.texture);
|
self.gl.BindTexture(ffi::TEXTURE_2D, texture.0.texture);
|
||||||
|
|
||||||
|
@ -484,6 +492,23 @@ impl Gles2Renderer {
|
||||||
self.gl
|
self.gl
|
||||||
.TexParameteri(ffi::TEXTURE_2D, ffi::TEXTURE_WRAP_T, ffi::CLAMP_TO_EDGE as i32);
|
.TexParameteri(ffi::TEXTURE_2D, ffi::TEXTURE_WRAP_T, ffi::CLAMP_TO_EDGE as i32);
|
||||||
self.gl.PixelStorei(ffi::UNPACK_ROW_LENGTH, stride / pixelsize);
|
self.gl.PixelStorei(ffi::UNPACK_ROW_LENGTH, stride / pixelsize);
|
||||||
|
if let Some(region) = damage {
|
||||||
|
self.gl.PixelStorei(ffi::UNPACK_SKIP_PIXELS, region.x);
|
||||||
|
self.gl.PixelStorei(ffi::UNPACK_SKIP_ROWS, region.y);
|
||||||
|
self.gl.TexSubImage2D(
|
||||||
|
ffi::TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
region.x,
|
||||||
|
region.y,
|
||||||
|
region.width,
|
||||||
|
region.height,
|
||||||
|
gl_format,
|
||||||
|
ffi::UNSIGNED_BYTE as u32,
|
||||||
|
slice.as_ptr().offset(offset as isize) as *const _,
|
||||||
|
);
|
||||||
|
self.gl.PixelStorei(ffi::UNPACK_SKIP_PIXELS, 0);
|
||||||
|
self.gl.PixelStorei(ffi::UNPACK_SKIP_ROWS, 0);
|
||||||
|
} else {
|
||||||
self.gl.TexImage2D(
|
self.gl.TexImage2D(
|
||||||
ffi::TEXTURE_2D,
|
ffi::TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
|
@ -495,6 +520,7 @@ impl Gles2Renderer {
|
||||||
ffi::UNSIGNED_BYTE as u32,
|
ffi::UNSIGNED_BYTE as u32,
|
||||||
slice.as_ptr().offset(offset as isize) as *const _,
|
slice.as_ptr().offset(offset as isize) as *const _,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.gl.PixelStorei(ffi::UNPACK_ROW_LENGTH, 0);
|
self.gl.PixelStorei(ffi::UNPACK_ROW_LENGTH, 0);
|
||||||
self.gl.BindTexture(ffi::TEXTURE_2D, 0);
|
self.gl.BindTexture(ffi::TEXTURE_2D, 0);
|
||||||
|
@ -878,7 +904,10 @@ impl Renderer for Gles2Renderer {
|
||||||
};
|
};
|
||||||
self.import_egl(&buffer, egl.unwrap(), buffer_cache, texture_cache)
|
self.import_egl(&buffer, egl.unwrap(), buffer_cache, texture_cache)
|
||||||
} else if crate::wayland::shm::with_buffer_contents(&buffer, |_, _| ()).is_ok() {
|
} else if crate::wayland::shm::with_buffer_contents(&buffer, |_, _| ()).is_ok() {
|
||||||
self.import_shm(&buffer, texture_cache)
|
self.import_shm(&buffer, texture_cache, surface.and_then(|surf| match surf.damage {
|
||||||
|
Damage::Buffer(rect) => Some(rect),
|
||||||
|
_ => None,
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
Err(Gles2Error::UnknownBufferType)
|
Err(Gles2Error::UnknownBufferType)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue