diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 08:41:51 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 08:41:51 +0300 |
| commit | 3b8af02be94a510e385f44d58c35c86bb89424a6 (patch) | |
| tree | 2573fb5ac41700d458109ee1cea4bfd875ecf1a2 /src/cocoa/window.m | |
| parent | f7fa0930cb46046f995fa1ab927aef62466e995e (diff) | |
refactor: simplify public API and isolate native extensions
Separate loop/timer and native interoperability APIs from the portable surface header. Unify dispatch, geometry queries, and timer callbacks; keep framebuffer bookkeeping and frame clocks private, and hide implementation symbols.
Update backends, documentation, examples, and API/integration coverage. Verify exports, strict C/C++ installed consumers, and normal plus ASan/UBSan suites.
Diffstat (limited to 'src/cocoa/window.m')
| -rw-r--r-- | src/cocoa/window.m | 99 |
1 files changed, 46 insertions, 53 deletions
diff --git a/src/cocoa/window.m b/src/cocoa/window.m index fc69412..6e1e457 100644 --- a/src/cocoa/window.m +++ b/src/cocoa/window.m @@ -3,7 +3,8 @@ #import <QuartzCore/QuartzCore.h> #include "cocoa/api.h" -#include "yasl/timing.h" +#include "common/timing.h" +#include "common/loop.h" #include "cocoa/keycodes.h" #include <assert.h> @@ -70,6 +71,8 @@ struct cocoa_surface { uint32_t *pixels; size_t pixel_capacity; + id<CAMetalDrawable> drawable; + bool transaction; struct yasl_frame frame; struct yasl_damage_list damage; bool did_present; @@ -775,9 +778,7 @@ bool cocoa_surface_present(struct cocoa_surface *w, const struct yasl_framebuffe { if (!w || w->closed || !w->rendering || w->did_present || !fb || !damage || fb->pixels != w->frame.target.pixels || fb->size.x != w->size.x || - fb->size.y != w->size.y || fb->buffer != w->frame.target.buffer || - fb->transaction != w->frame.target.transaction || - !fb->native_drawable || fb->native_drawable != w->frame.target.native_drawable) + fb->size.y != w->size.y || !w->drawable) return false; if (w->software_queue) { if (fb->pixels != w->pixels || fb->size.x != w->size.x || fb->size.y != w->size.y) @@ -793,7 +794,7 @@ bool cocoa_surface_present(struct cocoa_surface *w, const struct yasl_framebuffe id<MTLCommandBuffer> command = [w->software_queue commandBuffer]; id<MTLBlitCommandEncoder> blit = [command blitCommandEncoder]; if (!blit) { [buffer release]; return false; } - id<CAMetalDrawable> drawable = (id<CAMetalDrawable>)fb->native_drawable; + id<CAMetalDrawable> drawable = w->drawable; [blit copyFromBuffer:buffer sourceOffset:0 sourceBytesPerRow:row_bytes sourceBytesPerImage:length sourceSize:MTLSizeMake(w->size.x, w->size.y, 1) toTexture:drawable.texture destinationSlice:0 destinationLevel:0 @@ -827,6 +828,8 @@ static void render_and_commit(struct cocoa_surface *w) w->frame_due = false; w->did_present = false; id<CAMetalDrawable> drawable = [w->layer nextDrawable]; + w->drawable = drawable; + w->transaction = w->layer.presentsWithTransaction; w->damage = (struct yasl_damage_list){0}; w->frame = (struct yasl_frame){ .surface = &w->base, @@ -834,9 +837,6 @@ static void render_and_commit(struct cocoa_surface *w) .generation = yasl_frame_begin(&w->base), .pixels = w->software_queue ? w->pixels : NULL, .size = w->size, - .damage = &w->damage, - .native_drawable = drawable, - .transaction = w->layer.presentsWithTransaction, }, }; if (drawable) @@ -845,7 +845,7 @@ static void render_and_commit(struct cocoa_surface *w) w->want_draw = true; w->frames_skipped++; } - w->frame.target.native_drawable = NULL; + w->drawable = nil; w->rendering = false; darwin_ctx.depth--; } @@ -864,6 +864,14 @@ int cocoa_display_dispatch_timeout(struct cocoa_display *d, int timeout_ms) assert([NSThread isMainThread]); if (!d || d->pumping) return -1; + for (int i = 0; i < d->count; i++) { + struct cocoa_surface *w = d->windows[i]; + if (w->input.count || w->input.reset_pending || + (w->want_draw && (!w->link || w->frame_due || w->unpaced))) { + timeout_ms = 0; + break; + } + } d->pumping = true; d->depth++; int count = 0; @@ -914,21 +922,6 @@ int cocoa_display_dispatch_timeout(struct cocoa_display *d, int timeout_ms) return count; } -void cocoa_display_dispatch(struct cocoa_display *d) -{ - if (!d) return; - bool immediate = false; - for (int i = 0; i < d->count; i++) { - struct cocoa_surface *w = d->windows[i]; - if (w->input.count > 0 || w->input.reset_pending || - (w->want_draw && (!w->link || w->frame_due || w->unpaced))) { - immediate = true; - break; - } - } - cocoa_display_dispatch_timeout(d, immediate ? 0 : -1); -} - void cocoa_display_flush(struct cocoa_display *d) { assert([NSThread isMainThread]); @@ -1061,7 +1054,7 @@ uint32_t cocoa_display_caps(const struct cocoa_display *d) } struct cocoa_surface *cocoa_surface_create_toplevel(struct cocoa_display *d, - const struct yasl_surface_spec *spec) + const struct yasl_surface_spec *spec, void *graphics_device) { assert([NSThread isMainThread]); if (!d || !d->open || !spec) @@ -1104,8 +1097,8 @@ struct cocoa_surface *cocoa_surface_create_toplevel(struct cocoa_display *d, w->view = [[YaslView alloc] initWithFrame:w->window.contentView.bounds]; w->window.contentView = w->view; w->layer = (CAMetalLayer *)w->view.layer; - if (spec->graphics_device) { - w->layer.device = (id<MTLDevice>)spec->graphics_device; + if (graphics_device) { + w->layer.device = (id<MTLDevice>)graphics_device; } else { id<MTLDevice> device = MTLCreateSystemDefaultDevice(); w->layer.device = device; @@ -1311,14 +1304,12 @@ int cocoa_display_modifiers(const struct cocoa_display *d) return (int)cocoa_mods(NSEvent.modifierFlags); } -struct yasl_vector2i cocoa_surface_size(const struct cocoa_surface *w) +struct yasl_geometry cocoa_surface_geometry(const struct cocoa_surface *w) { - return w ? w->size : (struct yasl_vector2i){0}; -} - -uint32_t cocoa_surface_scale_120(const struct cocoa_surface *w) -{ - return w ? w->scale_120 : YASL_SCALE_UNIT; + return (struct yasl_geometry){ + .size = w ? w->size : (struct yasl_vector2i){0}, + .scale_120 = w ? w->scale_120 : YASL_SCALE_UNIT, + }; } struct cocoa_surface *cocoa_surface_create_popup(struct cocoa_surface *parent, @@ -1367,12 +1358,12 @@ bool cocoa_surface_show_window_menu(struct cocoa_surface *s, struct yasl_vector2 void *cocoa_display_get_native_handle(struct cocoa_display *d) { - return d ? (void *)d : NULL; + return d ? (void *)NSApp : NULL; } void *cocoa_surface_get_native_handle(struct cocoa_surface *s) { - return s ? (void *)s->view : NULL; + return s ? (void *)s->window : NULL; } @@ -1431,11 +1422,6 @@ static uint32_t impl_display_caps(const struct yasl_display *d) return cocoa_display_caps((const struct cocoa_display *)d); } -static void impl_display_dispatch(struct yasl_display *d) -{ - cocoa_display_dispatch((struct cocoa_display *)d); -} - static int impl_display_dispatch_timeout(struct yasl_display *d, int timeout_ms) { return cocoa_display_dispatch_timeout((struct cocoa_display *)d, timeout_ms); @@ -1471,9 +1457,10 @@ static void impl_display_drag_cancel(struct yasl_display *d) cocoa_display_drag_cancel((struct cocoa_display *)d); } -static struct yasl_surface *impl_surface_create_toplevel(struct yasl_display *d, const struct yasl_surface_spec *spec) +static struct yasl_surface *impl_surface_create_toplevel(struct yasl_display *d, + const struct yasl_surface_spec *spec, void *graphics_device) { - struct cocoa_surface *result = cocoa_surface_create_toplevel((struct cocoa_display *)d, spec); + struct cocoa_surface *result = cocoa_surface_create_toplevel((struct cocoa_display *)d, spec, graphics_device); return result ? &result->base : NULL; } @@ -1524,14 +1511,9 @@ static bool impl_surface_input_poll(struct yasl_surface *s, struct yasl_input_ev return cocoa_surface_input_poll((struct cocoa_surface *)s, ev); } -static struct yasl_vector2i impl_surface_size(const struct yasl_surface *s) +static struct yasl_geometry impl_surface_geometry(const struct yasl_surface *s) { - return cocoa_surface_size((const struct cocoa_surface *)s); -} - -static uint32_t impl_surface_scale_120(const struct yasl_surface *s) -{ - return cocoa_surface_scale_120((const struct cocoa_surface *)s); + return cocoa_surface_geometry((const struct cocoa_surface *)s); } static uint32_t impl_surface_state(const struct yasl_surface *s) @@ -1609,12 +1591,23 @@ static void *impl_surface_get_native_handle(struct yasl_surface *s) return cocoa_surface_get_native_handle((struct cocoa_surface *)s); } +static bool impl_surface_get_native_frame(struct yasl_surface *s, + const struct yasl_framebuffer *target, struct yasl_native_frame *out) +{ + struct cocoa_surface *w = (struct cocoa_surface *)s; + if (w->closed || !w->rendering || w->did_present || !w->drawable || + target->pixels != w->frame.target.pixels || + target->size.x != w->size.x || target->size.y != w->size.y) + return false; + *out = (struct yasl_native_frame){(void *)w->drawable, w->transaction}; + return true; +} + const struct yasl_backend_ops yasl_cocoa_backend = { .type = YASL_BACKEND_COCOA, .display_open = impl_display_open, .display_close = impl_display_close, .display_caps = impl_display_caps, - .display_dispatch = impl_display_dispatch, .display_dispatch_timeout = impl_display_dispatch_timeout, .display_flush = impl_display_flush, .display_modifiers = impl_display_modifiers, @@ -1632,8 +1625,7 @@ const struct yasl_backend_ops yasl_cocoa_backend = { .surface_schedule_redraw = impl_surface_schedule_redraw, .surface_present = impl_surface_present, .surface_input_poll = impl_surface_input_poll, - .surface_size = impl_surface_size, - .surface_scale_120 = impl_surface_scale_120, + .surface_geometry = impl_surface_geometry, .surface_state = impl_surface_state, .surface_timing = impl_surface_timing, .surface_frame_time_ns = impl_surface_frame_time_ns, @@ -1649,4 +1641,5 @@ const struct yasl_backend_ops yasl_cocoa_backend = { .surface_place_under_pointer = impl_surface_place_under_pointer, .display_get_native_handle = impl_display_get_native_handle, .surface_get_native_handle = impl_surface_get_native_handle, + .surface_get_native_frame = impl_surface_get_native_frame, }; |
