mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-06 21:34:00 -05:00
app: fix potential bug on exit due to already dropped anim when draw() is called after window quit request. see below for more detailed info.
= Crash = 1. User quits -> god.stop_app() -> runtime stops 2. Arc<ManagedSeqAnim> drops -> delete_unmanaged_anim() -> animation removed from self.anims 3. miniquad event loop calls draw() one more time 4. draw_call() hits GfxDrawInstruction::Animation(anim_id) -> self.anims.get_mut(&anim_id).unwrap() PANIC! Animation was already deleted in step 2 = Cause = - DrawCall holds Animation(AnimId) - just an ID, not a reference - self.anims: HashMap<AnimId, GfxSeqAnim> stores actual animation data - ManagedSeqAnim::drop() removes animation from self.anims - DrawCalls may still reference deleted animations - Race during shutdown: animations deleted before final draw() = Fix = Change Animation(AnimId) to Animation(ManagedSeqAnimPtr): - Arc keeps ManagedSeqAnim alive as long as DrawCall exists - Drop only fires when all DrawCalls are dropped - Animation stays in self.anims until safe to delete - Uses Rust ownership to prevent bug at compile time
This commit is contained in:
@@ -472,14 +472,14 @@ impl AsyncEncodable for DrawMesh {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, SerialEncodable)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DrawInstruction {
|
||||
SetScale(f32),
|
||||
Move(Point),
|
||||
SetPos(Point),
|
||||
ApplyView(Rectangle),
|
||||
Draw(DrawMesh),
|
||||
Animation(AnimId),
|
||||
Animation(ManagedSeqAnimPtr),
|
||||
EnableDebug,
|
||||
SetPipeline(GraphicPipeline),
|
||||
}
|
||||
@@ -506,7 +506,7 @@ impl DrawInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, SerialEncodable)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct DrawCall {
|
||||
pub instrs: Vec<DrawInstruction>,
|
||||
pub dcs: Vec<DcId>,
|
||||
@@ -560,7 +560,7 @@ enum GfxDrawInstruction {
|
||||
SetPos(Point),
|
||||
ApplyView(Rectangle),
|
||||
Draw(GfxDrawMesh),
|
||||
Animation(AnimId),
|
||||
Animation(ManagedSeqAnimPtr),
|
||||
EnableDebug,
|
||||
SetPipeline(GraphicPipeline),
|
||||
}
|
||||
@@ -721,10 +721,10 @@ impl<'a> RenderContext<'a> {
|
||||
self.ctx.apply_bindings(&bindings);
|
||||
self.ctx.draw(0, mesh.num_elements, 1);
|
||||
}
|
||||
GfxDrawInstruction::Animation(anim_id) => {
|
||||
let anim = self.anims.get_mut(&anim_id).unwrap();
|
||||
anim.is_visible = true;
|
||||
if let Some(dc) = anim.tick() {
|
||||
GfxDrawInstruction::Animation(anim) => {
|
||||
let gfx_anim = self.anims.get_mut(&anim.id).unwrap();
|
||||
gfx_anim.is_visible = true;
|
||||
if let Some(dc) = gfx_anim.tick() {
|
||||
self.draw_call(&dc, indent + 1, is_debug);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ impl Trax {
|
||||
0u8.encode(&mut self.buf).unwrap();
|
||||
epoch.encode(&mut self.buf).unwrap();
|
||||
batch_id.encode(&mut self.buf).unwrap();
|
||||
dcs.encode(&mut self.buf).unwrap();
|
||||
//dcs.encode(&mut self.buf).unwrap();
|
||||
}
|
||||
|
||||
pub fn put_start_batch(
|
||||
|
||||
@@ -250,7 +250,7 @@ impl Video {
|
||||
vec![
|
||||
DrawInstruction::SetPipeline(GraphicPipeline::YUV),
|
||||
DrawInstruction::Move(rect.pos()),
|
||||
DrawInstruction::Animation(vid_data.anim.id),
|
||||
DrawInstruction::Animation(vid_data.anim.clone()),
|
||||
],
|
||||
vec![],
|
||||
self.z_index.get(),
|
||||
|
||||
Reference in New Issue
Block a user