use cef::rc::{Rc, RcImpl}; use cef::sys::{_cef_render_handler_t, cef_base_ref_counted_t}; use cef::{Browser, ImplRenderHandler, PaintElementType, Rect, WrapRenderHandler}; use crate::cef::CefEventHandler; use crate::render::FrameBufferRef; pub(crate) struct RenderHandlerImpl { object: *mut RcImpl<_cef_render_handler_t, Self>, event_handler: H, } impl RenderHandlerImpl { pub(crate) fn new(event_handler: H) -> Self { Self { object: std::ptr::null_mut(), event_handler, } } } impl ImplRenderHandler for RenderHandlerImpl { fn view_rect(&self, _browser: Option<&mut Browser>, rect: Option<&mut Rect>) { if let Some(rect) = rect { let view_info = self.event_handler.view_info(); *rect = Rect { x: 0, y: 0, width: view_info.width() as i32, height: view_info.height() as i32, }; } } fn on_paint( &self, _browser: Option<&mut Browser>, _type_: PaintElementType, _dirty_rect_count: usize, _dirty_rects: Option<&Rect>, buffer: *const u8, width: std::ffi::c_int, height: std::ffi::c_int, ) { let buffer_size = (width * height * 4) as usize; let buffer_slice = unsafe { std::slice::from_raw_parts(buffer, buffer_size) }; let frame_buffer = FrameBufferRef::new(buffer_slice, width as usize, height as usize).expect("Failed to create frame buffer"); self.event_handler.draw(frame_buffer) } #[cfg(feature = "accelerated_paint")] fn on_accelerated_paint(&self, _browser: Option<&mut Browser>, type_: PaintElementType, _dirty_rect_count: usize, _dirty_rects: Option<&Rect>, info: Option<&cef::AcceleratedPaintInfo>) { use cef::osr_texture_import::SharedTextureHandle; if type_ != PaintElementType::default() { return; } let shared_handle = SharedTextureHandle::new(info.unwrap()); if let SharedTextureHandle::Unsupported = shared_handle { tracing::error!("Platform does not support accelerated painting"); return; } self.event_handler.draw_gpu(shared_handle); } fn get_raw(&self) -> *mut _cef_render_handler_t { self.object.cast() } } impl Clone for RenderHandlerImpl { fn clone(&self) -> Self { unsafe { let rc_impl = &mut *self.object; rc_impl.interface.add_ref(); } Self { object: self.object, event_handler: self.event_handler.duplicate(), } } } impl Rc for RenderHandlerImpl { fn as_base(&self) -> &cef_base_ref_counted_t { unsafe { let base = &*self.object; std::mem::transmute(&base.cef_object) } } } impl WrapRenderHandler for RenderHandlerImpl { fn wrap_rc(&mut self, object: *mut RcImpl<_cef_render_handler_t, Self>) { self.object = object; } }