Skip to content

Implement Debug for Context, Surface and Buffer #268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: madsmtm/context-easier
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Update to `objc2` 0.6.0.
- Bump MSRV to Rust 1.71.
- Make `Context` cloneable.
- `Context`, `Surface` and `Buffer` now implement `Debug`.

# 0.4.6

Expand Down
34 changes: 34 additions & 0 deletions src/backend_dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use crate::{backend_interface::*, backends, InitError, Rect, SoftBufferError};

use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use std::fmt;
use std::num::NonZeroU32;
#[cfg(any(wayland_platform, x11_platform, kms_platform))]
use std::sync::Arc;
Expand Down Expand Up @@ -56,6 +57,17 @@ macro_rules! make_dispatch {
}
}

impl<D: fmt::Debug> fmt::Debug for ContextDispatch<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
$(
$(#[$attr])*
Self::$name(inner) => inner.fmt(f),
)*
}
}
}

#[allow(clippy::large_enum_variant)] // it's boxed anyways
pub(crate) enum SurfaceDispatch<$dgen, $wgen> {
$(
Expand Down Expand Up @@ -117,6 +129,17 @@ macro_rules! make_dispatch {
}
}

impl<D: fmt::Debug, W: fmt::Debug> fmt::Debug for SurfaceDispatch<D, W> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
$(
$(#[$attr])*
Self::$name(inner) => inner.fmt(f),
)*
}
}
}

pub(crate) enum BufferDispatch<'a, $dgen, $wgen> {
$(
$(#[$attr])*
Expand Down Expand Up @@ -172,6 +195,17 @@ macro_rules! make_dispatch {
}
}
}

impl<D: fmt::Debug, W: fmt::Debug> fmt::Debug for BufferDispatch<'_, D, W> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
$(
$(#[$attr])*
Self::$name(inner) => inner.fmt(f),
)*
}
}
}
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/backends/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::error::InitError;
use crate::{BufferInterface, Rect, SoftBufferError, SurfaceInterface};

/// The handle to a window for software buffering.
#[derive(Debug)]
pub struct AndroidImpl<D, W> {
native_window: NativeWindow,
window: W,
Expand Down Expand Up @@ -113,6 +114,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Android
}
}

#[derive(Debug)]
pub struct BufferImpl<'a, D: ?Sized, W> {
native_window_buffer: NativeWindowBufferLockGuard<'a>,
buffer: Vec<u32>,
Expand Down
4 changes: 4 additions & 0 deletions src/backends/cg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ define_class!(
#[unsafe(super(NSObject))]
#[name = "SoftbufferObserver"]
#[ivars = SendCALayer]
#[derive(Debug)]
struct Observer;

/// NSKeyValueObserving
Expand Down Expand Up @@ -92,6 +93,7 @@ impl Observer {
}
}

#[derive(Debug)]
pub struct CGImpl<D, W> {
/// Our layer.
layer: SendCALayer,
Expand Down Expand Up @@ -263,6 +265,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for CGImpl<
}
}

#[derive(Debug)]
pub struct BufferImpl<'a, D, W> {
imp: &'a mut CGImpl<D, W>,
buffer: Box<[u32]>,
Expand Down Expand Up @@ -344,6 +347,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'_,
}
}

#[derive(Debug)]
struct SendCALayer(Retained<CALayer>);

// SAFETY: CALayer is dubiously thread safe, like most things in Core Animation.
Expand Down
8 changes: 8 additions & 0 deletions src/backends/kms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use drm::Device;
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawDisplayHandle, RawWindowHandle};

use std::collections::HashSet;
use std::fmt;
use std::marker::PhantomData;
use std::num::NonZeroU32;
use std::os::unix::io::{AsFd, BorrowedFd};
Expand Down Expand Up @@ -118,6 +119,13 @@ pub(crate) struct BufferImpl<'a, D: ?Sized, W: ?Sized> {
_window: PhantomData<&'a mut W>,
}

impl<D: ?Sized + fmt::Debug, W: ?Sized + fmt::Debug> fmt::Debug for BufferImpl<'_, D, W> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// FIXME: Derive instead once `DumbMapping` impls `Debug`.
f.debug_struct("BufferImpl").finish_non_exhaustive()
}
}

/// The combined frame buffer and dumb buffer.
#[derive(Debug)]
struct SharedBuffer {
Expand Down
5 changes: 5 additions & 0 deletions src/backends/orbital.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{cmp, marker::PhantomData, num::NonZeroU32, slice, str};
use crate::backend_interface::*;
use crate::{Rect, SoftBufferError};

#[derive(Debug)]
struct OrbitalMap {
address: usize,
size: usize,
Expand Down Expand Up @@ -55,6 +56,7 @@ impl Drop for OrbitalMap {
}
}

#[derive(Debug)]
pub struct OrbitalImpl<D, W> {
handle: ThreadSafeWindowHandle,
width: u32,
Expand All @@ -64,6 +66,7 @@ pub struct OrbitalImpl<D, W> {
_display: PhantomData<D>,
}

#[derive(Debug)]
struct ThreadSafeWindowHandle(OrbitalWindowHandle);
unsafe impl Send for ThreadSafeWindowHandle {}
unsafe impl Sync for ThreadSafeWindowHandle {}
Expand Down Expand Up @@ -180,11 +183,13 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Orbital
}
}

#[derive(Debug)]
enum Pixels {
Mapping(OrbitalMap),
Buffer(Vec<u32>),
}

#[derive(Debug)]
pub struct BufferImpl<'a, D, W> {
imp: &'a mut OrbitalImpl<D, W>,
pixels: Pixels,
Expand Down
1 change: 1 addition & 0 deletions src/backends/wayland/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ unsafe fn map_file(file: &File) -> MmapMut {
unsafe { MmapMut::map_mut(file.as_raw_fd()).expect("Failed to map shared memory") }
}

#[derive(Debug)]
pub(super) struct WaylandBuffer {
qh: QueueHandle<State>,
tempfile: File,
Expand Down
3 changes: 3 additions & 0 deletions src/backends/wayland/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use buffer::WaylandBuffer;

struct State;

#[derive(Debug)]
pub struct WaylandDisplayImpl<D: ?Sized> {
conn: Option<Connection>,
event_queue: Mutex<EventQueue<State>>,
Expand Down Expand Up @@ -74,6 +75,7 @@ impl<D: ?Sized> Drop for WaylandDisplayImpl<D> {
}
}

#[derive(Debug)]
pub struct WaylandImpl<D: ?Sized, W: ?Sized> {
display: Arc<WaylandDisplayImpl<D>>,
surface: Option<wl_surface::WlSurface>,
Expand Down Expand Up @@ -257,6 +259,7 @@ impl<D: ?Sized, W: ?Sized> Drop for WaylandImpl<D, W> {
}
}

#[derive(Debug)]
pub struct BufferImpl<'a, D: ?Sized, W> {
stack: util::BorrowStack<'a, WaylandImpl<D, W>, [u32]>,
age: u8,
Expand Down
5 changes: 4 additions & 1 deletion src/backends/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::num::NonZeroU32;
/// Display implementation for the web platform.
///
/// This just caches the document to prevent having to query it every time.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct WebDisplayImpl<D> {
document: web_sys::Document,
_display: D,
Expand All @@ -43,6 +43,7 @@ impl<D: HasDisplayHandle> ContextInterface<D> for WebDisplayImpl<D> {
}
}

#[derive(Debug)]
pub struct WebImpl<D, W> {
/// The handle and context to the canvas that we're drawing to.
canvas: Canvas,
Expand All @@ -65,6 +66,7 @@ pub struct WebImpl<D, W> {

/// Holding canvas and context for [`HtmlCanvasElement`] or [`OffscreenCanvas`],
/// since they have different types.
#[derive(Debug)]
enum Canvas {
Canvas {
canvas: HtmlCanvasElement,
Expand Down Expand Up @@ -373,6 +375,7 @@ impl Canvas {
}
}

#[derive(Debug)]
pub struct BufferImpl<'a, D, W> {
imp: &'a mut WebImpl<D, W>,
}
Expand Down
4 changes: 4 additions & 0 deletions src/backends/win32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const ZERO_QUAD: Gdi::RGBQUAD = Gdi::RGBQUAD {
rgbReserved: 0,
};

#[derive(Debug)]
struct Buffer {
dc: Gdi::HDC,
bitmap: Gdi::HBITMAP,
Expand Down Expand Up @@ -135,6 +136,7 @@ impl Buffer {
}

/// The handle to a window for software buffering.
#[derive(Debug)]
pub struct Win32Impl<D: ?Sized, W> {
/// The window handle.
window: OnlyUsedFromOrigin<HWND>,
Expand Down Expand Up @@ -281,6 +283,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Win32Im
}
}

#[derive(Debug)]
pub struct BufferImpl<'a, D, W>(&'a mut Win32Impl<D, W>);

impl<D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'_, D, W> {
Expand Down Expand Up @@ -460,6 +463,7 @@ impl Command {
}
}

#[derive(Debug)]
struct OnlyUsedFromOrigin<T>(T);
unsafe impl<T> Send for OnlyUsedFromOrigin<T> {}

Expand Down
6 changes: 6 additions & 0 deletions src/backends/x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use x11rb::protocol::shm::{self, ConnectionExt as _};
use x11rb::protocol::xproto::{self, ConnectionExt as _, ImageOrder, VisualClass, Visualid};
use x11rb::xcb_ffi::XCBConnection;

#[derive(Debug)]
pub struct X11DisplayImpl<D: ?Sized> {
/// The handle to the XCB connection.
connection: Option<XCBConnection>,
Expand Down Expand Up @@ -125,6 +126,7 @@ impl<D: ?Sized> X11DisplayImpl<D> {
}

/// The handle to an X11 drawing context.
#[derive(Debug)]
pub struct X11Impl<D: ?Sized, W: ?Sized> {
/// X display this window belongs to.
display: Arc<X11DisplayImpl<D>>,
Expand Down Expand Up @@ -155,6 +157,7 @@ pub struct X11Impl<D: ?Sized, W: ?Sized> {
}

/// The buffer that is being drawn to.
#[derive(Debug)]
enum Buffer {
/// A buffer implemented using shared memory to prevent unnecessary copying.
Shm(ShmBuffer),
Expand All @@ -163,6 +166,7 @@ enum Buffer {
Wire(Vec<u32>),
}

#[derive(Debug)]
struct ShmBuffer {
/// The shared memory segment, paired with its ID.
seg: Option<(ShmSegment, shm::Seg)>,
Expand Down Expand Up @@ -383,6 +387,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
}
}

#[derive(Debug)]
pub struct BufferImpl<'a, D: ?Sized, W: ?Sized>(&'a mut X11Impl<D, W>);

impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle + ?Sized> BufferInterface
Expand Down Expand Up @@ -681,6 +686,7 @@ impl ShmBuffer {
}
}

#[derive(Debug)]
struct ShmSegment {
id: File,
ptr: NonNull<i8>,
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub use backends::web::SurfaceExtWeb;

/// An instance of this struct contains the platform-specific data that must be managed in order to
/// write to a window on that platform.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct Context<D> {
/// The inner static dispatch object.
context_impl: ContextDispatch<D>,
Expand Down Expand Up @@ -73,6 +73,7 @@ pub struct Rect {
}

/// A surface for drawing to a window with software buffers.
#[derive(Debug)]
pub struct Surface<D, W> {
/// This is boxed so that `Surface` is the same size on every platform.
surface_impl: Box<SurfaceDispatch<D, W>>,
Expand Down Expand Up @@ -200,6 +201,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> HasWindowHandle for Surface<D, W>
///
/// Buffer copies an channel swizzling happen on:
/// - Android
#[derive(Debug)]
pub struct Buffer<'a, D, W> {
buffer_impl: BufferDispatch<'a, D, W>,
_marker: PhantomData<(Arc<D>, Cell<()>)>,
Expand Down
7 changes: 7 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![allow(dead_code)]

use std::cmp;
use std::fmt;
use std::num::NonZeroU32;

use crate::Rect;
Expand Down Expand Up @@ -50,6 +51,12 @@ impl<'a, T: 'a + ?Sized, U: 'a + ?Sized> BorrowStack<'a, T, U> {
}
}

impl<'a, T: 'a + ?Sized, U: 'a + ?Sized + fmt::Debug> fmt::Debug for BorrowStack<'a, T, U> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.member().fmt(f)
}
}

/// Calculates the smallest `Rect` necessary to represent all damaged `Rect`s.
pub(crate) fn union_damage(damage: &[Rect]) -> Option<Rect> {
struct Region {
Expand Down