Synchronization mechanism on Mixing Metal and OpenGL Rendering

ios: 14.2 iphone xr

I download the demo from "https://developer.apple.com/documentation/metal/mixing_metal_and_opengl_rendering_in_a_view?language=objc"

it play normally.

and then i change the code as followed:

the purpose is switching "mix render" and "just opengl rendering" and re-create AAPLMetalRenderer each time when re-entry "mix render"

there come a 'bug' phenomenon: the first frame each time from "just opengl" to "mix render" will display the old picture ( it was the last picture when "mix render" to "just opengl " ) .

the first frame it will re-create the AAPLMetalRenderer and call drawToInteropTexture, but it seems that the "InteropTexture" do not 'update' yet ( or opengl's draw do not wait for metal finish rendering to 'InteropTexture' ? )

so I have a question about how metal and opengl sync??

int counter = 0 ;
bool currentMetal = false ;
- (void)draw:(id)sender
{
  [EAGLContext setCurrentContext:_context];
	
	counter++;
	counter = counter % 180;
	
	if (counter < 90)
	{
		
		bool waitForFinish = false ;
		
		if (!currentMetal)  // re-entry "mix render"
		{
             // create MetalRender 
			_metalRenderer = nil;

			_metalRenderer = [[AAPLMetalRenderer alloc] initWithDevice:_metalDevice colorPixelFormat:AAPLOpenGLViewInteropPixelFormat];

			[_metalRenderer useTextureFromFileAsBaseMap];

			[_metalRenderer resize:AAPLInteropTextureSize];
			
 
		}
		
		currentMetal = true ;
	 	
		[_metalRenderer drawToInteropTexture:_interopTexture.metalTexture waitForFinish:waitForFinish];
		
		
		[_openGLRenderer draw];
	}
	else
	{
		[_metalRenderer justUpdate]; // not metal render
		[_openGLRenderer justClear]; // just clean opengl's fbo
	 
		currentMetal = false ;
	}

  glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
  [_context presentRenderbuffer:GL_RENDERBUFFER];
}

_openGLRenderer justClear is below:


- (void) justClear
{
	glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBOName);
	glClearColor(0.5, 0.5, 0.5, 1);
	glClear(GL_COLOR_BUFFER_BIT);
}
 

_metalRenderer justUpdate is below:


- (void)justUpdate
{
	[self updateState];
}

Add more infomation: the follow patch is for demo on Mixing Metal and OpenGL Rendering in a View

changes :

  1. just display Quad Rendered with GL to View
  2. AAPLMetalRenderer add internal texture(MTLTexture), first draw quad on this internal texture, and then draw to 'Interop Texture'
  3. CADisplayLink set up 1fps (so it's possible to see the phenomenon)

result: you can see the first frame is black just after the app start up (the 'metal-draw' quad is black but outside is red)

I'm having a little bit of trouble understanding what you are trying to do. In general, you need to execute glFlush() for Metal to get the results of the OpenGL rendering and you need to execute -[MTLCommandBuffer commit] and -[MTLCommandBuffer waitUntilScheduled] for OpenGL to get the result of Metal rendering.

If carefully using these does not resolve your issue, I suggest using Feedback Assistant and attach your project so we can build and run it to understand what you're trying to do. Make sure to repost the Feedback Assistant number here so we will be able to find it.

“[MTLCommandBuffer waitUntilScheduled]” it works! but the demo on "Mixing Metal and OpenGL Rendering in a View" do not show this call before using opengl to render 'Interop Texture' to fbo.

Anyways, thank you very much.

Synchronization mechanism on Mixing Metal and OpenGL Rendering
 
 
Q