VSYNC with 2 windows in SDL2

Hello,
I am trying to make 2 windowed program, but when i try to VSYNC this two windows drawn window is are unsynchronized.
I am drawing in one thread.
while (!quit)
{

//usleep (13000);
for (int i = 0; i < 2; i++)
{
	count[i]+=10;
	if (count[i] >= win[i]->Rect().w)
		count[i] = 0;

	rend[i]->Clear();

	 pic[i]->DrawToWindow(rect);

	 rend[i]->SetColor(255,255,255,255);
	rend[i]->DrawLine(0 + count[i],0, 0 + count[i],win[i]->Rect().w,5);

	rend[i]->SetColor(255,0,0,125);
	rend[i]->DrawRect(155,155,200,200,true);

	//win[i]->Flush();
            rend[i]->Present();
}

}

I am writing a wrapper to sdl functions.
when i create Windows i use -> SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN
when i create Render i use SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC flags.
I am think that the SDL_RenderPresent wait to sync with monitor and thats why the second present on second screen become is too late and become unstable.
Is there a way to Present two screens at same time, not to wait vsync on first and then present on second. :?

I am think that the SDL_RenderPresent wait to sync with monitor and
thats why the second present on second screen become is too late and
become unstable.

Yes, that’s correct, the Present waits for vsync, so the second Present
call will wait for the next vsync, so you’ll always be one frame out
of sync between the two windows.

I’m not sure there’s a good way to accomplish what you’d like in SDL at
the moment. I suppose you could set only the second window to wait for
vsync, but I can’t say for certain if this would work (and that it would
always work).

Does it have to be two windows? Perhaps make one window and draw twice,
with two different viewports, left and right, and Present once?

–ryan.

Hi,

maybe it will work if you move the Present calls out of the loop and use VSYNC
only on the first window:

for (int i =…) {
// … render to window i
}
rend[0]->Present(); // renderer 0 configured with VSYNC
rend[1]->Present(); // without VSYNC

If the Present calls are quick enough, the second window might benefit from the
VSYNC done for the first window.

It’s just an idea - I have no knowledge about this part of SDL at the moment.

Extended idea: You might VSYNC the window which is closer to the top of the
screen (if VSYNC still works that way, in the days of LCD).On 11.03.2014 17:35, mediata wrote:

Hello,
I am trying to make 2 windowed program, but when i try to VSYNC this two windows drawn window is are unsynchronized.
I am drawing in one thread.
while (!quit)
{

//usleep (13000);
for (int i = 0; i < 2; i++)
{
count[i]+=10;
if (count[i] >= win[i]->Rect().w)
count[i] = 0;

  	rend[i]->Clear();

   pic[i]->DrawToWindow(rect);

   rend[i]->SetColor(255,255,255,255);
  rend[i]->DrawLine(0 + count[i],0, 0 + count[i],win[i]->Rect().w,5);

  rend[i]->SetColor(255,0,0,125);
  rend[i]->DrawRect(155,155,200,200,true);

  //win[i]->Flush();
             rend[i]->Present();

}
}

I am writing a wrapper to sdl functions.
when i create Windows i use -> SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN
when i create Render i use SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC flags.
I am think that the SDL_RenderPresent wait to sync with monitor and thats why the second present on second screen become is too late and become unstable.
Is there a way to Present two screens at same time, not to wait vsync on first and then present on second. :?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

In plain OpenGL you could make the two contexts current on separate threads
and use VSync on both. Would this be possible
when using the rendering API?

2014-03-12 0:54 GMT+01:00 Martin <name.changed.by.editors at online.de>:> Hi,

maybe it will work if you move the Present calls out of the loop and use
VSYNC only on the first window:

for (int i =…) {
// … render to window i
}
rend[0]->Present(); // renderer 0 configured with VSYNC
rend[1]->Present(); // without VSYNC

If the Present calls are quick enough, the second window might benefit
from the VSYNC done for the first window.

It’s just an idea - I have no knowledge about this part of SDL at the
moment.

Extended idea: You might VSYNC the window which is closer to the top of
the screen (if VSYNC still works that way, in the days of LCD).

On 11.03.2014 17:35, mediata wrote:

Hello,
I am trying to make 2 windowed program, but when i try to VSYNC this two
windows drawn window is are unsynchronized.
I am drawing in one thread.
while (!quit)
{

    //usleep (13000);
    for (int i = 0; i < 2; i++)
    {
            count[i]+=10;
            if (count[i] >= win[i]->Rect().w)
                    count[i] = 0;

            rend[i]->Clear();

             pic[i]->DrawToWindow(rect);

             rend[i]->SetColor(255,255,255,255);
            rend[i]->DrawLine(0 + count[i],0, 0 +

count[i],win[i]->Rect().w,5);

            rend[i]->SetColor(255,0,0,125);
            rend[i]->DrawRect(155,155,200,200,true);

            //win[i]->Flush();
             rend[i]->Present();
    }

}

I am writing a wrapper to sdl functions.
when i create Windows i use -> SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN
when i create Render i use SDL_RENDERER_ACCELERATED |
SDL_RENDERER_PRESENTVSYNC flags.
I am think that the SDL_RenderPresent wait to sync with monitor and thats
why the second present on second screen become is too late and become
unstable.
Is there a way to Present two screens at same time, not to wait vsync on
first and then present on second. :?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Ryan C. Gordon wrote:

I am think that the SDL_RenderPresent wait to sync with monitor and
thats why the second present on second screen become is too late and
become unstable.

Yes, that’s correct, the Present waits for vsync, so the second Present
call will wait for the next vsync, so you’ll always be one frame out
of sync between the two windows.

I’m not sure there’s a good way to accomplish what you’d like in SDL at
the moment. I suppose you could set only the second window to wait for
vsync, but I can’t say for certain if this would work (and that it would
always work).

Does it have to be two windows? Perhaps make one window and draw twice,
with two different viewports, left and right, and Present once?

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Okay, but when i try this two methods i have problem again with vsync -> in second monitor i have no correct vertical sync. I tried with 2 process and i have no problem with vertical sync on second display. Where do i wrong? Why with one process i cant vsync two monitors but with two i have no problems.

If we’re dealing with two monitors, I’m not sure it’s a great idea to
assume they’re synchronized (that would require cooperation between the
RAMDACs, video cards and drivers involved), or even running at the same
refresh rate…!

For example, when I occasionally use two screens, one’s running at 60 Hz
(the maximum it can handle) and the other at 144 Hz (the reason I use it at
all).On Wed, Mar 12, 2014 at 12:45 PM, mediata wrote:

Ryan C. Gordon wrote:

Quote:

I am think that the SDL_RenderPresent wait to sync with monitor and
thats why the second present on second screen become is too late and
become unstable.

Yes, that’s correct, the Present waits for vsync, so the second Present
call will wait for the next vsync, so you’ll always be one frame out
of sync between the two windows.

I’m not sure there’s a good way to accomplish what you’d like in SDL at
the moment. I suppose you could set only the second window to wait for
vsync, but I can’t say for certain if this would work (and that it would
always work).

Does it have to be two windows? Perhaps make one window and draw twice,
with two different viewports, left and right, and Present once?

–ryan.


SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Okay, but when i try this two methods i have problem again with vsync ->
in second monitor i have no correct vertical sync. I tried with 2 process
and i have no problem with vertical sync on second display. Where do i
wrong? Why with one process i cant vsync two monitors but with two i have
no problems.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’

In theory, if you create two threads and a window and renderer or OpenGL
context on each thread, then you should be able to simultaneously wait for
vblank in the present on each thread. Note that you’ll have to have to call
SDL_PumpEvents() in each thread as well, to get each window’s messages.On Wed, Mar 12, 2014 at 4:45 AM, mediata wrote:

Ryan C. Gordon wrote:

Quote:

I am think that the SDL_RenderPresent wait to sync with monitor and
thats why the second present on second screen become is too late and
become unstable.

Yes, that’s correct, the Present waits for vsync, so the second Present
call will wait for the next vsync, so you’ll always be one frame out
of sync between the two windows.

I’m not sure there’s a good way to accomplish what you’d like in SDL at
the moment. I suppose you could set only the second window to wait for
vsync, but I can’t say for certain if this would work (and that it would
always work).

Does it have to be two windows? Perhaps make one window and draw twice,
with two different viewports, left and right, and Present once?

–ryan.


SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Okay, but when i try this two methods i have problem again with vsync ->
in second monitor i have no correct vertical sync. I tried with 2 process
and i have no problem with vertical sync on second display. Where do i
wrong? Why with one process i cant vsync two monitors but with two i have
no problems.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Sam Lantinga wrote:

In theory, if you create two threads and a window and renderer or OpenGL context on each thread, then you should be able to simultaneously wait for vblank in the present on each thread. Note that you’ll have to have to call SDL_PumpEvents() in each thread as well, to get each window’s messages.

Thank for help,
now it have some light in tunnel :slight_smile:
program work but in random moment two windows lag in same time for 1-2 seconds and after that everything is become again normal.
Here is my code.

thread code.
I made Window and renderer into main loop and give them to thread.
I create one texture -> pic, one transparent rectangle and vertical moving line.
void draw_thread(Window *win, Renderer *rend, int index) {
std::string str(“1.png”);
Texture *pic = new Texture (rend, str);
RectT rect(rand()%500,rand()%500,350, 250);

int count = 0;

 while (!quit)
{
	 f (Platform::PumpEvents())
		 quit = true;

	count+=10;
	if (count >= win->Rect().w)
		count = 0;

	rend->Clear();

	pic->DrawToWindow(rect);

	rend->SetColor(255,255,255,255);
	rend->DrawLine(0 + count,0, 0 + count,win->Rect().w,5);

	rend->SetColor(255,0,0,125);
	rend->DrawRect(155,155,200,200,true);

	rend->Present();
}

}

Here is how i create window:
Window::Window(std::string &name, int screen_num, bool fullscren)
: window(nullptr),
windowRect()
{
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
PDEBUG(“ERROR: SDL Was not inited please init platform first!\n”);
return;
}

SDL_Rect display_rect;
if (SDL_GetDisplayBounds(screen_num, &display_rect) != 0)
{
	PDEBUG("ERROR: SDL_GetDisplayBounds() %s\n", SDL_GetError());
	return;
}

memcpy(&windowRect, &display_rect, sizeof (windowRect));

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

uint32_t flags = SDL_WINDOW_OPENGL;
if (fullscren)
	flags |= SDL_WINDOW_BORDERLESS;
window = SDL_CreateWindow(name.c_str(), display_rect.x, display_rect.y, display_rect.w, display_rect.h, flags);
if (window == nullptr)
{
	PDEBUG("ERROR: SDL_CreateWindow() %s\n", SDL_GetError());
	return;
}

}

Here is how i create renderer:
Renderer::Renderer(Window *win, bool vsync)
: window(win),
render(nullptr),
context()
{
if (win == nullptr)
{
PDEBUG(“ERROR: Window is NULL\n”);
return;
}

//Create Renderer
uint32_t flags = SDL_RENDERER_ACCELERATED;
if (vsync)
	flags |= SDL_RENDERER_PRESENTVSYNC;
render = SDL_CreateRenderer(win->window, -1, flags);
if (render == nullptr)
{
	PDEBUG("ERROR: SDL_CreateRenderer(): %s\n", SDL_GetError());
	return;
}

//Create Window OpenGL Context
context = SDL_GL_CreateContext(win->window);
if (SDL_GL_MakeCurrent(window->window, context) != 0)
	PDEBUG("ERROR: SDL_GL_MakeCurrent() %s\n", SDL_GetError());
SDL_SetRenderDrawBlendMode(render, SDL_BLENDMODE_BLEND);
Clear();

}

bool
Renderer::SetColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
//if (SDL_GL_MakeCurrent(window->window, context) != 0)
// PDEBUG(“ERROR: SDL_GL_MakeCurrent() %s\n”, SDL_GetError());
if (SDL_SetRenderDrawColor(render, r, g, b, a) == 0)
return true;
PDEBUG(“ERROR: SDL_SetRenderDrawColor() %s\n”, SDL_GetError());
return false;
}

bool
Renderer::DrawRect(int x, int y, int width, int height, bool bFilled)
{
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = width;
rect.h = height;

if (bFilled)
{
	if (SDL_RenderFillRect(render, &rect) < 0)
	{
		PDEBUG("ERROR: SDL_RenderDrawRect() %s\n", SDL_GetError());
		return false;
	}
}
else
{
	if (SDL_RenderDrawRect(render, &rect) < 0)
	{
		PDEBUG("ERROR: SDL_RenderFillRect() %s\n", SDL_GetError());
		return false;
	}
}

return true;

}

bool
Renderer::DrawLine(int xStart, int yStart, int xEnd, int yEnd, int width)
{

//if (SDL_GL_MakeCurrent(window->window, context) != 0)
//		PDEBUG("ERROR: SDL_GL_MakeCurrent() %s\n", SDL_GetError());
glLineWidth(width);
if (SDL_RenderDrawLine(render, xStart, yStart, xEnd, yEnd) < 0)
{
	PDEBUG("ERROR: SDL_RenderDrawLine() %s\n", SDL_GetError());
	return false;
}
return true;

}

void
Renderer::Present()
{
SDL_RenderPresent(render);
}

and here is PollEnvent Function:

bool
Platform::PollEvents()
{
SDL_Event event;
if (SDL_PollEvent(&event) == 0)
return false;
switch (event.type)
{
case SDL_QUIT:
return true;
case SDL_KEYDOWN:
break;
case SDL_KEYUP:
if(event.key.keysym.sym == SDLK_ESCAPE)
return true;
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_CLOSE)
return true;
break;
}
return false;
}

What can be the problem here i cant see it…

Okay I found problem. it is in my PC.
I run program on two other PC and everything was okay.

Thanks for help guys.