debug_ui: Render bitmap in new 'Bitmap' display object tab
This lets us view a bitmap directly from the debug ui. We cache an egui texture handle on the `BitmapData` itself, and invalidate it whenever the BitmapData gets changed.
This commit is contained in:
parent
4d2b2893ae
commit
932f2d410b
|
@ -226,6 +226,12 @@ pub struct BitmapData<'gc> {
|
|||
|
||||
#[collect(require_static)]
|
||||
dirty_state: DirtyState,
|
||||
|
||||
/// Holds an egui texture handle, used for rendering this Bitmap in the debug ui.
|
||||
/// This is automatically set to `None` when the texture is updated (either from
|
||||
/// marking the CPU side dirty, or from performing a GPU -> CPU sync).
|
||||
#[cfg(feature = "egui")]
|
||||
pub egui_texture: std::cell::RefCell<Option<egui::TextureHandle>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -306,6 +312,8 @@ mod wrapper {
|
|||
avm2_object: None,
|
||||
display_objects: vec![],
|
||||
dirty_state: DirtyState::Clean,
|
||||
#[cfg(feature = "egui")]
|
||||
egui_texture: Default::default(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
@ -328,6 +336,8 @@ mod wrapper {
|
|||
display_objects: vec![],
|
||||
// We have no GPU texture, so there's no need to mark as dirty
|
||||
dirty_state: DirtyState::Clean,
|
||||
#[cfg(feature = "egui")]
|
||||
egui_texture: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,7 +359,9 @@ mod wrapper {
|
|||
}),
|
||||
)
|
||||
.expect("Failed to sync BitmapData");
|
||||
write.dirty_state = DirtyState::Clean
|
||||
write.dirty_state = DirtyState::Clean;
|
||||
#[cfg(feature = "egui")]
|
||||
write.egui_texture.borrow_mut().take();
|
||||
}
|
||||
old_state => write.dirty_state = old_state,
|
||||
}
|
||||
|
@ -389,6 +401,8 @@ mod wrapper {
|
|||
}
|
||||
DirtyState::CpuModified(_) | DirtyState::Clean => None,
|
||||
};
|
||||
#[cfg(feature = "egui")]
|
||||
write.egui_texture.borrow_mut().take();
|
||||
(self.0, dirty_rect)
|
||||
}
|
||||
|
||||
|
@ -561,6 +575,8 @@ impl<'gc> BitmapData<'gc> {
|
|||
avm2_object: None,
|
||||
display_objects: vec![],
|
||||
dirty_state: DirtyState::Clean,
|
||||
#[cfg(feature = "egui")]
|
||||
egui_texture: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -580,6 +596,8 @@ impl<'gc> BitmapData<'gc> {
|
|||
disposed: false,
|
||||
dirty_state: DirtyState::Clean,
|
||||
display_objects: vec![],
|
||||
#[cfg(feature = "egui")]
|
||||
egui_texture: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,6 +650,10 @@ impl<'gc> BitmapData<'gc> {
|
|||
pub fn set_cpu_dirty(&mut self, gc_context: &Mutation<'gc>, region: PixelRegion) {
|
||||
debug_assert!(region.x_max <= self.width);
|
||||
debug_assert!(region.y_max <= self.height);
|
||||
|
||||
#[cfg(feature = "egui")]
|
||||
self.egui_texture.borrow_mut().take();
|
||||
|
||||
let inform_changes = match &mut self.dirty_state {
|
||||
DirtyState::CpuModified(old_region) => {
|
||||
old_region.union(region);
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::debug_ui::handle::{AVM1ObjectHandle, AVM2ObjectHandle, DisplayObjectH
|
|||
use crate::debug_ui::movie::open_movie_button;
|
||||
use crate::debug_ui::Message;
|
||||
use crate::display_object::{
|
||||
DisplayObject, EditText, InteractiveObject, MovieClip, Stage, TDisplayObject,
|
||||
Bitmap, DisplayObject, EditText, InteractiveObject, MovieClip, Stage, TDisplayObject,
|
||||
TDisplayObjectContainer, TInteractiveObject,
|
||||
};
|
||||
use crate::focus_tracker::Highlight;
|
||||
|
@ -160,6 +160,8 @@ impl DisplayObjectWindow {
|
|||
self.show_movieclip(ui, context, object)
|
||||
} else if let DisplayObject::EditText(object) = object {
|
||||
self.show_edit_text(ui, object)
|
||||
} else if let DisplayObject::Bitmap(object) = object {
|
||||
self.show_bitmap(ui, context, object)
|
||||
} else if let DisplayObject::Stage(object) = object {
|
||||
self.show_stage(ui, context, object, messages)
|
||||
}
|
||||
|
@ -346,6 +348,29 @@ impl DisplayObjectWindow {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn show_bitmap<'gc>(
|
||||
&mut self,
|
||||
ui: &mut Ui,
|
||||
context: &mut UpdateContext<'_, 'gc>,
|
||||
object: Bitmap<'gc>,
|
||||
) {
|
||||
let bitmap_data = object.bitmap_data(context.renderer);
|
||||
let bitmap_data = bitmap_data.read();
|
||||
let mut egui_texture = bitmap_data.egui_texture.borrow_mut();
|
||||
let texture = egui_texture.get_or_insert_with(|| {
|
||||
let image = egui::ColorImage::from_rgba_premultiplied(
|
||||
[bitmap_data.width() as usize, bitmap_data.height() as usize],
|
||||
&bitmap_data.pixels_rgba(),
|
||||
);
|
||||
ui.ctx().load_texture(
|
||||
format!("bitmap-{:?}", object.as_ptr()),
|
||||
image,
|
||||
Default::default(),
|
||||
)
|
||||
});
|
||||
ui.image((texture.id(), texture.size_vec2()));
|
||||
}
|
||||
|
||||
pub fn show_movieclip<'gc>(
|
||||
&mut self,
|
||||
ui: &mut Ui,
|
||||
|
@ -979,7 +1004,10 @@ fn summary_color_transform_entry(name: &str, mult: Fixed8, add: i16) -> Option<S
|
|||
fn has_type_specific_tab(object: DisplayObject) -> bool {
|
||||
matches!(
|
||||
object,
|
||||
DisplayObject::MovieClip(_) | DisplayObject::EditText(_) | DisplayObject::Stage(_)
|
||||
DisplayObject::MovieClip(_)
|
||||
| DisplayObject::EditText(_)
|
||||
| DisplayObject::Bitmap(_)
|
||||
| DisplayObject::Stage(_)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue