///|
priv type NativeGpuWorkerHandle
///|
extern "C" fn native_gpu_worker_new() -> NativeGpuWorkerHandle = "moonbit_skia_native_gpu_worker_new"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_is_null(worker : NativeGpuWorkerHandle) -> Bool = "moonbit_skia_native_gpu_worker_is_null"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_submit_empty(
worker : NativeGpuWorkerHandle,
image_resource_revision : Int64,
submitted_at_ms : Double,
) -> Int64 = "moonbit_skia_native_gpu_worker_submit_empty"
///|
#borrow(worker, picture)
extern "C" fn native_gpu_worker_submit_picture(
worker : NativeGpuWorkerHandle,
picture : PictureHandle,
image_resource_revision : Int64,
submitted_at_ms : Double,
) -> Int64 = "moonbit_skia_native_gpu_worker_submit"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_submit_control(
worker : NativeGpuWorkerHandle,
kind : Int,
handle : UInt64,
auxiliary_handle : UInt64,
width : Int,
height : Int,
) -> Int64 = "moonbit_skia_native_gpu_worker_submit_control"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_count(
worker : NativeGpuWorkerHandle,
) -> Int = "moonbit_skia_native_gpu_worker_completion_count"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_wait_completion(
worker : NativeGpuWorkerHandle,
timeout_ms : Int,
) -> Bool = "moonbit_skia_native_gpu_worker_wait_completion"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_sequence(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_completion_sequence"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_control_token(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_completion_control_token"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_status(
worker : NativeGpuWorkerHandle,
) -> Int = "moonbit_skia_native_gpu_worker_completion_status"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_surface_generation(
worker : NativeGpuWorkerHandle,
) -> Int = "moonbit_skia_native_gpu_worker_completion_surface_generation"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_context_generation(
worker : NativeGpuWorkerHandle,
) -> Int = "moonbit_skia_native_gpu_worker_completion_context_generation"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_image_resource_revision(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_completion_image_resource_revision"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_submitted_at_ms(
worker : NativeGpuWorkerHandle,
) -> Double = "moonbit_skia_native_gpu_worker_completion_submitted_at_ms"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_processed_at_ms(
worker : NativeGpuWorkerHandle,
) -> Double = "moonbit_skia_native_gpu_worker_completion_processed_at_ms"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_presented_at_ms(
worker : NativeGpuWorkerHandle,
) -> Double = "moonbit_skia_native_gpu_worker_completion_presented_at_ms"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_pop_completion(
worker : NativeGpuWorkerHandle,
) -> Unit = "moonbit_skia_native_gpu_worker_pop_completion"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_thread_id(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_thread_id"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_submitted(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_submitted"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completed(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_completed"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_dropped(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_dropped"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_replaced_pending(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_replaced_pending"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_surface_generation(
worker : NativeGpuWorkerHandle,
) -> Int = "moonbit_skia_native_gpu_worker_surface_generation"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_context_generation(
worker : NativeGpuWorkerHandle,
) -> Int = "moonbit_skia_native_gpu_worker_context_generation"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_recovery_count(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_recovery_count"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_resource_cache_bytes(
worker : NativeGpuWorkerHandle,
) -> Int64 = "moonbit_skia_native_gpu_worker_resource_cache_bytes"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_control_pending(
worker : NativeGpuWorkerHandle,
) -> Int = "moonbit_skia_native_gpu_worker_control_pending"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_completion_pending(
worker : NativeGpuWorkerHandle,
) -> Int = "moonbit_skia_native_gpu_worker_completion_pending"
///|
#borrow(worker)
extern "C" fn native_gpu_worker_shutdown(
worker : NativeGpuWorkerHandle,
) -> Unit = "moonbit_skia_native_gpu_worker_shutdown"
///|
pub struct NativeGpuRenderWorker {
priv handle : NativeGpuWorkerHandle
}
///|
pub(all) enum NativeGpuWorkerCompletionStatus {
PictureRecorded
Dropped
ControlAcknowledged
FallbackToRaster
Presented
Unknown(Int)
} derive(Eq, Debug)
///|
pub(all) struct NativeGpuWorkerCompletion {
sequence : Int64
control_token : Int64
surface_generation : Int
context_generation : Int
image_resource_revision : Int64
submitted_at_ms : Double
processed_at_ms : Double
presented_at_ms : Double
status : NativeGpuWorkerCompletionStatus
} derive(Eq, Debug)
///|
fn native_gpu_worker_completion_status_from_int(
value : Int,
) -> NativeGpuWorkerCompletionStatus {
match value {
1 => NativeGpuWorkerCompletionStatus::PictureRecorded
2 => NativeGpuWorkerCompletionStatus::Dropped
3 => NativeGpuWorkerCompletionStatus::ControlAcknowledged
4 => NativeGpuWorkerCompletionStatus::FallbackToRaster
5 => NativeGpuWorkerCompletionStatus::Presented
value => NativeGpuWorkerCompletionStatus::Unknown(value)
}
}
///|
pub(all) struct NativeGpuWorkerDiagnostics {
worker_thread_id : Int64
submitted : Int64
completed : Int64
dropped : Int64
replaced_pending : Int64
readback_count : Int64
surface_generation : Int
context_generation : Int
recovery_count : Int64
resource_cache_bytes : Int64
control_pending : Int
completion_pending : Int
} derive(Eq, Debug)
///|
pub fn NativeGpuRenderWorker::new() -> NativeGpuRenderWorker? {
let handle = native_gpu_worker_new()
if native_gpu_worker_is_null(handle) {
None
} else {
Some({ handle, })
}
}
///|
pub fn NativeGpuRenderWorker::submit_empty_picture(
self : NativeGpuRenderWorker,
image_resource_revision? : Int64 = 0L,
submitted_at_ms? : Double = 0.0,
) -> Int64 {
native_gpu_worker_submit_empty(
self.handle,
image_resource_revision,
submitted_at_ms,
)
}
///|
/// Retains the native `SkPicture` before enqueueing it. The worker thread sees
/// only the retained Skia reference and POD metadata, never the MoonBit object.
pub fn NativeGpuRenderWorker::submit_picture(
self : NativeGpuRenderWorker,
picture : Picture,
image_resource_revision? : Int64 = 0L,
submitted_at_ms? : Double = 0.0,
) -> Int64 {
native_gpu_worker_submit_picture(
self.handle,
picture.handle,
image_resource_revision,
submitted_at_ms,
)
}
///|
pub fn NativeGpuRenderWorker::submit_control(
self : NativeGpuRenderWorker,
control : GpuRenderWorkerControl,
) -> Int64 {
match control {
Attach(handle) =>
native_gpu_worker_submit_control(self.handle, 1, handle, 0UL, 0, 0)
AttachSurface(handle, auxiliary_handle) =>
native_gpu_worker_submit_control(
self.handle,
1,
handle,
auxiliary_handle,
0,
0,
)
Resize(width, height) =>
native_gpu_worker_submit_control(self.handle, 2, 0UL, 0UL, width, height)
Detach => native_gpu_worker_submit_control(self.handle, 3, 0UL, 0UL, 0, 0)
ContextLoss(_) =>
native_gpu_worker_submit_control(self.handle, 4, 0UL, 0UL, 0, 0)
Shutdown => native_gpu_worker_submit_control(self.handle, 5, 0UL, 0UL, 0, 0)
}
}
///|
pub fn NativeGpuRenderWorker::wait_completion(
self : NativeGpuRenderWorker,
timeout_ms? : Int = 1000,
) -> Bool {
native_gpu_worker_wait_completion(self.handle, timeout_ms.max(0))
}
///|
pub fn NativeGpuRenderWorker::drain_completions(
self : NativeGpuRenderWorker,
) -> Array[NativeGpuWorkerCompletion] {
let result : Array[NativeGpuWorkerCompletion] = []
while native_gpu_worker_completion_count(self.handle) > 0 {
result.push({
sequence: native_gpu_worker_completion_sequence(self.handle),
control_token: native_gpu_worker_completion_control_token(self.handle),
surface_generation: native_gpu_worker_completion_surface_generation(
self.handle,
),
context_generation: native_gpu_worker_completion_context_generation(
self.handle,
),
image_resource_revision: native_gpu_worker_completion_image_resource_revision(
self.handle,
),
submitted_at_ms: native_gpu_worker_completion_submitted_at_ms(self.handle),
processed_at_ms: native_gpu_worker_completion_processed_at_ms(self.handle),
presented_at_ms: native_gpu_worker_completion_presented_at_ms(self.handle),
status: native_gpu_worker_completion_status_from_int(
native_gpu_worker_completion_status(self.handle),
),
})
native_gpu_worker_pop_completion(self.handle)
}
result
}
///|
pub fn NativeGpuRenderWorker::diagnostics(
self : NativeGpuRenderWorker,
) -> NativeGpuWorkerDiagnostics {
{
worker_thread_id: native_gpu_worker_thread_id(self.handle),
submitted: native_gpu_worker_submitted(self.handle),
completed: native_gpu_worker_completed(self.handle),
dropped: native_gpu_worker_dropped(self.handle),
replaced_pending: native_gpu_worker_replaced_pending(self.handle),
readback_count: 0L,
surface_generation: native_gpu_worker_surface_generation(self.handle),
context_generation: native_gpu_worker_context_generation(self.handle),
recovery_count: native_gpu_worker_recovery_count(self.handle),
resource_cache_bytes: native_gpu_worker_resource_cache_bytes(self.handle),
control_pending: native_gpu_worker_control_pending(self.handle),
completion_pending: native_gpu_worker_completion_pending(self.handle),
}
}
///|
pub fn NativeGpuRenderWorker::shutdown(self : NativeGpuRenderWorker) -> Unit {
native_gpu_worker_shutdown(self.handle)
}