Crate skia_rs_ffi

Crate skia_rs_ffi 

Source
Expand description

C FFI bindings for skia-rs.

This crate provides C-compatible bindings for use from other languages. It exposes a C API that mirrors the Skia C API for drop-in compatibility.

§Safety

All FFI functions are inherently unsafe. Callers must ensure:

  • Pointers are valid and non-null (unless explicitly documented otherwise)
  • Proper lifetime management (using the appropriate _unref functions)
  • Thread safety requirements are followed (see below)

§Reference Counting

Objects follow Skia’s reference counting model:

  • Objects are created with a reference count of 1
  • sk_*_ref() increments the reference count
  • sk_*_unref() decrements the reference count and frees when it reaches 0
  • Use sk_refcnt_get_count() to query the current count

Reference counting operations (ref/unref) are thread-safe and use atomic operations internally.

§Thread Safety

skia-rs follows Skia’s threading model. Understanding thread safety is critical for correct usage in multi-threaded applications.

§Thread Safety Categories

CategoryDescriptionExamples
Thread-SafeCan be accessed from any thread concurrentlysk_*_ref(), sk_*_unref(), sk_refcnt_*()
Thread-CompatibleSafe if each instance accessed by one threadMost objects
Main-Thread-OnlyMust only be used from main/UI threadGPU contexts

§Object-Specific Thread Safety

§Reference Counting (Thread-Safe)

// These operations are always thread-safe:
sk_surface_ref(surface);      // Atomic increment
sk_surface_unref(surface);    // Atomic decrement
sk_refcnt_get_count(ptr);     // Atomic read
sk_refcnt_is_unique(ptr);     // Atomic read

§Immutable Objects (Thread-Safe after creation)

Once created, these objects are safe to read from multiple threads:

  • sk_path_t (after building is complete)
  • sk_matrix_t (value type, copied on use)

§Mutable Objects (Thread-Compatible)

These must not be accessed concurrently from multiple threads:

  • sk_surface_t - Drawing operations are not thread-safe
  • sk_paint_t - Setters/getters must be externally synchronized
  • sk_pathbuilder_t - Building operations must be single-threaded

§GPU Objects (Special Restrictions)

GPU-related objects have additional constraints:

  • Must be created/destroyed on the same thread as the GPU context
  • Drawing to GPU surfaces must occur on the GPU context thread
  • Flush operations must be called from the same thread

§Safe Patterns

§Pattern 1: Object-per-Thread

// Each thread creates its own objects
void* thread_func(void* arg) {
    sk_surface_t* surface = sk_surface_new_raster(800, 600);
    sk_paint_t* paint = sk_paint_new();
    // ... use exclusively in this thread ...
    sk_paint_unref(paint);
    sk_surface_unref(surface);
    return NULL;
}

§Pattern 2: Shared Immutable Data

// Build path on one thread, share read-only
sk_path_t* shared_path;  // Global

void init() {
    sk_pathbuilder_t* builder = sk_pathbuilder_new();
    sk_pathbuilder_add_circle(builder, 100, 100, 50);
    shared_path = sk_pathbuilder_detach(builder);
    sk_pathbuilder_unref(builder);
}

void* render_thread(void* arg) {
    // Safe: path is immutable after creation
    sk_rect_t bounds;
    sk_path_get_bounds(shared_path, &bounds);
    sk_path_contains(shared_path, 100, 100);
    return NULL;
}

§Pattern 3: Reference Counted Sharing

// Safe: ref counting is atomic
sk_paint_t* paint = sk_paint_new();

void share_to_thread(sk_paint_t* p) {
    sk_paint_ref(p);  // Thread-safe increment
    // Pass to another thread...
}

void* other_thread(void* paint_ptr) {
    sk_paint_t* p = (sk_paint_t*)paint_ptr;
    // Clone for thread-local modifications
    sk_paint_t* local = sk_paint_clone(p);
    sk_paint_unref(p);  // Thread-safe decrement
    // ... use local exclusively ...
    sk_paint_unref(local);
    return NULL;
}

§Unsafe Patterns (AVOID)

// UNSAFE: Concurrent mutation
sk_paint_t* shared_paint;

void* thread1(void* arg) {
    sk_paint_set_color(shared_paint, 0xFFFF0000);  // DATA RACE!
    return NULL;
}

void* thread2(void* arg) {
    sk_paint_set_color(shared_paint, 0xFF0000FF);  // DATA RACE!
    return NULL;
}

// UNSAFE: Drawing while modifying
void* draw_thread(void* arg) {
    sk_surface_draw_rect(surface, &rect, paint);  // DATA RACE with modifier!
    return NULL;
}

void* modify_thread(void* arg) {
    sk_paint_set_stroke_width(paint, 5.0);  // DATA RACE with drawer!
    return NULL;
}

§Error Checking

After any FFI call, check for panics:

sk_surface_t* surface = sk_surface_new_raster(800, 600);
if (sk_last_call_panicked()) {
    // Handle error - surface may be NULL
    fprintf(stderr, "Surface creation panicked\n");
}

§Summary Table

OperationThread-SafeNotes
sk_*_new()YesReturns unique object
sk_*_ref()YesAtomic increment
sk_*_unref()YesAtomic decrement
sk_*_clone()Yes*Input must not be concurrently modified
sk_*_get_*()NoRequires external synchronization
sk_*_set_*()NoRequires external synchronization
sk_surface_draw_*()NoSingle-threaded drawing only
sk_path_contains()Yes*After path is immutable
sk_pathbuilder_*()NoSingle-threaded building

§Panic Safety

All FFI functions catch panics at the boundary to prevent unwinding into C code. Functions that panic will return a default/null value and set an error flag. Use sk_last_call_panicked() to check.

Modules§

abi
Binary ABI Compatibility Layer

Structs§

RefCounted
Reference counted wrapper for FFI objects.
sk_imageinfo_t
C-compatible image info structure.
sk_ipoint_t
C-compatible integer point structure.
sk_irect_t
C-compatible integer rectangle structure.
sk_isize_t
C-compatible integer size structure.
sk_matrix_t
C-compatible matrix structure.
sk_point_t
C-compatible point structure.
sk_rect_t
C-compatible rectangle structure.
sk_size_t
C-compatible size structure.

Functions§

sk_is_available
Check if the library is available.
sk_last_call_panicked
Check if the last FFI call panicked.
sk_matrix_concat
Concatenate two matrices.
sk_matrix_map_point
Map a point through a matrix.
sk_matrix_set_identity
Set matrix to identity.
sk_matrix_set_rotate
Set matrix to rotate (degrees).
sk_matrix_set_scale
Set matrix to scale.
sk_matrix_set_translate
Set matrix to translate.
sk_paint_clone
Clone a paint.
sk_paint_delete
Decrement the reference count of a paint (alias for unref).
sk_paint_get_color
Get the paint color.
sk_paint_get_refcnt
Get the reference count of a paint.
sk_paint_get_stroke_width
Get the stroke width.
sk_paint_is_antialias
Check if anti-alias is enabled.
sk_paint_new
Create a new paint.
sk_paint_ref
Increment the reference count of a paint.
sk_paint_set_antialias
Set anti-alias.
sk_paint_set_color
Set the paint color.
sk_paint_set_stroke_width
Set the stroke width.
sk_paint_set_style
Set the paint style.
sk_paint_unref
Decrement the reference count of a paint.
sk_path_clone
Clone a path.
sk_path_contains
Check if path contains a point.
sk_path_delete
Decrement the reference count of a path (alias for unref).
sk_path_get_bounds
Get the path bounds.
sk_path_get_filltype
Get the fill type.
sk_path_get_refcnt
Get the reference count of a path.
sk_path_is_empty
Check if path is empty.
sk_path_new
Create a new path.
sk_path_ref
Increment the reference count of a path.
sk_path_set_filltype
Set the fill type.
sk_path_unref
Decrement the reference count of a path.
sk_pathbuilder_add_circle
Add a circle.
sk_pathbuilder_add_oval
Add an oval.
sk_pathbuilder_add_rect
Add a rectangle.
sk_pathbuilder_close
Close the path.
sk_pathbuilder_cubic_to
Cubic bezier to a point.
sk_pathbuilder_delete
Decrement the reference count of a path builder (alias for unref).
sk_pathbuilder_detach
Build the path and reset the builder.
sk_pathbuilder_line_to
Line to a point.
sk_pathbuilder_move_to
Move to a point.
sk_pathbuilder_new
Create a new path builder.
sk_pathbuilder_quad_to
Quadratic bezier to a point.
sk_pathbuilder_ref
Increment the reference count of a path builder.
sk_pathbuilder_snapshot
Build the path without resetting the builder.
sk_pathbuilder_unref
Decrement the reference count of a path builder.
sk_refcnt_get_count
Get the reference count of an object.
sk_refcnt_is_unique
Check if an object has only one reference (is unique).
sk_surface_clear
Clear a surface with a color.
sk_surface_draw_circle
Draw a circle on a surface.
sk_surface_draw_line
Draw a line on a surface.
sk_surface_draw_path
Draw a path on a surface.
sk_surface_draw_rect
Draw a rect on a surface.
sk_surface_get_height
Get the height of a surface.
sk_surface_get_refcnt
Get the reference count of a surface.
sk_surface_get_width
Get the width of a surface.
sk_surface_is_unique
Check if the surface has only one reference.
sk_surface_new_raster
Create a new raster surface.
sk_surface_new_raster_with_info
Create a raster surface with specific image info.
sk_surface_peek_pixels
Get the pixel data from a surface.
sk_surface_ref
Increment the reference count of a surface.
sk_surface_unref
Decrement the reference count of a surface.
sk_version
Get the library version.

Type Aliases§

sk_color_t
C-compatible color (ARGB).
sk_paint_t
Reference counted paint type.
sk_path_t
Reference counted path type.
sk_pathbuilder_t
Reference counted path builder type.
sk_refcnt_t
Opaque reference counted object type.
sk_surface_t
Reference counted surface type.