From ecb38f349349ab369383c51a22f430909a7d2ebd Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 14 Apr 2026 12:45:23 +0300 Subject: [PATCH] gg: gg.update_pixel_data() empty buffer still draws (fixes #10989) --- vlib/gg/streaming_image_gl_test.v | 41 +++++++++++++++++++ .../streaming_r8_zero_buffer_issue_10989.vv | 37 +++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 vlib/gg/streaming_image_gl_test.v create mode 100644 vlib/gg/testdata/streaming_r8_zero_buffer_issue_10989.vv diff --git a/vlib/gg/streaming_image_gl_test.v b/vlib/gg/streaming_image_gl_test.v new file mode 100644 index 000000000..e1e8479d9 --- /dev/null +++ b/vlib/gg/streaming_image_gl_test.v @@ -0,0 +1,41 @@ +// vtest build: macos && !sanitized_job? +import os +import stbi + +@[direct_array_access] +fn png_has_non_black_pixels(path string) !bool { + img := stbi.load(path)! + defer { + img.free() + } + for i in 0 .. img.width * img.height { + unsafe { + if img.data[i * 4] != 0 || img.data[i * 4 + 1] != 0 || img.data[i * 4 + 2] != 0 { + return true + } + } + } + return false +} + +fn test_streaming_r8_zero_buffer_stays_black_on_gl_backend() { + vexe := @VEXE + vroot := os.dir(vexe) + sample_path := os.join_path(vroot, 'vlib/gg/testdata/streaming_r8_zero_buffer_issue_10989.vv') + temp_dir := os.join_path(os.temp_dir(), 'v_gg_issue_10989_${os.getpid()}') + os.mkdir_all(temp_dir) or { panic(err) } + defer { + os.rmdir_all(temp_dir) or {} + } + exe_path := os.join_path(temp_dir, 'issue10989_repro') + // Force the GL backend so this exercises the packed texture upload path from issue #10989. + compile_cmd := '${os.quoted_path(vexe)} -d gg_record -d darwin_sokol_glcore33 -o ${os.quoted_path(exe_path)} ${os.quoted_path(sample_path)}' + compile_res := os.execute(compile_cmd) + assert compile_res.exit_code == 0, compile_res.output + run_cmd := 'VGG_STOP_AT_FRAME=2 VGG_SCREENSHOT_FRAMES=2 VGG_SCREENSHOT_FOLDER=${os.quoted_path(temp_dir)} ${os.quoted_path(exe_path)}' + run_res := os.execute(run_cmd) + assert run_res.exit_code == 0, run_res.output + screenshot_path := os.join_path(temp_dir, 'issue10989_repro_2.png') + assert os.exists(screenshot_path) + assert png_has_non_black_pixels(screenshot_path)! == false +} diff --git a/vlib/gg/testdata/streaming_r8_zero_buffer_issue_10989.vv b/vlib/gg/testdata/streaming_r8_zero_buffer_issue_10989.vv new file mode 100644 index 000000000..607bd3f53 --- /dev/null +++ b/vlib/gg/testdata/streaming_r8_zero_buffer_issue_10989.vv @@ -0,0 +1,37 @@ +module main + +import gg + +const win_width = 100 +const win_height = 100 + +struct App { +mut: + gg &gg.Context = unsafe { nil } + image int +} + +fn main() { + mut app := &App{} + app.gg = gg.new_context( + width: win_width + height: win_height + window_title: 'issue 10989' + frame_fn: frame + user_data: app + init_fn: initialize + ) + app.gg.run() +} + +fn initialize(mut app App) { + buffer := []u8{len: 10 * 10} + app.image = app.gg.new_streaming_image(10, 10, 1, pixel_format: .r8) + app.gg.update_pixel_data(app.image, buffer.data) +} + +fn frame(mut app App) { + app.gg.begin() + app.gg.draw_image_by_id(0, 0, 10, 10, app.image) + app.gg.end() +} -- 2.39.5