c-ray icon indicating copy to clipboard operation
c-ray copied to clipboard

SDL implementation is really inefficient

Open vkoskiv opened this issue 6 years ago • 0 comments

Ideally we wouldn't SDL_RenderCopy the entire image buffers for every frame, but instead update only the currently active tile rectangles. Profiling reveals that a good portion of CPU time is indeed spent on the main thread where it copies the image buffers 60 times a second.

Another option would of course be to just reduce the update loop timing to 20 or 30fps, but I really prefer the smooth 60fps updating, and I think it can be manageable if we just implement this correctly. Another thing is, we're not using SDL_LockTexture at all yet.

I've been prototyping it like this recently, but it's still not working quite right:

void drawWindow(struct renderer *r, struct texture *t) {
	if (aborted) {
		r->state.renderAborted = true;
	}
#ifdef UI_ENABLED
	//Render frames
	updateFrames(r);
	//Update image data
	
	for (int i = 0; i < r->prefs.threadCount; ++i) {
		SDL_Rect rect = fromTile(r->state.renderTiles[r->state.threads[i].currentTileNum]);
		//int offset = rect.x + r->prefs.imageHeight * r->prefs.imageWidth; // (pitch * rect.y) + rect.x
		//int offset = (rect.y * r->prefs.imageWidth) + rect.x * t->channels;
		int offset = (rect.x + (rect.y) * t->width) * t->channels;
		SDL_UpdateTexture(r->mainDisplay->texture, &rect, t->byte_data + offset, t->width * 3);
		SDL_UpdateTexture(r->mainDisplay->overlayTexture, &rect, r->state.uiBuffer->byte_data, t->width * 4);
	}
	
	//SDL_UpdateTexture(r->mainDisplay->texture, NULL, t->byte_data, t->width * 3);
	//SDL_UpdateTexture(r->mainDisplay->overlayTexture, NULL, r->state.uiBuffer->byte_data, t->width * 4);
	SDL_RenderCopy(r->mainDisplay->renderer, r->mainDisplay->texture, NULL, NULL);
	SDL_RenderCopy(r->mainDisplay->renderer, r->mainDisplay->overlayTexture, NULL, NULL);
	SDL_RenderPresent(r->mainDisplay->renderer);
#endif
}

Here it gathers all the actively rendered tiles, generates an SDL_Rect based on them and then tries to update only those regions, but I keep getting the offset wrong for some reason.

vkoskiv avatar Feb 25 '20 01:02 vkoskiv