Skip to main content

ViewSurface

Struct ViewSurface 

Source
pub struct ViewSurface { /* private fields */ }
Expand description

A pixel buffer a Cocoa view draws from.

Two IOSurfaces, shown alternately. One is handed to a CALayer as its contents, where CoreAnimation reads it in place — no copy, and a cost that does not scale with the size of the window. The obvious alternative, a CGImage per frame, is copied whole on every commit however little of it changed: on a 1040×720 surface with one spinner animating, that is the difference between 9.2% of a core and 2%.

The pair is not for tearing, though it helps there too. It is because assigning the same object to contents tells CoreAnimation nothing: the property has not changed, so it has no reason to look at the buffer again, and the window shows the first frame for ever while the application draws happily into memory nobody is reading. Two surfaces means every present assigns a different object, which is a change it cannot miss. The private -[CALayer setContentsChanged] is the other way, and not one a published crate should take.

So the buffer handed back by Surface::acquire is two frames old, not one, and BufferAge::Frames(2) is what says so — which is exactly the case DamageTracker exists to widen for.

Implementations§

Source§

impl ViewSurface

Source

pub fn new(size: Size, scale_factor: f32) -> Result<Self, Error>

Allocates a surface size physical pixels across.

scale_factor is the view’s backing scale — 2.0 on a Retina display — and is reported to the application rather than applied here. Denise lays out in physical pixels, so a Retina view asks for twice as many of them.

Source

pub fn resize(&mut self, size: Size, scale_factor: f32) -> Result<bool, Error>

Reallocates for a new size or backing scale, discarding the contents.

The caller owes a full repaint afterwards. Nothing here can produce one: the tree owns damage, and it is the one that has to be told.

Source

pub const fn stride(&self) -> u32

Words per row. See Frame::stride for why this is not the width.

Source

pub unsafe fn draw_into(&self, context: &CGContext, bounds: CGRect)

Draws the surface into a Cocoa view’s graphics context.

bounds is the view’s rectangle in points, so a Retina view scales the image down by the backing factor here — the pixels stay physical all the way from layout to this call.

§Safety

context must be a live CGContext whose coordinate system is the one AppKit installs for a flipped view. In an unflipped one the image arrives upside down, silently.

Source

pub fn io_surface(&self) -> &IOSurfaceRef

The buffer to hand a CALayer as its contents.

IOSurfaceRef is toll-free bridged to the IOSurface class, which is what makes it assignable to contents at all.

Source

pub fn context(&self) -> &CGContext

The bitmap context, for a caller that wants to draw over Denise’s output with CoreGraphics itself.

Source

pub fn damage_to_points(&self, rect: Rect) -> CGRect

Converts a damage rectangle in physical pixels to the view’s points.

Rounded outwards, because a rectangle that lands between two points has to invalidate both or leave a seam down one edge.

No vertical flip: the view is flipped, so its coordinates already run top-left downwards, the same as Denise’s.

Trait Implementations§

Source§

impl Drop for ViewSurface

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Surface for ViewSurface

Source§

fn size(&self) -> Size

Visible extent in physical pixels.
Source§

fn scale_factor(&self) -> f32

Physical pixels per logical pixel. 1.0 on a typical panel.
Source§

fn format(&self) -> PixelFormat

Word layout the backend will scan out.
Source§

fn acquire(&mut self) -> Result<Frame<'_>, SurfaceError>

Takes the next drawable buffer.
Source§

fn present(&mut self, _damage: &[Rect]) -> Result<(), SurfaceError>

Publishes the frame, telling the backend which regions changed. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AutoreleaseSafe for T
where T: ?Sized,

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.