Как определить "недопустимое рисование" в Mac OS X?
Я работаю над кроссплатформенным приложением, которому более десяти лет. Пользовательский интерфейс выполнен с помощью Qt, а рендеринг сервера выполняется с помощью OpenGL. Контексты OpenGL управляются в бэкэнде, а не в Qt.
Недавно я добавил проверку ошибок и отчетность для всего кода OpenGL в нашем приложении. Иногда возникает ситуация, когда первый рендеринг, инициированный Qt, вызывает сообщение об ошибке "недопустимый вывод" в терминале, и все последующие вызовы OpenGl завершаются с ошибкой "недопустимый кадровый буфер". Эти недопустимые сообщения об ошибках рисования были обработаны как безвредные в прошлом, так как перед тем, как пользователь увидит их, рисование в конечном итоге становится действительным и сцена отображается правильно. Однако с новой проверкой / отчетом об ошибках OpenGL это невозможно, так как сообщается о большом количестве ошибок.
Я хотел бы проверить, действителен ли Drawable. Если это не так, он должен вернуться до начала рендеринга. Как я могу проверить, что отрисовка действительна?
MacBook Pro, OS X Mountain Lion (10.8.3), графическая карта ATI
2 ответа
Я не знаю, на каком уровне API вы работаете. Я не уверен, что возможно обнаружить проблему после факта. То есть, если все, что у вас есть, это контекст (возможно, неявный, как текущий контекст потока), который не смог подключиться к его рисуемой.
Я предполагаю, что Qt использует Какао под капотом. Я также предполагаю, что это создало NSOpenGLContext
и вызывает -setView:
в теме. Вы получаете эту "недопустимую отрисовываемую" ошибку, если во время этого вызова у окна представления нет оконного устройства.
Один из распространенных методов - отложить настройку представления контекста до -drawRect:
вызвал его, так как в этот момент вы уверены, что у представления есть окно, а у окна есть устройство. (Хотя это игнорирует возможность принудительного рисования за пределами обычного механизма отображения окна. Например, -cacheDisplayInRect:toBitmapImageRep:
.)
Если вы просто хотите знать, в точке вызова -setView:
безопасно это или нет, я думаю, что вы можете положиться на проверку ценности [[view window] windowNumber]
, Документы для -windowNumber
сказать:
Если у окна нет оконного устройства, возвращаемое значение будет равно или меньше 0.
Другой подход заключается в предотвращении проблемы, а не в ее обнаружении. Стратегия для этого заключается в том, чтобы убедиться, что окно было показано и нарисовано до вызова -setView:
, Вы можете быть в состоянии заставить это, заказав это на экране и вызвав -display
в теме.
Кен Томасес пост дал мне основную информацию, необходимую для поиска работоспособного решения. Требовалось дополнительное условие. Вот что сработало
//----------------------------------------------------------------------------
bool vtkCocoaRenderWindow::IsDrawable()
{
// you must initialize it first
// else it always evaluates false
this->Initialize();
// first check that window is valid
NSView *theView = (NSView*)this->GetWindowId();
bool win =[[theView window] windowNumber]>0;
// then check that the drawable is valid
NSOpenGLContext *context = (NSOpenGLContext *)this->GetContextId();
bool ok = [context view] != nil;
return win && ok;
}