Hi All,

I am developing an application that needs to render portions of a single 
composition across multiple displays attached to a single machine.  My approach 
is to create one renderer for each display and drive them "in parallel" with  
displayLinks.  My QCRenderer subclass works fine when rendering to system with 
only one display, however when two displays are attached to the system, it 
appears as though all rendering is done on the main screen (where the menubar 
is located).  Has anyone had this experience before?   What are the possible 
causes for this situation?

My code is based on the old source code from Quartz Composer Visualizer and is 
the relevant portions are attached below.  Basically, I create a QCRenderer 
with info specific to my app, then I drive the rendering process using a 
displayLink.  Also included is a listing of the relevant log messages when my 
renderers are being created.

I have checked the archives to see if any light could be  shed on what I was 
doing, but the suggestions I found (e.g., use multiple QCRenderers for multiple 
displays, check pixel format, sharing opengl context) are things I believe I 
have handled properly...  but then again, my code isn't working, so take my 
surety with a grain of salt.

Any help, hints, suggestions would be greatly appreciated.

Thanks,

douglas

---

*** Here's the relevant code from the QCRenderer subclass:

- (id) initWithComposition: (QCComposition *)composition screen: (NSDictionary 
*)screen renderFrame: (CGRect)renderFrame usingSharedContext: (NSOpenGLContext 
*)sharedContext
{
        NSOpenGLPixelFormatAttribute                    attributes[] = { 
NSOpenGLPFAScreenMask, 0, 
                                                                                
                                         NSOpenGLPFANoRecovery,
                                                                                
                                         NSOpenGLPFAAccelerated, 
                                                                                
                                         NSOpenGLPFADoubleBuffer, 
                                                                                
                                         NSOpenGLPFAColorSize, 24, 
                                                                                
                                         NSOpenGLPFADepthSize, 16, 
                                                                                
                                         NSOpenGLPFAFullScreen, 0
                                                                                
                                         };
        NSOpenGLPixelFormat*                                    pixelFormat;
        
        CGFloat                                                                 
longestSide = 0.0;

        CGColorSpaceRef                                         colorSpace;
        GLint                                                                   
swapInterval = 1;
        
        BOOL                                                                    
bezelEnabled;
        CGFloat                                                                 
bezel;
        
        CVReturn                                                                
returnCode;


        self.displayID = [[screen objectForKey: @"displayId"] intValue];
        self.glSharedContext = sharedContext;
        
        bezel = [[screen valueForKey: @"bezel"] floatValue];
        bezelEnabled = [[screen valueForKey: @"bezelEnabled"] boolValue];
        
        colorSpace = (CGColorSpaceRef)CGDisplayCopyColorSpace( self.displayID 
);                                                                              
          
        longestSide = fmaxf( renderFrame.size.width, renderFrame.size.height );

        CGRectMakeWithDictionaryRepresentation( (CFDictionaryRef)[screen 
objectForKey: @"onCanvasFrame"], &screenFrame );

        attributes[1] = CGDisplayIDToOpenGLDisplayMask( [[screen objectForKey: 
@"displayID"] intValue] );
        
        //+
        //  Make allowance for displaying with a bezelWidth adjustment
        //-
        
        if ( bezelEnabled && bezel != 0 )
             screenFrame = CGRectMake( screenFrame.origin.x + bezel, 
screenFrame.origin.y + bezel, screenFrame.size.width - 2 * bezel, 
screenFrame.size.height - 2 * bezel );
        
        //+
        //  Determine the region of the composition that is being drawn for 
this screen
        //-
        
        subRegion = screenFrame;
        
        subRegion.origin.x = ( subRegion.origin.x + longestSide / 2.0 - 
renderFrame.size.width / 2.0 + subRegion.size.width / 2.0 ) / longestSide;
        subRegion.origin.y = ( subRegion.origin.y + longestSide / 2.0 - 
renderFrame.size.height / 2.0 + subRegion.size.height / 2.0 ) / longestSide;
        subRegion.size.width = subRegion.size.width / longestSide;
        subRegion.size.height = subRegion.size.height / longestSide;    

        NSLog( @"\n--- display id: %@\n--- canvasFrame: %@\n---OpenGL Display 
Mask: %d\n---Sub Region: %@", 
                        [screen objectForKey: @"displayId"], 
                        NSStringFromRect( NSRectFromCGRect( screenFrame )), 
                        attributes[1], 
                        NSStringFromRect( NSRectFromCGRect( subRegion )));
                        
        //+
        //  Configure the pixelFormat to be used for the OpenGL context
                
        pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: 
attributes] autorelease];
        [pixelFormat getValues: &rendererID forAttribute: NSOpenGLPFARendererID 
forVirtualScreen: 0];

        self.glContext = [[NSOpenGLContext alloc] initWithFormat:  pixelFormat 
shareContext: sharedContext];
        [self.glContext setValues: &swapInterval forParameter: 
NSOpenGLCPSwapInterval];
        [self.glContext setFullScreen];

        NSLog( @"\n--- Virtual Screen: %d\n--- Renderer ID: %d\n--- pixel 
format: %@\n--- Context: %@\n--- shared Context: %@", 
                        [self.glContext currentVirtualScreen], 
                        [ArenaRenderer rendererIDForDisplayID: self.displayID], 
                        pixelFormat, 
                        self.glContext, 
                        sharedContext );
        
        //+
        //  Call the superclass
        //-
        
        self = [super initWithCGLContext: [self.glContext CGLContextObj] 
pixelFormat:[pixelFormat CGLPixelFormatObj] colorSpace: colorSpace composition: 
composition];
        if ( self != nil )
           {
                 CGColorSpaceRelease( colorSpace );
                 self.startTime = -1;
                                
                 returnCode = CVDisplayLinkCreateWithOpenGLDisplayMask( 
CGDisplayIDToOpenGLDisplayMask( self.displayID ), &displayLink );
                 if ( returnCode == kCVReturnSuccess ) 
                   {
                         CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( 
displayLink, [self.glContext CGLContextObj], [pixelFormat CGLPixelFormatObj]);
                         CVDisplayLinkSetOutputCallback( displayLink, 
displayLinkCallBack, self);
                         }
                 }
                
        CGDisplayCapture( self.displayID );
        CGDisplayHideCursor( self.displayID );

        CVDisplayLinkStart( displayLink );
        
        return self;
        }

- (void) renderScene
{
        float                           scale;
        NSTimeInterval          renderTime;

        //+
        //  Normalize the startTime, if necessary, then determine the current 
render time
        //-

        if ( self.startTime < 0 )
                 self.startTime = [NSDate timeIntervalSinceReferenceDate];
                 
        renderTime = [NSDate timeIntervalSinceReferenceDate] - self.startTime;
        
        //+
        //  Set up the OpenGL enviroment and get ready to render a frame
        //-

        [self.glContext makeCurrentContext];

        glClearColor( 0.0f, 0.0, 0.0, 1.0 );
        glClear( GL_COLOR_BUFFER_BIT );
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        glPushMatrix();
        
        //+
        //  Translate and scale the projection matrix so that correct subregion 
is rendered on display
        //-
        
        glTranslatef(( 0.5 - subRegion.origin.x ) / subRegion.size.width * 2.0, 
( 0.5 - subRegion.origin.y ) / subRegion.size.height * 2.0, 0.0 );
        scale = MIN( 1.0 / subRegion.size.width, 1.0 / subRegion.size.height );
        glScalef( scale, scale, 1.0 );
        
        //+
        //  Render composition
        //-
        
        [super renderAtTime: renderTime arguments: nil];
        [self.glContext flushBuffer];

        //+
        //  Restore projection matrix
        //-
        
        glMatrixMode( GL_PROJECTION );
        glPopMatrix();
        }

*** Here are the log messages I get on the console when the init method 
executes on a system with two displays:

6/28/11 1:01:32 PM      Arena Client[1641]      
--- display id: 69676800
--- canvasFrame: {{1391.79, 933.214}, {1920, 1080}}
---OpenGL Display Mask: 1
---Sub Region: {{0.653274, 0.409226}, {0.533333, 0.3}}
6/28/11 1:01:32 PM      Arena Client[1641]      
--- Virtual Screen: 0
--- Renderer ID: 16918030
--- pixel format: <NSOpenGLPixelFormat: 0x1027c6160>
--- Context: <NSOpenGLContext: 0x1027d0bf0>
--- shared Context: (null)
6/28/11 1:01:32 PM      Arena Client[1641]      --- comparing rendererIDs: 
16918030 to 16918030
6/28/11 1:01:32 PM      Arena Client[1641]      --- sharing a renderer's context
6/28/11 1:01:32 PM      Arena Client[1641]      
--- display id: 418793473
--- canvasFrame: {{692.143, 2046.43}, {1680, 1050}}
---OpenGL Display Mask: 1
---Sub Region: {{0.425595, 0.714286}, {0.466667, 0.291667}}
6/28/11 1:01:32 PM      Arena Client[1641]      
--- Virtual Screen: 0
--- Renderer ID: 16918030
--- pixel format: <NSOpenGLPixelFormat: 0x1027c9ba0>
--- Context: <NSOpenGLContext: 0x1027c8fa0>
--- shared Context: <NSOpenGLContext: 0x1027d0bf0> 
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartzcomposer-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to