Bug 753 - Rendering w/ CALayer shall not hog the GPU, otherwise heavy stuttering due to lack of proper GL multithreading.
Summary: Rendering w/ CALayer shall not hog the GPU, otherwise heavy stuttering due to...
Status: RESOLVED FIXED
Alias: None
Product: Jogl
Classification: JogAmp
Component: macosx (show other bugs)
Version: 2
Hardware: All macosx
: --- major
Assignee: Sven Gothel
URL:
Depends on:
Blocks: 735
  Show dependency treegraph
 
Reported: 2013-06-16 19:55 CEST by Sven Gothel
Modified: 2013-07-08 16:09 CEST (History)
4 users (show)

See Also:
Type: ---
SCM Refs:
jogl 92fce556bf9c3d8f1e99bf79f48631d58829c523 jogl d7e2cb6fdec200d25a9189f7951c5f94c26a1ce4
Workaround: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sven Gothel 2013-06-16 19:55:03 CEST
While analyzing Bug 735 is has been observed that the new LandscapeES2 GLEventListener shader
may utilize (hog) the GPU, so the CALayer rendering thread may not have enough resources
for compositioning the texture each frame.

See Bug 735 Comment 10.

waitUntilNSOpenGLLayerIsReady:
  if ( last_time+period < now  ) then we need to wait until now+period,
  where period is the vsync period multiplied by swap-interval.
  if swap-interval == 0, it still is the vsync period.

.. hence even w/o a given swap interval, we have to 'wait a while' until the CALayer signals 'ready'.
Comment 1 Sven Gothel 2013-06-16 20:00:20 CEST
(In reply to Bug 735 comment #11)
> Hi Sven, thanks for looking into this. 
> 
> I'm also glad to see that you were able to reproduce the stuttering issue,
> which was in fact the problem I faced originally. My use of invoke was
> basically an attempt to solve the stuttering. So far, the only way I was
> able to reduce the stuttering was by adding a glFinish() call at the end of
> the frame rendering, which of course shouldn't be done, at least from my
> understanding of glFinish.

I have moved the stuttering issue to it's own bug, Bug 753.

Thank you for the hint glFinish(), maybe it gives a 'timeout',
allowing the CALayer thread to utilize the GPU.
Comment 2 ac 2013-06-17 01:36:15 CEST
I think the reason why glFinish() fixes the stuttering is because it blocks the calling thread until all the commands in the GL pipeline completed execution... but this is of course not recommended to use, right?
Comment 3 Sven Gothel 2013-06-17 04:43:41 CEST
(In reply to comment #2)
> I think the reason why glFinish() fixes the stuttering is because it blocks
> the calling thread until all the commands in the GL pipeline completed
> execution... but this is of course not recommended to use, right?

Depends .. probably a GL pipeline bugs, however .. one could also 
see this as a required synchronization between to rendering threads
each with their own context - sharing resources. 
Ofc .. this synchronization should be performed implicit after 
CGL.flushBuffer(..) - maybe we earmark this to become a quirk.
See comments in d7e2cb6fdec200d25a9189f7951c5f94c26a1ce4.

d7e2cb6fdec200d25a9189f7951c5f94c26a1ce4 also incl. log files
of perf. tests, i.e. demonstrating that finish _only_  triggers rendering
and waits for results. So the flushBuffer() does nothing :(
Comment 4 ac 2013-06-17 19:45:21 CEST
I see you added a call to glFinish() to swapBuffers(). I used glFinish only because it worked as a temporary hack to fix the stuttering, however, from what I read online, the use of glFinish in general is not recommended.

See for instance comment 3 in: 
http://stackoverflow.com/questions/2143240/opengl-glflush-vs-glfinish

This technical Q&A from Apple might also be useful:
http://developer.apple.com/library/mac/#qa/qa1158/_index.html
Comment 5 ac 2013-06-17 19:46:30 CEST
Sorry, I meant this comment:

http://stackoverflow.com/a/2149938
Comment 6 Sven Gothel 2013-06-18 02:20:48 CEST
(In reply to comment #5)
> Sorry, I meant this comment:
> 
> http://stackoverflow.com/a/2149938

Indeed .. as I commented, see comment 3,
and from source code:
  <http://jogamp.org/git/?p=jogl.git;a=blob;f=src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java;h=6b086ce44dc81cc950e33ad5bd50afcb2d12b094;hb=d7e2cb6fdec200d25a9189f7951c5f94c26a1ce4#l1080>:

// Required(?) to finish previous GL rendering to give CALayer proper result,
// i.e. synchronize both threads each w/ their GLContext sharing same resources.
//
// FIXME: IMHO this synchronization should be implicitly performed via 'CGL.flushBuffer(contextHandle)' above,
// in case this will be determined a driver bug - use a QUIRK entry in GLRendererQuirks!

Note: This code is only active in case of CALayer usage,
i.e. in conjunction w/ CALayer thread .. sharing GL resources.

We could inject a GLSync object as well here, if the used GLProfile allows it .. sure.

All the 'disclaimer' and 'FIXME' note stands, so if it is a driver bug 
due to 'CGL.flushBuffer(contextHandle)' lack of synchronization .. we maybe able to remove it later.

See the performance measurings here:
  <http://jogamp.org/git/?p=jogl.git;a=tree;f=src/test/com/jogamp/opengl/test/bugs/Bug735.OSX.CALayer.Perf.logs;hb=HEAD>

They prove that only glFinish() synchronizes the rendering pipeline.
Note: Variation 'm1' w/ flush is removed, current code reflects 'm2'.

Yes, I spend a great deal of time w/ this odd behavior,
and injecting a manual synchronization point via glFinish() was not easy :)
Comment 7 ac 2013-07-08 16:09:48 CEST
I updated Processing to use RC12, and removed the glFinish() call I had as a temporary workaround in the Processing renderer, but now I see the stuttering happening in the landscape example...