leadedge/Spout2

flickering because receiver sometimes can't access the shared texture.

Closed this issue · 5 comments

I implemented texture sharing between opengl process.

However, every other draw, the program can't access shared image. Here is a demo capture.
I found that CheckTextureAccess returns false in ReadGLDXtexture func and can't GetSharedTextureData every other draw.
Source code is here.

Thank you.

I have built both your receiver and sender projects and they work without flicker for me. But we need to find out what the problem is. First of all, could you try -


bool Receiver::Connect()
{
	if (spout.ReceiveTexture(texture.GetTexId(), GL_TEXTURE_2D, false)) {
		if (spout.IsUpdated())
		{
			texture.Resize(spout.GetSenderWidth(), spout.GetSenderHeight());
		}
		if (spout.BindSharedTexture())
		{
			ShowLog();
			return true;
		}
	}
	return false;
}

Next, remove the mutex test and leave the texture sync to the GL/DX interop. Remove these lines -

	// if (frame.CheckTextureAccess(m_pSharedTexture)) {
		--- 
		--- 
		--- 
		// frame.AllowTextureAccess(m_pSharedTexture);
	// }

If that solves it, put the lines back in and test for a timeout in "CheckAccess" by adding the log that is commented out.

			case WAIT_TIMEOUT: // The time-out interval elapsed,
			SpoutLogError("CheckAccess - WAIT_TIMEOUT");
			break;

Is the graphics driver vertical sync setting on or off? What is the graphics hardware?

I changed my code as you suggest , but it does not work.
THe graphics hardware is GeForce RTX 2070 super and vertical sync setting is on.
I had my friend(similaly GeForce hardware) try it, but it still is flickering.

Thank you.

I think the problem is that the OpenGL shared texture is bound and this prevents access to the Directx shared texture that it is linked to.

There is a texture used to receive to but that is never used. Try the following -

bool Receiver::Connect()
{
	// Unbind if connected
	if (spout.IsConnected())
		spout.UnBindSharedTexture();

	if (spout.ReceiveTexture())
	{
		if (spout.BindSharedTexture()) {
			ShowLog();
			return true;
		}
	}
	return false;
}

The only problem is that the texture will be inverted because it is connected to a DirectX texture. You will need to flip the vbo texture vertices in Y.

This worked! Thank you.

That's good. Normally you would follow BindSharedTextre() with UnBindSharedTexture(), but this will work OK.