First, let me explain what I'm trying to do: I've got two Quartz
Compositions, and I want to feed the rendered output of the first
one into the second, and have each in a CALayer. Also, the second
layer has a few output ports I want to get values from each frame.
Am I overlooking something more straightforward? QCCompositionLayer
doesn't appear to be flexible enough for this.
See the QCCompositionRenderer protocol. Its implemented by
QCRenderer, QCView, and QCCompositionLayer. It specifically gives
you the capabilities that your looking for to query and set ports.
I passed over that briefly, but it didn't catch my attention because
it didn't appear to give me any way to ensure that one composition was
rendered before the other, or to capture the rendered frame from the
first. So I went for the second route, with your help:
One problem is I'm not very clear on what a GL context is. The
CAOpenGLLayer drawInCGLContext:::: callback gives me a
CGLContextObj to draw in, but QCRenderer needs the context on init.
Should these be the same context? I've tried returning the same
context I gave to the renderer in -[CAOpenGLLayer
copyCGLContextForPixelFormat:] but none of the CAOpenGLLayer
methods are being called, even after setNeedsDisplay.
If you end up going down this route, then I would recommend that you
override copyCGLContextForPixelFormat:, create your CGLContextObj
*and* create your QCRenderer there. Then you should be able to
render normally in drawInCGLContext::::. But I suspect you'll be
able to use the QCCompositionLayer after all :).
I After a few hiccups, this is working very well. I still don't have
the rendered frame of the first composition, but I made an output port
with the image that goes into that composition's billboard, and it's
good enough for now. For anyone googling this (me, anyway), here's
some hints for the problems I ran into:
First, I realized that CAOpenGLLayer's drawInCGLContext:::: method is
called on the main thread, so I threw out all my lame attempts at
using the display link callback and went with an NSTimer. I don't
really understand what the display link is, and it works just fine
this way. (I'm still curious though, does using the display link give
you any kind of performance benefit?)
Despite the decree of "you should not call this method directly" in
the documentation for -[CALayer display], calling it directly does
seem to work just fine and it lets me render the different
compositions in the right order. I'm not thrilled about defying the
documentation gods, but at least it's a public method.. I should ask,
though: is there a better way to do it?
Many, many thanks for your help! This got me to my "proof of concept"
milestone, what I've been aiming at for the last month or so. The
concept's far from proven, but it gives me a lot of fun stuff to play
with.