Fix build on Wayland
Francesco Pasa 2 weeks ago
Francesco Pasa 2 weeks ago
src/draw_call.c M +16 -28
1 #include "alba.h"
2 #include "internal.h"
3
4-DrawCall* window_create_draw_call(AlbaWindow* window)
5-{
6+DrawCall *window_create_draw_call(AlbaWindow *window) {
7 DrawCall draw_call = {0};
8 draw_call.buffers_dirty = 1;
9 draw_call.bind_group_dirty = 1;
13 return alba_array_last(&window->draw_calls);
14 }
15
16-void window_set_texture(AlbaWindow* window, const WGPUTexture texture)
17-{
18- DrawCall* draw_call = alba_array_last(&window->draw_calls);
19- if (draw_call->texture_set)
20- {
21+void window_set_texture(AlbaWindow *window, const WGPUTexture texture) {
22+ DrawCall *draw_call = alba_array_last(&window->draw_calls);
23+ if (draw_call->texture_set) {
24 draw_call = window_create_draw_call(window);
25 }
26 draw_call_set_texture(draw_call, texture);
27 draw_call->texture_set = 1;
28 }
29
30-void window_clear(AlbaWindow* window)
31-{
32+void window_clear(AlbaWindow *window) {
33 alba_array_clear(&window->draw_calls);
34 }
35
36-void clear_texture_bind_group(const DrawCall* draw_call)
37-{
38+void clear_texture_bind_group(const DrawCall *draw_call) {
39 wgpuBindGroupRelease(draw_call->bind_group);
40 }
41
42-void draw_call_set_texture(DrawCall* draw_call, const WGPUTexture texture)
43-{
44- if (draw_call->view != NULL)
45- {
46+void draw_call_set_texture(DrawCall *draw_call, const WGPUTexture texture) {
47+ if (draw_call->view != NULL) {
48 wgpuTextureViewRelease(draw_call->view);
49 }
50- if (draw_call->texture != NULL)
51- {
52+ if (draw_call->texture != NULL) {
53 wgpuTextureDestroy(draw_call->texture);
54 wgpuTextureRelease(draw_call->texture);
55 }
44 draw_call->bind_group_dirty = 1;
45 }
46
47-void draw_call_update_bind_group(const AlbaWindow* window, DrawCall* draw_call)
48-{
49+void draw_call_update_bind_group(const AlbaWindow *window, DrawCall *draw_call) {
50 WGPUBindGroupEntry bind_group_entries[2] = {0};
51
52 // Texture
53- if (draw_call->texture == NULL)
54- {
55+ if (draw_call->texture == NULL) {
56 draw_call_set_texture(
57 draw_call,
58 // 1x1 white texture
56 window,
57 WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst,
58 (AlbaVector){1, 1},
59- WGPUTextureFormat_RGBA8UnormSrgb, 1,
60+ window->surface_format,
61+ 1,
62 &(AlbaColor)WHITE
63 )
64 );
68 bind_group_entries[0].textureView = draw_call->view;
69
70 // Sampler
71- if (draw_call->sampler == NULL)
72- {
73+ if (draw_call->sampler == NULL) {
74 WGPUSamplerDescriptor sampler_options = {0};
75 sampler_options.addressModeU = WGPUAddressMode_ClampToEdge;
76 sampler_options.addressModeV = WGPUAddressMode_ClampToEdge;
91 binding_group_options.entryCount = 2;
92 binding_group_options.entries = bind_group_entries;
93
94- if (draw_call->bind_group != NULL)
95- {
96+ if (draw_call->bind_group != NULL) {
97 wgpuBindGroupRelease(draw_call->bind_group);
98 }
99 draw_call->bind_group = wgpuDeviceCreateBindGroup(window->device, &binding_group_options);
100 }
101
102-void draw_call_release(const DrawCall* draw_call)
103-{
104+void draw_call_release(const DrawCall *draw_call) {
105 wgpuBufferDestroy(draw_call->vertices);
106 wgpuBufferRelease(draw_call->vertices);
107 alba_array_release(&draw_call->new_vertices);
src/helpers.c M +18 -28
3
4 #include <stdio.h>
5
6-void alba_color_print(const AlbaColor* color)
7-{
8+void alba_color_print(const AlbaColor *color) {
9 printf("AlbaColor{%f, %f, %f, %f}\n", color->r, color->g, color->b, color->a);
10 }
11
12-int alba_color_is_transparent(const AlbaColor* color)
13-{
14+int alba_color_is_transparent(const AlbaColor *color) {
15 return color->r == 0 && color->g == 0 && color->b == 0 && color->a == 0;
16 }
17
18-void alba_vector_print(const AlbaVector* vector)
19-{
20+void alba_vector_print(const AlbaVector *vector) {
21 printf("AlbaVector{%f, %f}\n", vector->x, vector->y);
22 }
23
24-void alba_attribute_print(const AlbaAttribute* attribute)
25-{
26+void alba_attribute_print(const AlbaAttribute *attribute) {
27 printf("AlbaAttribute{\n ");
28 alba_color_print(&attribute->color);
29 printf(" ");
24 }
25
26 WGPUBuffer create_buffer(
27- const AlbaWindow* window,
28- const uint64_t size, const void* data,
29+ const AlbaWindow *window,
30+ const uint64_t size, const void *data,
31 const WGPUBufferUsageFlags flags
32-)
33-{
34+) {
35 WGPUBufferDescriptor buffer_options = {0};
36 buffer_options.usage = WGPUBufferUsage_CopyDst | flags;
37 buffer_options.size = size;
36 return buffer;
37 }
38
39-void release_buffer(const WGPUBuffer buffer)
40-{
41- if (buffer != NULL)
42- {
43+void release_buffer(const WGPUBuffer buffer) {
44+ if (buffer != NULL) {
45 wgpuBufferDestroy(buffer);
46 wgpuBufferRelease(buffer);
47 }
48 }
49
50 WGPUBuffer update_buffer(
51- const AlbaWindow* window, WGPUBuffer buffer, const WGPUBufferUsage usage, AlbaArray data
52-)
53-{
54+ const AlbaWindow *window, WGPUBuffer buffer, const WGPUBufferUsage usage, AlbaArray data
55+) {
56 // Deallocate old buffer if any
57 release_buffer(buffer);
58 // Copy data to new buffer
56 }
57
58 WGPUTexture create_texture(
59- const AlbaWindow* window,
60+ const AlbaWindow *window,
61 const WGPUTextureUsage usage,
62 const AlbaVector size,
63- const WGPUTextureFormat format, const uint8_t samples,
64- const void* data
65-)
66-{
67+ const WGPUTextureFormat format,
68+ const uint8_t samples,
69+ const void *data
70+) {
71 WGPUTextureDescriptor texture_options = {0};
72 texture_options.usage = usage;
73 texture_options.format = format;
75
76 const WGPUTexture texture = wgpuDeviceCreateTexture(window->device, &texture_options);
77
78- if (data != NULL)
79- {
80+ if (data != NULL) {
81 const uint64_t bpp = format == WGPUTextureFormat_R8Unorm ? 1 : 4;
82
83 WGPUImageCopyTexture destination = {0};
98 return texture;
99 }
100
101-void release_texture(const WGPUTexture texture)
102-{
103+void release_texture(const WGPUTexture texture) {
104 wgpuTextureDestroy(texture);
105 wgpuTextureRelease(texture);
106 }
src/internal.h M +40 -32
12 #define NO_TEXTURE {-1, -1}
13
14 // Window
15-typedef struct
16-{
17+typedef struct {
18 AlbaString string; // needed?
19 AlbaVector position;
20 // Make part of style?
21 FT_Face face; // needed?
22 AlbaTextStyle style;
23 uint32_t glyph_count;
24- hb_glyph_info_t* glyphs_infos;
25- hb_glyph_position_t* glyph_positions;
26+ hb_glyph_info_t *glyphs_infos;
27+ hb_glyph_position_t *glyph_positions;
28 } Text;
29
30-typedef struct
31-{
32+typedef struct {
33 int buffers_dirty;
34 AlbaArray new_vertices;
35 AlbaArray new_attributes;
43 WGPUBindGroup bind_group;
44 } DrawCall;
45
46-void draw_call_generate_text(const AlbaWindow* window, DrawCall* draw_call);
47-void draw_call_set_texture(DrawCall* draw_call, WGPUTexture texture);
48-void draw_call_update_bind_group(const AlbaWindow* window, DrawCall* draw_call);
49-void draw_call_release(const DrawCall* draw_call);
50+void draw_call_generate_text(const AlbaWindow *window, DrawCall *draw_call);
51
52-typedef struct AlbaWindowImpl
53-{
54+void draw_call_set_texture(DrawCall *draw_call, WGPUTexture texture);
55+
56+void draw_call_update_bind_group(const AlbaWindow *window, DrawCall *draw_call);
57+
58+void draw_call_release(const DrawCall *draw_call);
59+
60+typedef struct AlbaWindowImpl {
61 AlbaWindowOptions options;
62- GLFWwindow* glfw_window;
63+ GLFWwindow *glfw_window;
64 AlbaVector size;
65 AlbaVector scale;
66 WGPUInstance instance;
68 WGPUBindGroup uniforms_bind_group;
69 WGPUBindGroupLayout texture_bind_group_layout;
70 AlbaArray draw_calls;
71+ WGPUTextureFormat surface_format;
72 } AlbaWindow;
73
74-DrawCall* window_create_draw_call(AlbaWindow* window);
75-void window_set_texture(AlbaWindow* window, WGPUTexture texture);
76-void window_clear(AlbaWindow* window);
77+DrawCall *window_create_draw_call(AlbaWindow *window);
78+
79+void window_set_texture(AlbaWindow *window, WGPUTexture texture);
80+
81+void window_clear(AlbaWindow *window);
82
83 // Atlas
84-typedef struct
85-{
86+typedef struct {
87 // Key properties
88 uint32_t codepoint;
89 AlbaTextStyle style;
91 AlbaVector end;
92 } AlbaGlyph;
93
94-typedef struct
95-{
96- struct hashmap* glyphs;
97+typedef struct {
98+ struct hashmap *glyphs;
99 int dirty;
100 AlbaArray glyph_sizes; // in w, h order
101 AlbaVector size;
102- uint8_t* image;
103+ uint8_t *image;
104 } Atlas;
105
106 Atlas create_atlas(uint32_t capacity);
107-void atlas_reserve(Atlas* atlas, uint32_t capacity);
108-void atlas_append(Atlas* atlas, FT_Face face, uint32_t codepoint, AlbaTextStyle style);
109-void atlas_generate_image(Atlas* atlas);
110-void atlas_release(const Atlas* atlas);
111+
112+void atlas_reserve(Atlas *atlas, uint32_t capacity);
113+
114+void atlas_append(Atlas *atlas, FT_Face face, uint32_t codepoint, AlbaTextStyle style);
115+
116+void atlas_generate_image(Atlas *atlas);
117+
118+void atlas_release(const Atlas *atlas);
119
120 // Helpers
121-WGPUSurface get_window_surface(WGPUInstance instance, AlbaWindow* window);
122+WGPUSurface get_window_surface(WGPUInstance instance, AlbaWindow *window);
123
124 WGPUBuffer create_buffer(
125- const AlbaWindow* window,
126- uint64_t size, const void* data,
127+ const AlbaWindow *window,
128+ uint64_t size, const void *data,
129 WGPUBufferUsageFlags flags
130 );
131+
132 void release_buffer(WGPUBuffer buffer);
133+
134 WGPUBuffer update_buffer(
135- const AlbaWindow* window, WGPUBuffer buffer, WGPUBufferUsage usage, AlbaArray data
136+ const AlbaWindow *window, WGPUBuffer buffer, WGPUBufferUsage usage, AlbaArray data
137 );
138
139 WGPUTexture create_texture(
140- const AlbaWindow* window,
141+ const AlbaWindow *window,
142 WGPUTextureUsage usage,
143 AlbaVector size,
144 WGPUTextureFormat format, uint8_t samples,
145- const void* data
146+ const void *data
147 );
148+
149 void release_texture(WGPUTexture texture);
150
151 // Global variables
src/text.c M +33 -49
13 Atlas atlas;
14 pthread_mutex_t freetype_mutex = PTHREAD_MUTEX_INITIALIZER;
15
16-void ensure_freetype_initialized()
17-{
18+void ensure_freetype_initialized() {
19 // already initialized
20 if (freetype != NULL) return;
21
22 pthread_mutex_lock(&freetype_mutex);
23- if (FT_Init_FreeType(&freetype))
24- {
25+ if (FT_Init_FreeType(&freetype)) {
26 fprintf(stderr, "error: initializeing FreeType failed");
27 pthread_mutex_unlock(&freetype_mutex);
28 exit(1);
31 0, // face index
32 &roboto
33 );
34- if (error)
35- {
36+ if (error) {
37 fprintf(stderr, "error: cound not load built in Roboto font");
38 }
39
41 }
42
43 void atlas_add_chars(
44- Atlas* atlas,
45- const uint32_t glyph_count, const hb_glyph_info_t* glyph_infos,
46+ Atlas *atlas,
47+ const uint32_t glyph_count, const hb_glyph_info_t *glyph_infos,
48 const AlbaTextStyle style
49-)
50-{
51- for (uint32_t i = 0; i < glyph_count; i++)
52- {
53+) {
54+ for (uint32_t i = 0; i < glyph_count; i++) {
55 atlas_append(atlas, roboto, glyph_infos[i].codepoint, style);
56 }
57 }
58
59-uint64_t hash_glyph2(const void* item, const uint64_t seed0, const uint64_t seed1)
60-{
61- return hashmap_murmur((FT_Long*)item, sizeof(FT_Long), seed0, seed1);
62+uint64_t hash_glyph2(const void *item, const uint64_t seed0, const uint64_t seed1) {
63+ return hashmap_murmur((FT_Long *) item, sizeof(FT_Long), seed0, seed1);
64 }
65
66 void atlas_generate_text_geometry(
67- const Atlas* atlas,
68- const Text* text,
69- const AlbaWindow* window,
70- DrawCall* draw_call
71-)
72-{
73+ const Atlas *atlas,
74+ const Text *text,
75+ const AlbaWindow *window,
76+ DrawCall *draw_call
77+) {
78 const AlbaTextStyle style = text->style;
79- AlbaArray* vertices = &draw_call->new_vertices;
80- AlbaArray* attributes = &draw_call->new_attributes;
81- AlbaArray* indices = &draw_call->new_indices;
82+ AlbaArray *vertices = &draw_call->new_vertices;
83+ AlbaArray *attributes = &draw_call->new_attributes;
84+ AlbaArray *indices = &draw_call->new_indices;
85
86 alba_array_reserve(vertices, vertices->length + text->glyph_count * 4);
87 alba_array_reserve(attributes, attributes->length + text->glyph_count * 4);
88 alba_array_reserve(indices, indices->length + text->glyph_count * 6);
89
90 AlbaVector current = text->position;
91- for (uint32_t i = 0; i < text->glyph_count; i++)
92- {
93+ for (uint32_t i = 0; i < text->glyph_count; i++) {
94 // TODO: mutex?
95 const uint32_t codepoint = text->glyphs_infos[i].codepoint;
96- const AlbaGlyph* glyph = hashmap_get(
97+ const AlbaGlyph *glyph = hashmap_get(
98 atlas->glyphs,
99 &(AlbaGlyph){
100 .codepoint = codepoint,
101 .style = style
102 }
103 );
104- if (glyph == NULL)
105- {
106- fprintf(stderr, "error: unable to find glyph for codepoint '%s'\n", (char*)&codepoint);
107+ if (glyph == NULL) {
108+ fprintf(stderr, "error: unable to find glyph for codepoint '%s'\n", (char *) &codepoint);
109 exit(1);
110 }
111
112- const hb_glyph_position_t* pos = &text->glyph_positions[i];
113+ const hb_glyph_position_t *pos = &text->glyph_positions[i];
114 const FT_Glyph_Metrics metrics = glyph->metrics;
115
116 // All these / 64 are because FreeType reports metrics in 1/64th of pixel
132 }
133 }
134
135-void draw_call_generate_text(const AlbaWindow* window, DrawCall* draw_call)
136-{
137- for (uint64_t i = 0; i < draw_call->new_texts.length; i++)
138- {
139- const Text* text = draw_call->new_texts.data + i * draw_call->new_texts.element_size;
140+void draw_call_generate_text(const AlbaWindow *window, DrawCall *draw_call) {
141+ for (uint64_t i = 0; i < draw_call->new_texts.length; i++) {
142+ const Text *text = draw_call->new_texts.data + i * draw_call->new_texts.element_size;
143 atlas_generate_text_geometry(&atlas, text, window, draw_call);
144 }
145 }
146
147 void alba_draw_text(
148- AlbaWindow* window,
149+ AlbaWindow *window,
150 const AlbaVector pos,
151 const AlbaString string,
152 AlbaTextStyle style
153-)
154-{
155+) {
156 ensure_freetype_initialized();
157
158 if (style.font_size == 0) style.font_size = 16;
159 if (alba_color_is_transparent(&style.color)) style.color = (AlbaColor)WHITE;
160
161- const char* chars = alba_string_to_char(&string);
162- hb_buffer_t* buffer = hb_buffer_create();
163+ const char *chars = alba_string_to_char(&string);
164+ hb_buffer_t *buffer = hb_buffer_create();
165
166 // TODO: remove assumption that string is in a single script
167 const hb_script_t script = HB_SCRIPT_LATIN;
170 style.font_size * window->scale.x,
171 style.font_size * window->scale.y
172 );
173- if (error)
174- {
175+ if (error) {
176 fprintf(stderr, "error: cound not set Roboto face size");
177 }
178
178 {HB_TAG('l', 'i', 'g', 'a'), 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
179 };
180
181- hb_font_t* hb_font = hb_ft_font_create_referenced(roboto); // TODO: free
182+ hb_font_t *hb_font = hb_ft_font_create_referenced(roboto); // TODO: free
183 hb_shape(hb_font, buffer, features, 1);
184
185 Text text = {
193 atlas_add_chars(&atlas, text.glyph_count, text.glyphs_infos, style);
194 pthread_mutex_unlock(&freetype_mutex);
195
196- DrawCall* draw_call = alba_array_last(&window->draw_calls);
197- if (draw_call->texture_set)
198- {
199+ DrawCall *draw_call = alba_array_last(&window->draw_calls);
200+ if (draw_call->texture_set) {
201 draw_call = window_create_draw_call(window);
202 }
203 alba_array_append(&draw_call->new_texts, &text);
src/window.c M +70 -106
17 void on_receive_adapter(
18 const WGPURequestAdapterStatus status,
19 const WGPUAdapter adapter,
20- char const* message,
21- void* data
22-)
23-{
24- if (status != WGPURequestAdapterStatus_Success)
25- {
26+ char const *message,
27+ void *data
28+) {
29+ if (status != WGPURequestAdapterStatus_Success) {
30 fprintf(stderr, "error: requesting adapter failed: %s", message);
31 exit(1);
32 }
33
34- *((WGPUAdapter*)data) = adapter;
35+ *((WGPUAdapter *) data) = adapter;
36 }
37
38-void on_device_lost_error(const WGPUDeviceLostReason reason, char const* message, void* userdata)
39-{
40+void on_device_lost_error(const WGPUDeviceLostReason reason, char const *message, void *userdata) {
41 fprintf(stderr, "error: device lost error (%d): %s", reason, message);
42 exit(1);
43 }
36 void on_receive_device(
37 const WGPURequestDeviceStatus status,
38 const WGPUDevice device,
39- char const* message,
40- void* data
41-)
42-{
43- if (status != WGPURequestDeviceStatus_Success)
44- {
45+ char const *message,
46+ void *data
47+) {
48+ if (status != WGPURequestDeviceStatus_Success) {
49 fprintf(stderr, "error: requesting device failed: %s", message);
50 exit(1);
51 }
52
53- *((WGPUDevice*)data) = device;
54+ *((WGPUDevice *) data) = device;
55 }
56
57-void on_error(const WGPUErrorType type, char const* message, void* data)
58-{
59- if (type == WGPUErrorType_NoError)
60- {
61+void on_error(const WGPUErrorType type, char const *message, void *data) {
62+ if (type == WGPUErrorType_NoError) {
63 return;
64 }
65 fprintf(stderr, "error (%d): %s", type, message);
66 }
67
68
69-void create_uniform_bind_group(AlbaWindow* window, const WGPUBindGroupLayout bind_group_layout)
70-{
71+void create_uniform_bind_group(AlbaWindow *window, const WGPUBindGroupLayout bind_group_layout) {
72 const float uniforms_default_value[2] = {1, 1};
73 window->uniforms = create_buffer(
74 window,
76 window->uniforms_bind_group = wgpuDeviceCreateBindGroup(window->device, &binding_group_options);
77 }
78
79-WGPUPipelineLayout configure_bind_group_layout(AlbaWindow* window)
80-{
81+WGPUPipelineLayout configure_bind_group_layout(AlbaWindow *window) {
82 WGPUBindGroupLayout bind_groups[2];
83
84 // @group(0) - Uniforms (scale)
130 }
131
132
133-void configure_surface(AlbaWindow* window)
134-{
135+void configure_surface(AlbaWindow *window) {
136 int width, height;
137 float x_scale, y_scale;
138 glfwGetWindowSize(window->glfw_window, &width, &height);
146 // Update uniforms
147 wgpuQueueWriteBuffer(window->queue, window->uniforms, 0, &scaled_size, sizeof(AlbaVector));
148
149- const WGPUTextureFormat format = wgpuSurfaceGetPreferredFormat(window->surface, window->adapter);
150-
151 WGPUSurfaceConfiguration surface_options = {0};
152 surface_options.device = window->device;
153- surface_options.format = format;
154+ surface_options.format = window->surface_format;
155 surface_options.usage = WGPUTextureUsage_RenderAttachment;
156 surface_options.presentMode = WGPUPresentMode_Fifo;
157 surface_options.width = width;
156 wgpuSurfaceConfigure(window->surface, &surface_options);
157 }
158
159-void configure_pipeline(AlbaWindow* window)
160-{
161+void configure_pipeline(AlbaWindow *window) {
162 // Load shaders
163 // --------------------------------------------
164 WGPUShaderModuleWGSLDescriptor shader_options = {0};
164 shader_options.code = _binary_shaders_wgsl_start;
165
166 WGPUShaderModuleDescriptor shader_loader_options = {0};
167- shader_loader_options.nextInChain = (WGPUChainedStruct*)&shader_options;
168+ shader_loader_options.nextInChain = (WGPUChainedStruct *) &shader_options;
169
170 window->shaders = wgpuDeviceCreateShaderModule(window->device, &shader_loader_options);
171
229 }
230 };
231 WGPUColorTargetState color_state = {0};
232- color_state.format = WGPUTextureFormat_BGRA8UnormSrgb; // TODO: avoid hardcoding
233+ color_state.format = window->surface_format;
234 color_state.blend = &blend_state;
235 color_state.writeMask = WGPUColorWriteMask_All;
236 WGPUFragmentState fragment_state = {0};
247 wgpuPipelineLayoutRelease(pipleine_options.layout);
248 }
249
250-AlbaWindow* alba_create_window(const AlbaWindowOptions* options)
251-{
252+AlbaWindow *alba_create_window(const AlbaWindowOptions *options) {
253 pthread_mutex_lock(&glfw_mutex);
254- if (!glfw_initialized)
255- {
256- if (!glfwInit())
257- {
258- fprintf(stderr, "error: initializeing GLFW failed");
259+ if (!glfw_initialized) {
260+ if (!glfwInit()) {
261+ fprintf(stderr, "error: initializing GLFW failed");
262 pthread_mutex_unlock(&glfw_mutex);
263 exit(1);
264 }
260 pthread_mutex_unlock(&glfw_mutex);
261
262 const AlbaWindowOptions default_options = {0};
263- if (options == NULL)
264- {
265+ if (options == NULL) {
266 options = &default_options;
267 }
268
269- AlbaWindow* window = calloc(1, sizeof(AlbaWindow));
270+ AlbaWindow *window = calloc(1, sizeof(AlbaWindow));
271 memset(window, 0, sizeof(AlbaWindow));
272
273 window->options = *options;
307 window->queue = wgpuDeviceGetQueue(window->device);
308 window->command_encoder = wgpuDeviceCreateCommandEncoder(window->device, NULL);
309
310+ // Detect format in advance as it's used both to configure the pipeline and the surface
311+ window->surface_format = wgpuSurfaceGetPreferredFormat(window->surface, window->adapter);
312 configure_pipeline(window);
313 configure_surface(window);
314
318 return window;
319 }
320
321-uint32_t alba_window_should_close(const AlbaWindow* window)
322-{
323+uint32_t alba_window_should_close(const AlbaWindow *window) {
324 const int should_close = glfwWindowShouldClose(window->glfw_window);
325- if (!should_close)
326- {
327+ if (!should_close) {
328 glfwWaitEventsTimeout(0.01);
329 }
330 return should_close;
331 }
332
333-void alba_window_release(AlbaWindow* window)
334-{
335- for (uint64_t i = 0; i < window->draw_calls.length; i++)
336- {
337+void alba_window_release(AlbaWindow *window) {
338+ for (uint64_t i = 0; i < window->draw_calls.length; i++) {
339 draw_call_release(window->draw_calls.data + i);
340 }
341 alba_array_release(&window->draw_calls);
347 free(window);
348 }
349
350-uint32_t frame_status_is_valid(const WGPUSurfaceTexture frame)
351-{
352- switch (frame.status)
353- {
354- case WGPUSurfaceGetCurrentTextureStatus_Success:
355- break;
356- case WGPUSurfaceGetCurrentTextureStatus_Timeout:
357- case WGPUSurfaceGetCurrentTextureStatus_Outdated:
358- case WGPUSurfaceGetCurrentTextureStatus_Lost:
359- return 0;
360- case WGPUSurfaceGetCurrentTextureStatus_OutOfMemory:
361- fprintf(stderr, "error: frame allocation failed due to insufficient memory (%d)\n",
362- frame.status);
363- case WGPUSurfaceGetCurrentTextureStatus_DeviceLost:
364- fprintf(stderr, "error: device lost (%d)\n", frame.status);
365- case WGPUSurfaceGetCurrentTextureStatus_Force32:
366- fprintf(stderr, "error: force 32 error (%d)\n", frame.status);
367- exit(1);
368+uint32_t frame_status_is_valid(const WGPUSurfaceTexture frame) {
369+ switch (frame.status) {
370+ case WGPUSurfaceGetCurrentTextureStatus_Success:
371+ break;
372+ case WGPUSurfaceGetCurrentTextureStatus_Timeout:
373+ case WGPUSurfaceGetCurrentTextureStatus_Outdated:
374+ case WGPUSurfaceGetCurrentTextureStatus_Lost:
375+ return 0;
376+ case WGPUSurfaceGetCurrentTextureStatus_OutOfMemory:
377+ fprintf(stderr, "error: frame allocation failed due to insufficient memory (%d)\n",
378+ frame.status);
379+ case WGPUSurfaceGetCurrentTextureStatus_DeviceLost:
380+ fprintf(stderr, "error: device lost (%d)\n", frame.status);
381+ case WGPUSurfaceGetCurrentTextureStatus_Force32:
382+ fprintf(stderr, "error: force 32 error (%d)\n", frame.status);
383+ exit(1);
384 }
385
386 return 1;
387 }
388
389
390-void copy_color(const AlbaColor src, WGPUColor* dst)
391-{
392+void copy_color(const AlbaColor src, WGPUColor *dst) {
393 dst->r = src.r;
394 dst->g = src.g;
395 dst->b = src.b;
377 }
378
379 void ensure_draw_call_updated(
380- const AlbaWindow* window,
381- DrawCall* draw_call
382-)
383-{
384- if (draw_call->text_dirty)
385- {
386+ const AlbaWindow *window,
387+ DrawCall *draw_call
388+) {
389+ if (draw_call->text_dirty) {
390 pthread_mutex_lock(&freetype_mutex);
391 atlas_generate_image(&atlas);
392 pthread_mutex_unlock(&freetype_mutex);
400 draw_call->text_dirty = 0;
401 }
402
403- if (draw_call->buffers_dirty)
404- {
405+ if (draw_call->buffers_dirty) {
406 draw_call->vertices = update_buffer(
407 window, draw_call->vertices, WGPUBufferUsage_Vertex, draw_call->new_vertices);
408 draw_call->attributes = update_buffer(
411 draw_call->buffers_dirty = 0;
412 }
413
414- if (draw_call->bind_group_dirty)
415- {
416+ if (draw_call->bind_group_dirty) {
417 draw_call_update_bind_group(window, draw_call);
418 draw_call->bind_group_dirty = 0;
419 }
420 }
421
422 void draw_objects(
423- const AlbaWindow* window,
424+ const AlbaWindow *window,
425 const WGPUCommandEncoder command_encoder,
426 const WGPURenderPassEncoder render_pass
427-)
428-{
429+) {
430 wgpuRenderPassEncoderSetPipeline(render_pass, window->pipeline);
431 wgpuRenderPassEncoderSetBindGroup(render_pass, 0, window->uniforms_bind_group, 0, NULL);
432
433- for (uint64_t i = 0; i < window->draw_calls.length; i++)
434- {
435- DrawCall* draw_call = window->draw_calls.data + i;
436+ for (uint64_t i = 0; i < window->draw_calls.length; i++) {
437+ DrawCall *draw_call = window->draw_calls.data + i;
438
439 ensure_draw_call_updated(window, draw_call);
440 wgpuRenderPassEncoderSetBindGroup(render_pass, 1, draw_call->bind_group, 0, NULL);
434 const uint32_t vertex_size = wgpuBufferGetSize(draw_call->vertices);
435 const uint32_t attributes_size = wgpuBufferGetSize(draw_call->attributes);
436 const uint32_t indices_size = wgpuBufferGetSize(draw_call->indices);
437- if (vertex_size > 0)
438- {
439+ if (vertex_size > 0) {
440 wgpuRenderPassEncoderSetVertexBuffer(
441 render_pass, 0, draw_call->vertices, 0, vertex_size);
442 wgpuRenderPassEncoderSetVertexBuffer(
454 wgpuCommandBufferRelease(command);
455 }
456
457-void alba_window_render(AlbaWindow* window)
458-{
459+void alba_window_render(AlbaWindow *window) {
460 // Setup textures for rendering
461 // --------------------------------------------
462 WGPUSurfaceTexture frame;
463 wgpuSurfaceGetCurrentTexture(window->surface, &frame);
464- if (!frame_status_is_valid(frame))
465- {
466+ if (!frame_status_is_valid(frame)) {
467 // Re-configure surface and skip frame
468- if (frame.texture != NULL)
469- {
470+ if (frame.texture != NULL) {
471 wgpuTextureRelease(frame.texture);
472 }
473
470 }
471
472 const WGPUTextureView frame_view = wgpuTextureCreateView(frame.texture, NULL);
473- if (frame_view == NULL)
474- {
475+ if (frame_view == NULL) {
476 printf("warning: could not get frame view, dropping frame (%d)\n", frame.status);
477 return;
478 }
480 window,
481 WGPUTextureUsage_RenderAttachment,
482 window->size,
483- WGPUTextureFormat_BGRA8UnormSrgb, 4, // TODO: do not assume format
484+ window->surface_format,
485+ 4,
486 NULL
487 );
488 const WGPUTextureView render_target_view = wgpuTextureCreateView(render_target, NULL);
489- if (render_target_view == NULL)
490- {
491+ if (render_target_view == NULL) {
492 printf("warning: could not get texture view, dropping frame\n");
493 return;
494 }
526 }
527
528
529-void alba_window_get_size(const AlbaWindow* window, float* width, float* height)
530-{
531+void alba_window_get_size(const AlbaWindow *window, float *width, float *height) {
532 int raw_width, raw_height;
533 float x_scale, y_scale;
534 glfwGetWindowSize(window->glfw_window, &raw_width, &raw_height);