Saving a screenshot blocks the thread

i am trying to capture a screenshot and share it at the same time on android .
i have used screenshot extension

local random = math.random(100)
local path = sys.get_save_file("MyGame", "screenshot" .. random .. ".png")
local png, w, h = screenshot.png()
		
local f = io.open(path, "wb")
f:write(png)
f:flush()
f:close()

share.file(path)

whenever i call this bloc of code it blocks the game for about 3-4sec on android .
My question is how i can avoid this thread blocking , i have heard about coroutines but i don’t know how to implement that in my case .

Have you measured what is actually taking the time? It could be screenshot.png() as well. But saving a large file is bound to take time as well. Spreading the work over multiple frames using coroutines or a timer would lessen the load. Example using a timer:

local png, w, h = screenshot.png()
local f = io.open(path, "wb")
local offset = 1
local chunk_size = 1024
timer.delay(0, true, function(self, handle, time_elapsed)
	local chunk = png:sub(offset, offset + chunk_size)
	f:write(chunk)
	f:flush()
	offset = offset + chunk_size
	if offset > #png then
		timer.cancel(handle)
	end
end)
f:close()

The above is untested code so there might be problems with it.

I assume this isn’t cheap either, since it has compress the image?

I have tested the screenshot.png() alone without saving it took about 2.5sec

it turns out that the saving task didn’t add that much time .

Indeed, it is probably slower than writing the file to disk.

@MrZak-dev: Use socket.gettime() to measure time

i have measured the time before and after taking screenshot , this is the result
Time for a screenshot 2.4647130966187 , i guess it will vary based on the device performance .
by adding the save task the result was around ±0.05s

That is a very long time to compress a texture.
Anyways, I think it will be difficult to improve upon without any changes to the screenshot extension, e.g. supplying a threaded callback once the screenshot is created.

1 Like