| Q: I'm working with QTCoreVideo101 but it never returns a VisualContextRef. Calling QTOpenGLTextureContextCreatealways fails with error -9459. I have a Mac Pro system with a third party video card for Final Cut Pro. How can I create a QuickTime OpenGL Texture Visual Context?A: The most likely reason for the -9459 (kQTVisualContextNotAllowedErr) error is the third party video card. If the card presents itself as a video device but does not support accelerated surfacesQTOpenGLTextureContextCreatewill fail. Note: In Quartz, the term display refers to a graphics hardware system consisting of a framebuffer, a color correction (gamma) table or color palette, and possibly an attached monitor.To successfully create a QuickTime OpenGL Texture Visual Context, the non-accelerated display(s) may be masked out by creating a display mask (simply a bitmask used to specify a set of attached displays) that only identifies the displays supporting accelerated surfaces. This can be done using Quartz Display Services APIs such as CGDisplayUsesOpenGLAccelerationandCGDisplayIDToOpenGLDisplayMask. This display mask (with the non-accelerated display(s) masked out) is then used when creating the OpenGL Pixel Format object. This Pixel Format object is used when creating the OpenGL Context and when calling QTOpenGLTextureContextCreate. Listing 1 demonstrates how to build the display mask, while listing 2 demonstrates how to use the returned display mask when creating the NSOpenGLPixelFormatobject. Listing 1: Return the Accelerated Display Mask. 
static CGOpenGLDisplayMask GetTheAcceleratedDisplayMask(void)
{
    const CGDisplayCount maxDisplays = sizeof(CGOpenGLDisplayMask) * 8; // the number of displays
    CGDirectDisplayID displays[maxDisplays];  // represents the unique identifier for an attached display
    CGDisplayCount display, displayCount;
    CGOpenGLDisplayMask displayMask = 0;   // bitmask used in OpenGL to specify a set of attached displays
    // get the list of displays that are active (or drawable)
    if (CGGetActiveDisplayList(maxDisplays, displays, &displayCount) == kCGErrorSuccess) {
        // does the display support acceleration
        for (display = 0; display < displayCount; display++) {
            if (CGDisplayUsesOpenGLAcceleration(displays[display])) {
                // it does, so get the OpenGL display mask for the display and update our display mask
                displayMask |= CGDisplayIDToOpenGLDisplayMask(displays[display]);
            }
        }
    }
    // return our display mask that now has all the non-accelerated displays filtered out
    return displayMask;
}
Note: CGGetActiveDisplayListvs.CGGetOnlineDisplayList In listing 1, we need the active display list. An active display is connected, awake and available for drawing, while a display is considered online simply when the frame buffer is connected to a monitor. In a hardware mirroring set, only the primary display is active.Listing 2: Using the Display Mask by Subclassing NSOpenGLView 
@interface MyOpenGLView : NSOpenGLView
{
    ...
    QTVisualContextRef mQTOpenGLTextureVisualContext;
}
    ...
- (QTVisualContextRef)visualContext;
- (void) setVisualContextRef:(QTVisualContextRef)inVisualContext;
    ...
@end
@implementation MyOpenGLView
+ (NSOpenGLPixelFormat *)defaultPixelFormat
{
    // create an NSOpenGLPixelFormat object with the appropriate display mask
    CGOpenGLDisplayMask myDisplayMask = GetTheAcceleratedDisplayMask();
    if (0 != myDisplayMask) {
        NSOpenGLPixelFormatAttribute attributes[] =
        {
            NSOpenGLPFADoubleBuffer, // double buffered pixel format
            NSOpenGLPFAAccelerated,  // hardware accelerated renderer
            NSOpenGLPFANoRecovery,   // disable all failure recovery systems
            //** bit mask of supported physical screens **//
            NSOpenGLPFAScreenMask, (NSOpenGLPixelFormatAttribute)myDisplayMask,
            (NSOpenGLPixelFormatAttribute)0
        };
        return [[(NSOpenGLPixelFormat*)[NSOpenGLPixelFormat alloc]
                                                            initWithAttributes:attributes] autorelease];
    } else {
        return [super defaultPixelFormat];
    }
}
- (id)initWithFrame:(NSRect)frameRect
{
    return [super initWithFrame:frameRect pixelFormat:[MyOpenGLView defaultPixelFormat]];
}
- (void)prepareOpenGL
{
    ...
    if (nil != [self openGLContext]) {
        long swapInterval = 1;
       // sync with screen refresh to avoid tearing
       [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
    }
    ...
    // create the QuickTime Texture Visual Context for rendering to my custom NSOpenGLView
    if (NULL == [self visualContextRef]) {
        QTVisualContextRef aQTOpenGLTextureContext;
        OSStatus status = QTOpenGLTextureContextCreate(kCFAllocatorDefault,
                                         [[self openGLContext] CGLContextObj],
                                         (CGLPixelFormatObj)[[self pixelFormat] CGLPixelFormatObj],
                                         NULL, &aQTOpenGLTextureContext);
        if (noErr == status) {
            [self setVisualContextRef:aQTOpenGLTextureContext];
            ...
        } else {
            [self setVisualContextRef:NULL];
        }
    }
    ...
}
    ...
- (QTVisualContextRef)visualContext
{
    return mQTOpenGLTextureVisualContext;
}
- (void)setVisualContextRef:(QTVisualContextRef)inVisualContext
{
    mQTOpenGLTextureVisualContext = inVisualContext;
}
    ...
ReferencesBack to Top  Document Revision History| Date | Notes | 
|---|
 | 2007-09-18 | First Version | 
 Posted: 2007-09-18 |