Merge pull request 'Fix leak in canvas code and samples' (#60) from fix_canvas_leak into main

Reviewed-on: #60
This commit is contained in:
MartinFouilleul 2023-08-23 14:33:22 +00:00
commit d3e27df818
8 changed files with 67 additions and 31 deletions

View File

@ -56,7 +56,9 @@ oc_str8 loadFile(oc_arena* arena, oc_str8 filename)
oc_file file = oc_file_open(filename, OC_FILE_ACCESS_READ, 0); oc_file file = oc_file_open(filename, OC_FILE_ACCESS_READ, 0);
if(oc_file_last_error(file) != OC_IO_OK) if(oc_file_last_error(file) != OC_IO_OK)
{ {
oc_log_error("Couldn't open file %s\n", oc_str8_to_cstring(oc_scratch(), filename)); oc_arena_scope scope = oc_arena_scope_begin(arena);
oc_log_error("Couldn't open file %s\n", oc_str8_to_cstring(arena, filename));
oc_arena_scope_end(scope);
} }
u64 size = oc_file_size(file); u64 size = oc_file_size(file);
char* buffer = oc_arena_push(arena, size); char* buffer = oc_arena_push(arena, size);
@ -347,6 +349,8 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
oc_surface_select(surface); oc_surface_select(surface);
oc_render(surface, canvas); oc_render(surface, canvas);
oc_surface_present(surface); oc_surface_present(surface);
oc_arena_clear(oc_scratch());
} }
oc_rect blockRect(int i) oc_rect blockRect(int i)

View File

@ -393,4 +393,6 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
oc_ui_draw(); oc_ui_draw();
oc_render(surface, canvas); oc_render(surface, canvas);
oc_surface_present(surface); oc_surface_present(surface);
oc_arena_clear(oc_scratch());
} }

View File

@ -22,6 +22,7 @@ def init_parser(parser):
parser.add_argument("-n", "--name", default="out", help="the app's name") parser.add_argument("-n", "--name", default="out", help="the app's name")
parser.add_argument("-O", "--orca-dir", default=".") parser.add_argument("-O", "--orca-dir", default=".")
parser.add_argument("--version", default="0.0.0", help="a version number to embed in the application bundle") parser.add_argument("--version", default="0.0.0", help="a version number to embed in the application bundle")
parser.add_argument("--mtl-enable-capture", action='store_true', help="Enable Metal frame capture for the application bundle (macOS only)")
parser.add_argument("module", help="a .wasm file containing the application's wasm module") parser.add_argument("module", help="a .wasm file containing the application's wasm module")
parser.set_defaults(func=shellish(make_app)) parser.set_defaults(func=shellish(make_app))
@ -169,8 +170,13 @@ def macos_make_app(args):
<string>icon.icns</string> <string>icon.icns</string>
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
<string>True</string> <string>True</string>
"""
if args.mtl_enable_capture == True:
plist_contents += f"""
<key>MetalCaptureEnabled</key> <key>MetalCaptureEnabled</key>
<true/> <true/>"""
plist_contents += f"""
</dict> </dict>
</plist> </plist>
""" """

View File

@ -451,15 +451,15 @@ void oc_install_keyboard_layout_listener()
event.window = (oc_window){ 0 }; event.window = (oc_window){ 0 };
event.type = OC_EVENT_PATHDROP; event.type = OC_EVENT_PATHDROP;
oc_arena* scratch = oc_scratch(); oc_arena_scope scratch = oc_scratch_begin();
oc_arena_scope scope = oc_arena_scope_begin(scratch);
oc_str8 path = oc_str8_push_cstring(scratch, [filename UTF8String]); oc_str8 path = oc_str8_push_cstring(scratch.arena, [filename UTF8String]);
oc_str8_list_push(scratch, &event.paths, path); oc_str8_list_push(scratch.arena, &event.paths, path);
oc_queue_event(&event); oc_queue_event(&event);
oc_arena_scope_end(scope); //NOTE: oc_queue_event copies paths to the event queue, so we can clear the arena scope here
oc_scratch_end(scratch);
return (YES); return (YES);
} }
@ -472,15 +472,15 @@ void oc_install_keyboard_layout_listener()
event.window = (oc_window){ 0 }; event.window = (oc_window){ 0 };
event.type = OC_EVENT_PATHDROP; event.type = OC_EVENT_PATHDROP;
oc_arena* scratch = oc_scratch(); oc_arena_scope scratch = oc_scratch_begin();
oc_arena_scope scope = oc_arena_scope_begin(scratch);
oc_str8 path = oc_str8_push_cstring(scratch, [nsPath UTF8String]); oc_str8 path = oc_str8_push_cstring(scratch.arena, [nsPath UTF8String]);
oc_str8_list_push(scratch, &event.paths, path); oc_str8_list_push(scratch.arena, &event.paths, path);
oc_queue_event(&event); oc_queue_event(&event);
oc_arena_scope_end(scope); //NOTE: oc_queue_event copies paths to the event queue, so we can clear the arena scope here
oc_scratch_end(scratch);
} }
//TODO: drag and drop paths //TODO: drag and drop paths
@ -1536,7 +1536,6 @@ void oc_window_restore(oc_window window)
} }
} }
void oc_window_send_to_back(oc_window window) void oc_window_send_to_back(oc_window window)
{ {
@autoreleasepool @autoreleasepool

View File

@ -719,8 +719,8 @@ oc_rect oc_text_bounding_box_utf32(oc_font font, f32 fontSize, oc_str32 codePoin
return ((oc_rect){ 0 }); return ((oc_rect){ 0 });
} }
oc_arena* scratch = oc_scratch(); oc_arena_scope scratch = oc_scratch_begin();
oc_str32 glyphIndices = oc_font_push_glyph_indices(font, scratch, codePoints); oc_str32 glyphIndices = oc_font_push_glyph_indices(font, scratch.arena, codePoints);
//NOTE(martin): find width of missing character //NOTE(martin): find width of missing character
//TODO(martin): should cache that at font creation... //TODO(martin): should cache that at font creation...
@ -789,6 +789,8 @@ oc_rect oc_text_bounding_box_utf32(oc_font font, f32 fontSize, oc_str32 codePoin
f32 fontScale = oc_font_get_scale_for_em_pixels(font, fontSize); f32 fontScale = oc_font_get_scale_for_em_pixels(font, fontSize);
oc_rect rect = { 0, -fontData->extents.ascent * fontScale, width * fontScale, (y + lineHeight) * fontScale }; oc_rect rect = { 0, -fontData->extents.ascent * fontScale, width * fontScale, (y + lineHeight) * fontScale };
oc_scratch_end(scratch);
return (rect); return (rect);
} }
@ -799,9 +801,11 @@ oc_rect oc_text_bounding_box(oc_font font, f32 fontSize, oc_str8 text)
return ((oc_rect){ 0 }); return ((oc_rect){ 0 });
} }
oc_arena* scratch = oc_scratch(); oc_arena_scope scratch = oc_scratch_begin();
oc_str32 codePoints = oc_utf8_push_to_codepoints(scratch, text); oc_str32 codePoints = oc_utf8_push_to_codepoints(scratch.arena, text);
return (oc_text_bounding_box_utf32(font, fontSize, codePoints)); oc_rect result = oc_text_bounding_box_utf32(font, fontSize, codePoints);
oc_scratch_end(scratch);
return (result);
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -1353,8 +1357,12 @@ void oc_codepoints_outlines(oc_str32 codePoints)
return; return;
} }
oc_str32 glyphIndices = oc_font_push_glyph_indices(canvas->attributes.font, oc_scratch(), codePoints); oc_arena_scope scratch = oc_scratch_begin();
oc_str32 glyphIndices = oc_font_push_glyph_indices(canvas->attributes.font, scratch.arena, codePoints);
oc_glyph_outlines_from_font_data(fontData, glyphIndices); oc_glyph_outlines_from_font_data(fontData, glyphIndices);
oc_scratch_end(scratch);
} }
void oc_text_outlines(oc_str8 text) void oc_text_outlines(oc_str8 text)
@ -1370,11 +1378,13 @@ void oc_text_outlines(oc_str8 text)
return; return;
} }
oc_arena* scratch = oc_scratch(); oc_arena_scope scratch = oc_scratch_begin();
oc_str32 codePoints = oc_utf8_push_to_codepoints(scratch, text); oc_str32 codePoints = oc_utf8_push_to_codepoints(scratch.arena, text);
oc_str32 glyphIndices = oc_font_push_glyph_indices(canvas->attributes.font, scratch, codePoints); oc_str32 glyphIndices = oc_font_push_glyph_indices(canvas->attributes.font, scratch.arena, codePoints);
oc_glyph_outlines_from_font_data(fontData, glyphIndices); oc_glyph_outlines_from_font_data(fontData, glyphIndices);
oc_scratch_end(scratch);
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -1579,7 +1589,9 @@ oc_image oc_image_create_from_file(oc_surface surface, oc_str8 path, bool flip)
oc_image image = oc_image_nil(); oc_image image = oc_image_nil();
int width, height, channels; int width, height, channels;
const char* cpath = oc_str8_to_cstring(oc_scratch(), path); oc_arena_scope scratch = oc_scratch_begin();
const char* cpath = oc_str8_to_cstring(scratch.arena, path);
stbi_set_flip_vertically_on_load(flip ? 1 : 0); stbi_set_flip_vertically_on_load(flip ? 1 : 0);
u8* pixels = stbi_load(cpath, &width, &height, &channels, 4); u8* pixels = stbi_load(cpath, &width, &height, &channels, 4);
@ -1592,6 +1604,8 @@ oc_image oc_image_create_from_file(oc_surface surface, oc_str8 path, bool flip)
{ {
oc_log_error("stbi_load() failed: %s\n", stbi_failure_reason()); oc_log_error("stbi_load() failed: %s\n", stbi_failure_reason());
} }
oc_scratch_end(scratch);
return (image); return (image);
} }
@ -1719,9 +1733,13 @@ oc_image_region oc_image_atlas_alloc_from_file(oc_rect_atlas* atlas, oc_image ba
stbi_set_flip_vertically_on_load(flip ? 1 : 0); stbi_set_flip_vertically_on_load(flip ? 1 : 0);
const char* cpath = oc_str8_to_cstring(oc_scratch(), path); oc_arena_scope scratch = oc_scratch_begin();
const char* cpath = oc_str8_to_cstring(scratch.arena, path);
int width, height, channels; int width, height, channels;
u8* pixels = stbi_load(cpath, &width, &height, &channels, 4); u8* pixels = stbi_load(cpath, &width, &height, &channels, 4);
oc_scratch_end(scratch);
if(pixels) if(pixels)
{ {
imageRgn = oc_image_atlas_alloc_from_rgba8(atlas, backingImage, width, height, pixels); imageRgn = oc_image_atlas_alloc_from_rgba8(atlas, backingImage, width, height, pixels);

View File

@ -53,11 +53,14 @@ void oc_mtl_surface_destroy(oc_surface_data* interface)
void oc_mtl_surface_acquire_command_buffer(oc_mtl_surface* surface) void oc_mtl_surface_acquire_command_buffer(oc_mtl_surface* surface)
{ {
@autoreleasepool
{
if(surface->commandBuffer == nil) if(surface->commandBuffer == nil)
{ {
surface->commandBuffer = [surface->commandQueue commandBuffer]; surface->commandBuffer = [surface->commandQueue commandBuffer];
[surface->commandBuffer retain]; [surface->commandBuffer retain];
} }
}
} }
void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface) void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface)
@ -102,8 +105,9 @@ void oc_mtl_surface_present(oc_surface_data* interface)
[surface->commandBuffer presentDrawable:surface->drawable]; [surface->commandBuffer presentDrawable:surface->drawable];
[surface->drawable release]; [surface->drawable release];
surface->drawable = nil; surface->drawable = nil;
}
[surface->commandBuffer commit]; [surface->commandBuffer commit];
}
[surface->commandBuffer release]; [surface->commandBuffer release];
surface->commandBuffer = nil; surface->commandBuffer = nil;
} }

View File

@ -11,7 +11,6 @@
oc_io_cmp oc_runtime_io_wait_single_req(oc_io_req* wasmReq) oc_io_cmp oc_runtime_io_wait_single_req(oc_io_req* wasmReq)
{ {
oc_runtime* orca = oc_runtime_get(); oc_runtime* orca = oc_runtime_get();
oc_arena* scratch = oc_scratch();
oc_io_cmp cmp = { 0 }; oc_io_cmp cmp = { 0 };
oc_io_req req = *wasmReq; oc_io_req req = *wasmReq;

View File

@ -848,7 +848,9 @@ const void* glShaderSource_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint6
i32 lengthArrayOffset = *(i32*)&_sp[3]; i32 lengthArrayOffset = *(i32*)&_sp[3];
int* stringOffsetArray = (int*)((char*)_mem + stringArrayOffset); int* stringOffsetArray = (int*)((char*)_mem + stringArrayOffset);
const char** stringArray = (const char**)oc_arena_push_array(oc_scratch(), char*, count);
oc_arena_scope scratch = oc_scratch_begin();
const char** stringArray = (const char**)oc_arena_push_array(scratch.arena, char*, count);
for(int i = 0; i < count; i++) for(int i = 0; i < count; i++)
{ {
stringArray[i] = (char*)_mem + stringOffsetArray[i]; stringArray[i] = (char*)_mem + stringOffsetArray[i];
@ -857,6 +859,8 @@ const void* glShaderSource_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint6
int* lengthArray = lengthArrayOffset ? (int*)((char*)_mem + lengthArrayOffset) : 0; int* lengthArray = lengthArrayOffset ? (int*)((char*)_mem + lengthArrayOffset) : 0;
glShaderSource(shader, count, stringArray, lengthArray); glShaderSource(shader, count, stringArray, lengthArray);
oc_scratch_end(scratch);
return (0); return (0);
} }