如何在Mac OS X中检测到“无效的可绘制”?

时间:2013-04-10 20:47:24

标签: macos opengl ati

我正在开发一个已有十多年历史的跨平台应用程序。 UI由Qt提供,后端渲染由OpenGL完成。 OpenGL上下文在后端管理,而不是由Qt管理。

我最近在我们的应用中添加了所有OpenGL代码的错误检查和报告。偶尔出现这样的情况,即Qt启动的第一个渲染在终端中导致“无效的可绘制”错误消息,并且所有后续的OpenGl调用失败并报告“无效的帧缓冲”错误。这些无效的可绘制错误消息在过去被视为无害,因为在用户看到它之前,drawable最终变为有效并且场景被正确呈现。但是,由于报告了大量错误,因此无法使用新的OpenGL错误检查/报告。

我想测试drawable是否有效。如果不是,则应在渲染开始之前返回。如何验证drawable是否有效?

MacBook Pro,OS X Mountain Lion(10.8.3),ati显卡

2 个答案:

答案 0 :(得分:4)

我不知道您正在使用哪种API级别。我不确定事后可以发现问题。也就是说,如果您拥有的是一个上下文(可能隐含为线程的当前上下文),则无法连接到其drawable。

我认为Qt正在使用Cocoa。我进一步假设它创建了一个NSOpenGLContext并在其上调用-setView:。如果在该调用时,视图的窗口没有窗口设备,则会出现“无效的可绘制”错误。

一种常见的技术是推迟设置上下文的视图,直到视图调用-drawRect:为止,因为此时你确定视图有一个窗口,窗口有一个设备。 (虽然这忽略了在正常窗口显示机制之外强制绘制的可能性。例如,-cacheDisplayInRect:toBitmapImageRep:。)

如果您只是想知道-setView:的来电是否安全,我认为您可以依靠检查[[view window] windowNumber]的值。 -windowNumber的文档说:

  

如果窗口没有窗口设备,则返回的值将等于或小于0.

另一种方法是防止问题而不是检测问题。对此的策略基本上是确保在调用-setView:之前已显示和绘制窗口。您可以通过在屏幕上对其进行排序并在其上调用-display来强制执行此操作。

答案 1 :(得分:0)

Ken Thomases的帖子给了我找到可行解决方案所需的基本信息。需要另外的条件。这是有用的

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