How to enable Vsync with Software Rendering in SDL [SOLVED]. 如何在SDL2下实现垂直同步
Hi, I just figured out the dirty way to enable vsync with software rendering on SDL.
This was bothering me for a week now & I've seen many questions on the net without answer. But I finally figured it out and it's plain and stupid but it works.
It basically uses the Accelerated Renderer only to provide vsync'ed delay for software renderer. So I'm not certain if this will also work on machines with absolutely no acceleration (I have some OpenGl context enabled on my laptop, allthough I have no proper graphics card - have no idea how it works ). But It's worth a try. If the accelerated renderer won't crash your app (it does not have to display anything - just work in the background) - this should work for you.
This is how :
-
The INIT section:
You create your main Window & then create a accelerated renderer with vsync enabled:
Main_Window = SDL_CreateWindow ("hello void",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, w, h,SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS);
renderer = SDL_CreateRenderer(Main_Window,-1,SDL_RENDERER_ACCELERATED|
SDL_RENDERER_PRESENTVSYNC);
Then, as you do in software rendering, you assign a surface from your main window:
SDL Surface * window = SDL_GetWindowSurface(Main_Window);
This surface is your main rendering target for software rendering. You may further create a proper software renderer (if you want to use SDL rendering functions) like this:
SDL_Renderer* soft_renderer = SDL_CreateSoftwareRenderer(window);
Or you can directly access the window surface pixel data, f.ex. for pixel by pixel fast software editing, blitting surfaces, or your invented rendering functions.
Then you create a tiny empty texture (1 pix by 1pix) to update to accelerated renderer:
texture = SDL_CreateTexture(renderer, window->format->format, SDL_TEXTUREACCESS_STREAMING, 1, 1);
Then you create a tiny 1 pix SDL_Rect structure like this:
SDL_Rect onepix_rect;
onepix_rect.h=1;
onepix_rect.w=1;
onepix_rect.x=0;
onepix_rect.y=0;
2. Then what you do in the PICTURE UPDATE loop:
Normally for software rendering you would use
SDL_UpdateWindowSurface(Main_Window);
Now - to get it to Vsync you put it right after SDL_RenderPresent(renderer) :
SDL_RenderCopy(renderer, texture, NULL, &onepix_rect);
SDL_RenderPresent(renderer);
SDL_UpdateWindowSurface(Main_Window);
In this way accelerated renderer provides a delay for the update loop & prevents picture tearing.
I guess how it works is the Acc_Renderer triggers on vsync but after it finishes uptade of 1 tiny texture there is still enough time for the UpdateWindow function to fit in the VBlank period of the screen.
You no longer have to put any framerate caps on the update loop.
If you want to further halve the number of frames (from the usual 60fps to 30fps),
You add another line like this which provides another delay:
SDL_RenderCopy(renderer, texture, NULL, &onepix_rect);
SDL_RenderPresent(renderer);
SDL_RenderPresent(renderer);
SDL_UpdateWindowSurface(Main_Window);
Or you can simply add any chosen delay in the loop.
If you manage to squeeze anything else in the picture update loop below 11ms or so, you will always reach 60 fps. Any more delay in the loop will simply lower your frame rate but won't ever cause picture tearing.
I know it's stupid and dirty hack, but it works and it enables you to edit surface pixels & update them to the window without conversion to textures - without picture tearing - and this is what was missing in software rendering for me.
Now I can confidently say the full functionality of Acc_Rendering can be applied to soft_rendering. And this is somehow pleasing to me.
Maybe this is something irrelevant (who the hell uses soft_rendering anyway - right?) but I just wanted to leave this solution somewhere if anyone was wondering like I did how to do it, because they are trying out SDL on computer without proper graphics card, or want to simplify their app by using just surfaces. Now You can do it without picture tearing. So cheers!
If you found this helpful future person, please leave a comment, it will make my day!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」