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
impl ViewSurface
Sourcepub fn new(size: Size, scale_factor: f32) -> Result<Self, Error>
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.
Sourcepub fn resize(&mut self, size: Size, scale_factor: f32) -> Result<bool, Error>
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.
Sourcepub const fn stride(&self) -> u32
pub const fn stride(&self) -> u32
Words per row. See Frame::stride for why this is not the width.
Sourcepub unsafe fn draw_into(&self, context: &CGContext, bounds: CGRect)
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.
Sourcepub fn io_surface(&self) -> &IOSurfaceRef
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.
Sourcepub fn context(&self) -> &CGContext
pub fn context(&self) -> &CGContext
The bitmap context, for a caller that wants to draw over Denise’s output with CoreGraphics itself.
Sourcepub fn damage_to_points(&self, rect: Rect) -> CGRect
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
impl Drop for ViewSurface
Source§impl Surface for ViewSurface
impl Surface for ViewSurface
Source§fn scale_factor(&self) -> f32
fn scale_factor(&self) -> f32
1.0 on a typical panel.