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

Советы по делящемуся контекста

Q: Как я совместно использую ресурсы между контекстами OpenGL?

A: Контексты могут совместно использовать объектные ресурсы и их связанное объектное состояние путем указания совместно используемого контекста во время создания контекста. Совместно используемые контексты совместно используют все объекты текстуры, объекты массива вершины, дисплейные списки, программы вершины и программы фрагмента, создаваемые прежде и после того, как будет инициироваться совместное использование. Состояние этих объектов также совместно используется, но другое состояние контекста не. Не каждый контекст может быть совместно использован с любым контекстом. Много зависит от обеспечения того же набора поддержки средств рендеринга оба контекста. В целом, совместно использованные контексты позволяют меньше дублирования ресурса, устанавливают затраты и кодирующий для разработчика.

Q: Каковы основы?

A: Когда контексты OpenGL создаются, можно определять второй контекст совместно использовать объектные ресурсы. Все совместное использование является коллегой для пиринга, и разработчики могут предположить, что совместно используемые ресурсы являются считаемой ссылкой и таким образом будут сохраняться, пока явно не выпущено или когда самостоятельно высвобождены последние средства совместного использования контекста. Полезно думать об этом простым языком возможном а не принять избыточную сложность.

Q: Что и не совместно используется?

A: Доля контекста «возражает ресурсам», включающим текстуры, объекты массива вершины, дисплейные списки, программы вершины и программы фрагмента. Объектное состояние также совместно используется, такие как параметры текстуры или параметры среды программы. Необъектное состояние не совместно используется, такие как цель текстуры включает, или текущая программа фрагмента/вершины. В то время как установка отдельного объекта должна будет только быть сделана одно время, клиенты должны будут копировать изменения состояния контекста как требуется.

Q: Какие контексты могут быть совместно использованы?

A: Контекст, совместно использующий, ограничивается теми контекстами, имеющими двойные виртуальные экранные отображения. Это означает пиксельные форматы, устанавливающиеся с тем же самым набором средств рендеринга, может создать контексты, которые могут быть совместно использованы. Существует два простых способа достигнуть этой цели. Во-первых, используйте тот же самый формат пикселя для всех контекстов, которые клиент хочет совместно использовать. Это гарантирует то же виртуальное экранное отображение и таким образом возможность совместно использовать контексты. В некоторых случаях вследствие требуемых различий в формате пикселя может не быть просто гарантировать, что набор средств рендеринга является непротиворечивым. Самое простое решение состоит в том, чтобы выбрать единственное средство рендеринга для всех форматов пикселя.

Q: Точно, как совместно используются контексты?

A: Совместное использование контекстов очень просто. Точная форма вызовов функции зависит, на котором используется API. Примеры CGL, AGL и NSOpenGL представлены в Перечислении 1, Перечислении 2 и Перечислении 3, соответственно..

Перечисление 1  установка контекста CGL для совместного использования

#include <OpenGL/OpenGL.h>

// Note: for demonstration purposes, normally one would create a CGL pixel
//format for a single full screen, see Listing 2 for an example of this
CGLPixelFormatAttribute attrib[] = {kCGLPFADoubleBuffer, 0};
CGLPixelFormatObj pixelFormat = NULL;
long numPixelFormats = 0;
CGLContextObj cglContext1 = NULL;
CGLContextObj cglContext2 = NULL;

CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats);
CGLCreateContext(pixelFormat, NULL, &cglContext1);

// create a second context sharing with the first
CGLCreateContext(pixelFormat, cglContext1, &cglContext2);

Перечисление 2  установка контекста AGL для совместного использования

#include <AGL/agl.h>

GLint attrib[] = {AGL_RGBA, AGL_DOUBLEBUFFER, AGL_NONE};

AGLPixelFormat aglPixFmt = aglChoosePixelFormat (NULL, 0, attrib);
AGLContext aglContext1 = aglCreateContext (aglPixFmt, NULL);

// create a second context sharing with the first
AGLContext aglContext2 = aglCreateContext (aglPixFmt, aglContext1);

  Изменения перечисления 3 в установке NSOpenGLContext для совместного использования

#import <Cocoa/Cocoa.h>

+ (NSOpenGLPixelFormat*)defaultPixelFormat
{
  NSOpenGLPixelFormatAttribute attributes [] = {
                               NSOpenGLPFADoubleBuffer,  // double buffered
                               (NSOpenGLPixelFormatAttribute)nil };

  return [[(NSOpenGLPixelFormat *)[NSOpenGLPixelFormat alloc] 
                                  initWithAttributes:attribs] autorelease];
}

- (NSOpenGLContext*)openGLContextWithShareContext:(NSOpenGLContext*)context
{ // create a context the first time through
   if (_openGLContext == NULL) {
    _openGLContext = [[NSOpenGLContext alloc] 
                      initWithFormat:[[self class] defaultPixelFormat]
                      shareContext:context];
    [_openGLContext makeCurrentContext];
    [self prepareOpenGL]; // call to initialize OpenGL state here
  }
  return _openGLContext;
}

- (void)prepareOpenGL
{
  // for overriding to initialize OpenGL state, 
  // occurs after context creation
}

Установка контекстов для использования единственного средства рендеринга для определенного экрана дисплея является довольно прямой также. Так как платформа OpenGL будет обычно обеспечивать, программное обеспечение отступают средство рендеринга, нужно явно предотвратить это, не указав восстановления в атрибутах формата пикселя, не уже указав полный экран (так как полный экран не подразумевает восстановления). Перечисление 4, Перечисление 5 и Перечисление 6 показывают примеры того, как установить форматы пикселя, которые являются единственным дисплеем только.

Перечисление 4  CGL единственный экранный формат пикселя

#include <OpenGL/OpenGL.h>

// a full screen single drawable set of pixel attributes
CGLPixelFormatAttribute attribs[] = { kCGLPFADisplayMask, 0,
                                      kCGLPFAFullScreen,
                                      kCGLPFADoubleBuffer,
                                      0 };
CGLPixelFormatObj pixelFormat = NULL;
long numPixelFormats = 0;
CGLContextObj cglContext = NULL;

// fill in display mask attrib for selected display
CGDirectDisplayID display = CGMainDisplayID ();
attribs[1] = CGDisplayIDToOpenGLDisplayMask (display); 
CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats);

Перечисление 5  AGL единственный экранный формат пикселя

#include <AGL/agl.h>

GLint attrib[] = {AGL_RGBA, GL_DOUBLEBUFFER, AGL_NO_RECOVERY, AGL_NONE};

GDHandle display = GetMainDevice ();
AGLPixelFormat aglPixFmt = aglChoosePixelFormat (&display, 1, attrib);

Перечисление 6  NSOpenGL единственный экранный формат пикселя

#import <Cocoa/Cocoa.h>

+ (NSOpenGLPixelFormat*)defaultPixelFormat
{
  NSOpenGLPixelFormatAttribute attributes [] = {
                               NSOpenGLPFAScreenMask,
                               0,
                               NSOpenGLPFANoRecovery,
                               NSOpenGLPFADoubleBuffer,  // double buffered
                               (NSOpenGLPixelFormatAttribute)nil };

// fill in display mask attrib for selected display
CGDirectDisplayID display = CGMainDisplayID ();
attributes[1] = (NSOpenGLPixelFormatAttribute) 
                                  CGDisplayIDToOpenGLDisplayMask (display);
return [[(NSOpenGLPixelFormat *)[NSOpenGLPixelFormat alloc] 
                                  initWithAttributes:attribs] autorelease];
}

Q: Какие-либо дополнительные примечания?

A: Если Ваш формат пикселя указан, чтобы поддерживать единственный дисплей, таким образом единственное средство рендеринга, понять, что перетаскивание оконного drawable на другой экран или присоединение полноэкранного контекста к другому дисплею, вероятно, приведет к неработающему рендерингу или рендерингу на указанном средстве рендеринга с копией через к недавно резидентному дисплею. Ни один из которых, вероятно, желательны. Разработчики должны кодировать защитно, чтобы обнаружить и обработать изменения средства рендеринга.

Q: Как насчет оконного drawables с полноэкранными форматами пикселя?

A: Для дальнейшего упрощения совместного использования контекстов оконного и полного экрана возможность использовать полноэкранные форматы пикселя для создания оконного drawables была добавлена к Mac OS X v10.3 Пантера. Это означает, что клиент может создать один формат пикселя с указанным полным экраном и использовать его для поддержки и контекстов оконного и полного экрана. Однако требования для полноэкранного формата пикселя для явной поддержки единственного дисплея и для совместно используемых форматов пикселя для поддержки той же самой экранной конфигурации не были ослаблены и должны все еще быть удовлетворены.



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


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

Обновленный и переформатированный текст. Измененная информация в последнем абзаце согласно radr://проблема/3968679

24.06.2003

Новый документ, что, как правильно совместно использовать контексты OpenGL и каковы пределы на этом совместном использовании.