Merge pull request #731 from mahkoh/jorth/fix-ctx-change
gfx: handle context change when buffer is attached to multiple surfaces
This commit is contained in:
commit
75e56bb8c0
11 changed files with 119 additions and 102 deletions
|
|
@ -7,6 +7,7 @@ use {
|
||||||
clm::{CL_CHANGED_DESTROYED, CL_CHANGED_NEW, ClMatcherChange},
|
clm::{CL_CHANGED_DESTROYED, CL_CHANGED_NEW, ClMatcherChange},
|
||||||
},
|
},
|
||||||
ifs::{
|
ifs::{
|
||||||
|
wl_buffer::WlBuffer,
|
||||||
wl_display::WlDisplay,
|
wl_display::WlDisplay,
|
||||||
wl_registry::WlRegistry,
|
wl_registry::WlRegistry,
|
||||||
wl_surface::{WlSurface, commit_timeline::CommitTimelines},
|
wl_surface::{WlSurface, commit_timeline::CommitTimelines},
|
||||||
|
|
@ -21,6 +22,7 @@ use {
|
||||||
buffd::{MsgFormatter, MsgParser, MsgParserError, OutBufferSwapchain},
|
buffd::{MsgFormatter, MsgParser, MsgParserError, OutBufferSwapchain},
|
||||||
copyhashmap::{CopyHashMap, Locked},
|
copyhashmap::{CopyHashMap, Locked},
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
|
event_listener::EventSource,
|
||||||
numcell::NumCell,
|
numcell::NumCell,
|
||||||
pending_serial::PendingSerial,
|
pending_serial::PendingSerial,
|
||||||
pid_info::{PidInfo, get_pid_info, get_socket_creds},
|
pid_info::{PidInfo, get_pid_info, get_socket_creds},
|
||||||
|
|
@ -194,6 +196,7 @@ impl Clients {
|
||||||
changed_properties: Default::default(),
|
changed_properties: Default::default(),
|
||||||
destroyed: Default::default(),
|
destroyed: Default::default(),
|
||||||
acceptor: acceptor.clone(),
|
acceptor: acceptor.clone(),
|
||||||
|
gfx_ctx_changed: Default::default(),
|
||||||
});
|
});
|
||||||
track!(data, data);
|
track!(data, data);
|
||||||
global.update_capabilities(&data, bounding_caps, set_bounding_caps_for_children);
|
global.update_capabilities(&data, bounding_caps, set_bounding_caps_for_children);
|
||||||
|
|
@ -321,6 +324,7 @@ pub struct Client {
|
||||||
pub changed_properties: Cell<ClMatcherChange>,
|
pub changed_properties: Cell<ClMatcherChange>,
|
||||||
pub destroyed: CopyHashMap<CritMatcherId, Weak<dyn CritDestroyListener<Rc<Self>>>>,
|
pub destroyed: CopyHashMap<CritMatcherId, Weak<dyn CritDestroyListener<Rc<Self>>>>,
|
||||||
pub acceptor: Rc<AcceptorMetadata>,
|
pub acceptor: Rc<AcceptorMetadata>,
|
||||||
|
pub gfx_ctx_changed: EventSource<WlBuffer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const NUM_CACHED_SERIAL_RANGES: usize = 64;
|
pub const NUM_CACHED_SERIAL_RANGES: usize = 64;
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ pub enum QueueTransfer {
|
||||||
pub enum VulkanImageMemory {
|
pub enum VulkanImageMemory {
|
||||||
DmaBuf(VulkanDmaBufImage),
|
DmaBuf(VulkanDmaBufImage),
|
||||||
Internal(VulkanShmImage),
|
Internal(VulkanShmImage),
|
||||||
Blend(#[expect(dead_code)] VulkanAllocation),
|
Blend(VulkanAllocation),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VulkanDmaBufImage {
|
pub struct VulkanDmaBufImage {
|
||||||
|
|
|
||||||
|
|
@ -2117,6 +2117,18 @@ impl Debug for VulkanRenderer {
|
||||||
impl VulkanImage {
|
impl VulkanImage {
|
||||||
fn assert_device(&self, device: &Device) -> Result<(), VulkanError> {
|
fn assert_device(&self, device: &Device) -> Result<(), VulkanError> {
|
||||||
if self.renderer.device.device.handle() != device.handle() {
|
if self.renderer.device.device.handle() != device.handle() {
|
||||||
|
match &self.ty {
|
||||||
|
VulkanImageMemory::DmaBuf(v) => {
|
||||||
|
log::warn!("Mixed device use with dmabuf {}", v.template.dmabuf.id);
|
||||||
|
}
|
||||||
|
VulkanImageMemory::Internal(_v) => {
|
||||||
|
log::warn!("Mixed device use with internal image");
|
||||||
|
}
|
||||||
|
VulkanImageMemory::Blend(_v) => {
|
||||||
|
log::warn!("Mixed device use with blend buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log::info!("Image address {:?}", ptr::from_ref(self));
|
||||||
return Err(VulkanError::MixedVulkanDeviceUse);
|
return Err(VulkanError::MixedVulkanDeviceUse);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use {
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
rect::{Rect, Region},
|
rect::{Rect, Region},
|
||||||
utils::{errorfmt::ErrorFmt, page_size::page_size},
|
utils::{errorfmt::ErrorFmt, event_listener::EventListener, page_size::page_size},
|
||||||
video::{
|
video::{
|
||||||
LINEAR_MODIFIER,
|
LINEAR_MODIFIER,
|
||||||
dmabuf::{DmaBuf, DmaBufPlane},
|
dmabuf::{DmaBuf, DmaBufPlane},
|
||||||
|
|
@ -61,6 +61,7 @@ pub struct WlBuffer {
|
||||||
pub color: Option<[u32; 4]>,
|
pub color: Option<[u32; 4]>,
|
||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
|
gfx_ctx_changed: EventListener<WlBuffer>,
|
||||||
pub tracker: Tracker<Self>,
|
pub tracker: Tracker<Self>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,16 +74,18 @@ impl WlBuffer {
|
||||||
self.shm
|
self.shm
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_dmabuf(
|
fn new(
|
||||||
id: WlBufferId,
|
id: WlBufferId,
|
||||||
client: &Rc<Client>,
|
client: &Rc<Client>,
|
||||||
format: &'static Format,
|
format: &'static Format,
|
||||||
dmabuf: DmaBuf,
|
width: i32,
|
||||||
img: &Rc<dyn GfxImage>,
|
height: i32,
|
||||||
) -> Self {
|
dmabuf: Option<DmaBuf>,
|
||||||
let width = img.width();
|
storage: Option<WlBufferStorage>,
|
||||||
let height = img.height();
|
shm: bool,
|
||||||
Self {
|
color: Option<[u32; 4]>,
|
||||||
|
) -> Rc<Self> {
|
||||||
|
let slf = Rc::new_cyclic(|slf| Self {
|
||||||
id,
|
id,
|
||||||
destroyed: Cell::new(false),
|
destroyed: Cell::new(false),
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
|
|
@ -90,17 +93,40 @@ impl WlBuffer {
|
||||||
format,
|
format,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
dmabuf: Some(dmabuf),
|
dmabuf,
|
||||||
render_ctx_version: Cell::new(client.state.render_ctx_version.get()),
|
render_ctx_version: Cell::new(client.state.render_ctx_version.get()),
|
||||||
storage: RefCell::new(Some(WlBufferStorage::Dmabuf {
|
storage: RefCell::new(storage),
|
||||||
|
shm,
|
||||||
|
tracker: Default::default(),
|
||||||
|
color,
|
||||||
|
gfx_ctx_changed: EventListener::new(slf.clone()),
|
||||||
|
});
|
||||||
|
slf.gfx_ctx_changed.attach(&client.gfx_ctx_changed);
|
||||||
|
slf
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_dmabuf(
|
||||||
|
id: WlBufferId,
|
||||||
|
client: &Rc<Client>,
|
||||||
|
format: &'static Format,
|
||||||
|
dmabuf: DmaBuf,
|
||||||
|
img: &Rc<dyn GfxImage>,
|
||||||
|
) -> Rc<Self> {
|
||||||
|
Self::new(
|
||||||
|
id,
|
||||||
|
client,
|
||||||
|
format,
|
||||||
|
img.width(),
|
||||||
|
img.height(),
|
||||||
|
Some(dmabuf),
|
||||||
|
Some(WlBufferStorage::Dmabuf {
|
||||||
img: img.clone(),
|
img: img.clone(),
|
||||||
tex: None,
|
tex: None,
|
||||||
fb: None,
|
fb: None,
|
||||||
})),
|
}),
|
||||||
shm: false,
|
false,
|
||||||
tracker: Default::default(),
|
None,
|
||||||
color: None,
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments)]
|
||||||
|
|
@ -114,7 +140,7 @@ impl WlBuffer {
|
||||||
format: &'static Format,
|
format: &'static Format,
|
||||||
mem: &Rc<ClientMem>,
|
mem: &Rc<ClientMem>,
|
||||||
udmabuf: Option<(&Rc<OwnedFd>, usize)>,
|
udmabuf: Option<(&Rc<OwnedFd>, usize)>,
|
||||||
) -> Result<Self, WlBufferError> {
|
) -> Result<Rc<Self>, WlBufferError> {
|
||||||
let bytes = stride as u64 * height as u64;
|
let bytes = stride as u64 * height as u64;
|
||||||
let required = bytes + offset as u64;
|
let required = bytes + offset as u64;
|
||||||
if required > mem.len() as u64 {
|
if required > mem.len() as u64 {
|
||||||
|
|
@ -150,25 +176,21 @@ impl WlBuffer {
|
||||||
tex_impossible: false,
|
tex_impossible: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Ok(Self {
|
Ok(Self::new(
|
||||||
id,
|
id,
|
||||||
destroyed: Cell::new(false),
|
client,
|
||||||
client: client.clone(),
|
|
||||||
rect: Rect::new_sized_saturating(0, 0, width, height),
|
|
||||||
format,
|
format,
|
||||||
dmabuf: None,
|
width,
|
||||||
render_ctx_version: Cell::new(client.state.render_ctx_version.get()),
|
height,
|
||||||
storage: RefCell::new(Some(WlBufferStorage::Shm {
|
None,
|
||||||
|
Some(WlBufferStorage::Shm {
|
||||||
dmabuf_buffer_params,
|
dmabuf_buffer_params,
|
||||||
mem,
|
mem,
|
||||||
stride,
|
stride,
|
||||||
})),
|
}),
|
||||||
shm: true,
|
true,
|
||||||
width,
|
None,
|
||||||
height,
|
))
|
||||||
tracker: Default::default(),
|
|
||||||
color: None,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_single_pixel(
|
pub fn new_single_pixel(
|
||||||
|
|
@ -178,40 +200,37 @@ impl WlBuffer {
|
||||||
g: u32,
|
g: u32,
|
||||||
b: u32,
|
b: u32,
|
||||||
a: u32,
|
a: u32,
|
||||||
) -> Self {
|
) -> Rc<Self> {
|
||||||
Self {
|
Self::new(
|
||||||
id,
|
id,
|
||||||
destroyed: Cell::new(false),
|
client,
|
||||||
client: client.clone(),
|
ARGB8888,
|
||||||
rect: Rect::new_sized_saturating(0, 0, 1, 1),
|
1,
|
||||||
format: ARGB8888,
|
1,
|
||||||
dmabuf: None,
|
None,
|
||||||
render_ctx_version: Cell::new(client.state.render_ctx_version.get()),
|
None,
|
||||||
storage: RefCell::new(None),
|
false,
|
||||||
shm: false,
|
Some([r, g, b, a]),
|
||||||
width: 1,
|
)
|
||||||
height: 1,
|
|
||||||
tracker: Default::default(),
|
|
||||||
color: Some([r, g, b, a]),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_gfx_context_change(&self, surface: Option<&WlSurface>) {
|
pub fn handle_gfx_context_change(&self) -> bool {
|
||||||
let ctx_version = self.client.state.render_ctx_version.get();
|
let ctx_version = self.client.state.render_ctx_version.get();
|
||||||
if self.render_ctx_version.replace(ctx_version) == ctx_version {
|
let up_to_date = self.render_ctx_version.replace(ctx_version) == ctx_version;
|
||||||
return;
|
|
||||||
}
|
|
||||||
let had_texture = self.reset_gfx_objects(surface);
|
|
||||||
if had_texture && let Some(surface) = surface {
|
|
||||||
self.update_texture_or_log(surface, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset_gfx_objects(&self, surface: Option<&WlSurface>) -> bool {
|
|
||||||
let mut storage = self.storage.borrow_mut();
|
let mut storage = self.storage.borrow_mut();
|
||||||
let Some(s) = &mut *storage else {
|
let Some(s) = &mut *storage else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
if up_to_date {
|
||||||
|
let tex = match s {
|
||||||
|
WlBufferStorage::Shm {
|
||||||
|
dmabuf_buffer_params: DmabufBufferParams { tex, .. },
|
||||||
|
..
|
||||||
|
} => tex,
|
||||||
|
WlBufferStorage::Dmabuf { tex, .. } => tex,
|
||||||
|
};
|
||||||
|
return tex.is_some();
|
||||||
|
}
|
||||||
let had_texture = match s {
|
let had_texture = match s {
|
||||||
WlBufferStorage::Shm {
|
WlBufferStorage::Shm {
|
||||||
dmabuf_buffer_params:
|
dmabuf_buffer_params:
|
||||||
|
|
@ -227,13 +246,8 @@ impl WlBuffer {
|
||||||
} => {
|
} => {
|
||||||
host_buffer.take();
|
host_buffer.take();
|
||||||
*host_buffer_impossible = *udmabuf_impossible;
|
*host_buffer_impossible = *udmabuf_impossible;
|
||||||
let mut had_texture = tex.take().is_some();
|
let had_texture = tex.take().is_some();
|
||||||
*tex_impossible = *udmabuf_impossible;
|
*tex_impossible = *udmabuf_impossible;
|
||||||
if let Some(s) = surface {
|
|
||||||
s.shm_staging.take();
|
|
||||||
s.shm_textures.back().tex.take();
|
|
||||||
had_texture |= s.shm_textures.front().tex.take().is_some();
|
|
||||||
}
|
|
||||||
return had_texture;
|
return had_texture;
|
||||||
}
|
}
|
||||||
WlBufferStorage::Dmabuf { tex, .. } => tex.is_some(),
|
WlBufferStorage::Dmabuf { tex, .. } => tex.is_some(),
|
||||||
|
|
|
||||||
|
|
@ -166,13 +166,7 @@ impl WlDrmRequestHandler for WlDrm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let img = ctx.dmabuf_img(&dmabuf)?;
|
let img = ctx.dmabuf_img(&dmabuf)?;
|
||||||
let buffer = Rc::new(WlBuffer::new_dmabuf(
|
let buffer = WlBuffer::new_dmabuf(req.id, &self.client, format, dmabuf, &img);
|
||||||
req.id,
|
|
||||||
&self.client,
|
|
||||||
format,
|
|
||||||
dmabuf,
|
|
||||||
&img,
|
|
||||||
));
|
|
||||||
track!(self.client, buffer);
|
track!(self.client, buffer);
|
||||||
self.client.add_client_obj(&buffer)?;
|
self.client.add_client_obj(&buffer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ impl WlShmPoolRequestHandler for WlShmPool {
|
||||||
if req.height < 0 || req.width < 0 || req.stride < 0 || req.offset < 0 {
|
if req.height < 0 || req.width < 0 || req.stride < 0 || req.offset < 0 {
|
||||||
return Err(WlShmPoolError::NegativeParameters);
|
return Err(WlShmPoolError::NegativeParameters);
|
||||||
}
|
}
|
||||||
let buffer = Rc::new(WlBuffer::new_shm(
|
let buffer = WlBuffer::new_shm(
|
||||||
req.id,
|
req.id,
|
||||||
&self.client,
|
&self.client,
|
||||||
req.offset as usize,
|
req.offset as usize,
|
||||||
|
|
@ -72,7 +72,7 @@ impl WlShmPoolRequestHandler for WlShmPool {
|
||||||
format,
|
format,
|
||||||
&self.mem.get(),
|
&self.mem.get(),
|
||||||
None,
|
None,
|
||||||
)?);
|
)?;
|
||||||
track!(self.client, buffer);
|
track!(self.client, buffer);
|
||||||
self.client.add_client_obj(&buffer)?;
|
self.client.add_client_obj(&buffer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -1481,12 +1481,14 @@ impl WlSurface {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_shm_textures(&self) {
|
pub fn reset_shm_textures(&self) -> bool {
|
||||||
|
let had_texture = self.shm_textures.front().tex.is_some();
|
||||||
self.shm_staging.take();
|
self.shm_staging.take();
|
||||||
for tex in &*self.shm_textures {
|
for tex in &*self.shm_textures {
|
||||||
tex.tex.take();
|
tex.tex.take();
|
||||||
tex.damage.clear();
|
tex.damage.clear();
|
||||||
}
|
}
|
||||||
|
had_texture
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_damage(&self, pending: &PendingState) {
|
fn apply_damage(&self, pending: &PendingState) {
|
||||||
|
|
|
||||||
|
|
@ -76,14 +76,7 @@ impl WpSinglePixelBufferManagerV1RequestHandler for WpSinglePixelBufferManagerV1
|
||||||
req: CreateU32RgbaBuffer,
|
req: CreateU32RgbaBuffer,
|
||||||
_slf: &Rc<Self>,
|
_slf: &Rc<Self>,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
let buffer = Rc::new(WlBuffer::new_single_pixel(
|
let buffer = WlBuffer::new_single_pixel(req.id, &self.client, req.r, req.g, req.b, req.a);
|
||||||
req.id,
|
|
||||||
&self.client,
|
|
||||||
req.r,
|
|
||||||
req.g,
|
|
||||||
req.b,
|
|
||||||
req.a,
|
|
||||||
));
|
|
||||||
track!(self.client, buffer);
|
track!(self.client, buffer);
|
||||||
self.client.add_client_obj(&buffer)?;
|
self.client.add_client_obj(&buffer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ impl ZwpLinuxBufferParamsV1 {
|
||||||
)
|
)
|
||||||
.map(Rc::new)
|
.map(Rc::new)
|
||||||
.map_err(ZwpLinuxBufferParamsV1Error::CreateClientMem)?;
|
.map_err(ZwpLinuxBufferParamsV1Error::CreateClientMem)?;
|
||||||
Rc::new(WlBuffer::new_shm(
|
WlBuffer::new_shm(
|
||||||
get_id()?,
|
get_id()?,
|
||||||
&self.parent.client,
|
&self.parent.client,
|
||||||
p.offset as usize,
|
p.offset as usize,
|
||||||
|
|
@ -135,16 +135,10 @@ impl ZwpLinuxBufferParamsV1 {
|
||||||
format.format,
|
format.format,
|
||||||
&client_mem,
|
&client_mem,
|
||||||
Some((&p.fd, size)),
|
Some((&p.fd, size)),
|
||||||
)?)
|
)?
|
||||||
} else {
|
} else {
|
||||||
let img = ctx.dmabuf_img(&dmabuf)?;
|
let img = ctx.dmabuf_img(&dmabuf)?;
|
||||||
Rc::new(WlBuffer::new_dmabuf(
|
WlBuffer::new_dmabuf(get_id()?, &self.parent.client, format.format, dmabuf, &img)
|
||||||
get_id()?,
|
|
||||||
&self.parent.client,
|
|
||||||
format.format,
|
|
||||||
dmabuf,
|
|
||||||
&img,
|
|
||||||
))
|
|
||||||
};
|
};
|
||||||
track!(self.parent.client, buffer);
|
track!(self.parent.client, buffer);
|
||||||
if buffer_id.is_some() {
|
if buffer_id.is_some() {
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,9 @@ impl RendererBase<'_> {
|
||||||
opaque: bool,
|
opaque: bool,
|
||||||
cd: &Rc<ColorDescription>,
|
cd: &Rc<ColorDescription>,
|
||||||
) {
|
) {
|
||||||
|
// log::info!("rendering texture {:?}", std::ptr::from_ref(&**texture) as *const u8);
|
||||||
|
// log::info!("{:?}", backtrace::Backtrace::new());
|
||||||
|
|
||||||
let mut texcoord = tpoints.unwrap_or_else(SampleRect::identity);
|
let mut texcoord = tpoints.unwrap_or_else(SampleRect::identity);
|
||||||
|
|
||||||
let (twidth, theight) = if let Some(size) = tsize {
|
let (twidth, theight) = if let Some(size) = tsize {
|
||||||
|
|
|
||||||
21
src/state.rs
21
src/state.rs
|
|
@ -133,7 +133,7 @@ use {
|
||||||
},
|
},
|
||||||
xwayland::{self, XWaylandEvent},
|
xwayland::{self, XWaylandEvent},
|
||||||
},
|
},
|
||||||
ahash::{AHashMap, AHashSet},
|
ahash::AHashMap,
|
||||||
bstr::ByteSlice,
|
bstr::ByteSlice,
|
||||||
jay_config::{
|
jay_config::{
|
||||||
PciId,
|
PciId,
|
||||||
|
|
@ -676,20 +676,21 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Walker.visit_display(&self.root);
|
Walker.visit_display(&self.root);
|
||||||
|
let mut updated_buffers = AHashMap::new();
|
||||||
for client in self.clients.clients.borrow_mut().values() {
|
for client in self.clients.clients.borrow_mut().values() {
|
||||||
let mut updated_buffers = AHashSet::new();
|
updated_buffers.clear();
|
||||||
|
for buffer in client.data.gfx_ctx_changed.iter() {
|
||||||
|
let had_buffer_texture = buffer.handle_gfx_context_change();
|
||||||
|
updated_buffers.insert(buffer.id, had_buffer_texture);
|
||||||
|
}
|
||||||
for surface in client.data.objects.surfaces.lock().values() {
|
for surface in client.data.objects.surfaces.lock().values() {
|
||||||
|
let had_shm_texture = surface.reset_shm_textures();
|
||||||
if let Some(buffer) = surface.buffer.get() {
|
if let Some(buffer) = surface.buffer.get() {
|
||||||
updated_buffers.insert(buffer.buffer.id);
|
let had_buffer_texture = *updated_buffers.get(&buffer.buffer.id).unwrap();
|
||||||
buffer.buffer.handle_gfx_context_change(Some(surface));
|
if had_shm_texture || had_buffer_texture {
|
||||||
} else {
|
buffer.buffer.update_texture_or_log(surface, true);
|
||||||
surface.reset_shm_textures();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for buffer in client.data.objects.buffers.lock().values() {
|
|
||||||
if !updated_buffers.contains(&buffer.id) {
|
|
||||||
buffer.handle_gfx_context_change(None);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue