This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
oeed's profile picture

Speed Improvements of using a Buffer

Started by oeed, 16 March 2013 - 01:49 AM
oeed #1
Posted 16 March 2013 - 02:49 AM
I've been working on making a display buffer. However, the method I have used actually reduces the frame rate.
Just drawing the character I averaged 195 FPS, doing the buffer calculations I got 150FPS. Now, that is a large margin, especially considering that there was only about 100 characters on the screen.

Here is the code I am using to draw my buffer (note that a 'pixel' contains 3 indexes, character, text colour and background colour)


for y,row in pairs(Drawing.Buffer) do
   for x,pixel in pairs(row) do
	--this needs to be fixed, ive done some benchmarks and...
	--this method averaged 150-160 fps
	--just drawing it averaged 190-200fps
	local shouldDraw = false
	local hasBackBuffer = true
	if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then
	 hasBackBuffer = false
	end
	if hasBackBuffer and Drawing.BackBuffer[y][x][1] == Drawing.Buffer[y][x][1] and Drawing.BackBuffer[y][x][2] == Drawing.Buffer[y][x][2] and Drawing.BackBuffer[y][x][3] == Drawing.Buffer[y][x][3] then
	 shouldDraw = false
	end
	if shouldDraw then
	 term.setBackgroundColour(pixel[3])
	 term.setTextColour(pixel[2])
	 term.setCursorPos(x, y)
	 term.write(pixel[1])
	end
   end
  end
  Drawing.BackBuffer = Drawing.Buffer

So essentially, what I am asking is, is it actually slower to use a buffer or have I just made a bad implementation (most likely)
GopherAtl #2
Posted 16 March 2013 - 03:54 AM
of course it's slower, you're doing more work. You don't do buffering to be faster. In graphics in general, you do buffering to prevent tearing or flickering, which is caused by a single redraw of the screen being spread over multiple hardware refreshes to the screen; you avoid that by doign your slower drawing operations to a back buffer in memory, then doing a much faster operation to copy or swap the back buffer to the front. In the case of cc, the "hardware" refreshes are actually the sending of the screen data to the clients, so in cc there is a secondary purpose, to eliminate useless bandwidth use by not sending lines to the client for redrawing unless they've actually changed.
Lyqyd #3
Posted 16 March 2013 - 03:56 AM
Not a terrible implementation, though I hope you are re-initializing Buffer each time. Assignment with tables just copies the reference, so you're making buffer and back buffer point to the same table at the end there, not copying it. It is worth noting that drawing the longest string possible makes for quicker draws, since the screen updates always send a whole line to the clients to display.

Also, if you're compositing buffers together, draw them into an output buffer before you draw that to the screen.

Edit: Also, why are you still triple-indexing in your loops?! pixel[1], not Drawing.Buffer[x][y][1].
oeed #4
Posted 16 March 2013 - 10:25 AM
Ok, yea, I realised later on that it probably had something to do with bandwidth. I'll try to improve it base on what you've said Lydyd

Thanks