Технические вопросы и ответы QA1542

Текстура QuickTime Визуальный Контекст - kQTVisualContextNotAllowedErr с неускоренными видеокартами

Q: Я работаю с QTCoreVideo101, но он никогда не возвращает VisualContextRef. Вызов QTOpenGLTextureContextCreate всегда сбои с ошибкой-9459. У меня есть Mac Pro система со сторонней видеокартой для Final Cut Pro. Как я могу создать QuickTime Текстура OpenGL Визуальный Контекст?

A: Я работаю с QTCoreVideo101, но он никогда не возвращает VisualContextRef. Вызов QTOpenGLTextureContextCreate всегда сбои с ошибкой-9459. У меня есть Mac Pro система со сторонней видеокартой для Final Cut Pro. Как я могу создать QuickTime Текстура OpenGL Визуальный Контекст?

Наиболее вероятная причина-9459 (kQTVisualContextNotAllowedErr) ошибка является сторонней видеокартой. Если карта представляет себя как видеоустройство, но не поддерживает ускоренные поверхности QTOpenGLTextureContextCreate перестанет работать.

Для успешного создания QuickTime Текстура OpenGL Визуальный Контекст неускоренный дисплей (и) может кашироваться путем создания маски дисплея (просто битовая маска, используемая для указания ряда присоединенных дисплеев), который только идентифицирует дисплеи, поддерживающие ускоренные поверхности. Это может быть сделано с помощью Quartz Display Services APIs такой как CGDisplayUsesOpenGLAcceleration и CGDisplayIDToOpenGLDisplayMask.

Эта маска дисплея (с неускоренным кашировавшим дисплеем (ями)) тогда используется при создании объекта Формата пикселя OpenGL. Этот объект Формата пикселя используется при создании Контекста OpenGL и при вызове QTOpenGLTextureContextCreate.

Перечисление 1 демонстрирует, как создать маску дисплея, в то время как перечисление 2 демонстрирует, как использовать возвращенную маску дисплея при создании NSOpenGLPixelFormat объект.

  Возврат перечисления 1 ускоренная маска дисплея.

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;
}

В перечислении 1 нам нужен активный дисплейный список. Активный дисплей подключается, не спит и доступный для рисования, в то время как дисплей считают онлайновым просто, когда кадровый буфер подключен к монитору.

В аппаратном наборе зеркального отражения только главный дисплей активен.

Перечисление 2  Используя маску дисплея путем разделения на подклассы 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;
}
    ...

Ссылки



История версии документа


ДатаПримечания
18.09.2007

Новый документ, обсуждающий, как создать маску дисплея и избежать kQTVisualContextNotAllowedErr при использовании неускоренной видеокарты.