简体   繁体   English

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

[英]How do I detect “invalid drawable” in Mac OS X?

I am working on a cross platform application that is over a decade old. 我正在研究一个已有十多年历史的跨平台应用程序。 The UI is by Qt and backend rendering is done with OpenGL. UI由Qt提供,后端渲染由OpenGL完成。 OpenGL contexts are managed in the back end, not by Qt. OpenGL上下文在后端管理,而不是由Qt管理。

I have recently added error checking and reporting for all OpenGL code in our app. 我最近在我们的应用程序中添加了所有OpenGL代码的错误检查和报告。 Occasionally a situation arises where the first render initiated by Qt causes an "invalid drawable" error message in the terminal and all subsequent OpenGl calls fail with an "invalid framebuffer" error reported. 偶尔出现这样的情况,即Qt启动的第一个渲染在终端中导致“无效的可绘制”错误消息,并且所有后续的OpenGl调用失败并报告“无效的帧缓冲”错误。 These invalid drawable error messages have been treated as innocuous in the past, since before the user sees it the drawable eventually becomes valid and the scene is rendered correctly. 这些无效的可绘制错误消息在过去被视为无害,因为在用户看到它之前,drawable最终变为有效并且场景被正确呈现。 However, with the new OpenGL error check/report it's not possible since there are large numbers of errors reported. 但是,由于报告了大量错误,因此无法使用新的OpenGL错误检查/报告。

I would like to test if the drawable is valid. 我想测试drawable是否有效。 If it is not, it should return before the render starts. 如果不是,则应在渲染开始之前返回。 How can I verify that the drawable is valid? 如何验证drawable是否有效?

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

I don't know at what API level you're working. 我不知道你正在使用什么API级别。 I'm not sure it's possible to detect the problem after the fact. 我不确定事后可以发现问题。 That is, if all you have is a context (perhaps implicit as the thread's current context) that failed to connect to its drawable. 也就是说,如果您拥有的是一个上下文(可能隐含为线程的当前上下文),则无法连接到其drawable。

I presume that Qt is using Cocoa under the hood. 我认为Qt正在使用Cocoa。 I further assume it has created an NSOpenGLContext and is invoking -setView: on it. 我进一步假设它创建了一个NSOpenGLContext并在其上调用-setView: . You get that "invalid drawable" error if, at the time of that call, the view's window doesn't have a window device. 如果在该调用时,视图的窗口没有窗口设备,则会出现“无效的drawable”错误。

One common technique is to defer setting the context's view until the view has -drawRect: called on it, since at that point you're sure that the view has a window and the window has a device. 一种常见的技术是推迟设置上下文的视图,直到视图有-drawRect:调用它,因为此时你确定视图有一个窗口,窗口有一个设备。 (Although that ignores the possibility of forced drawing outside of the normal window display mechanism. For example, -cacheDisplayInRect:toBitmapImageRep: .) (虽然这忽略了在正常窗口显示机制之外强制绘制的可能性。例如, -cacheDisplayInRect:toBitmapImageRep: .)

If you just want to know at the point of the call to -setView: whether it's safe or not, I think you can rely on checking the value of [[view window] windowNumber] . 如果你只想知道调用-setView:是否安全,我认为你可以依靠检查[[view window] windowNumber] The docs for -windowNumber say: -windowNumber的文档说:

If the window doesn't have a window device, the value returned will be equal to or less than 0. 如果窗口没有窗口设备,则返回的值将等于或小于0。

Another approach is to prevent the problem rather than detect it. 另一种方法是防止问题而不是检测它。 The strategy for that is basically to make sure the window has been shown and drawn before the call to -setView: . 这个策略基本上是为了确保在调用-setView:之前显示和绘制窗口。 You may be able to force that by ordering it on-screen and invoking -display on it. 您可以通过在屏幕上对其进行排序并在其上调用-display来强制执行此操作。

Ken Thomases post gave me the basic info I needed to find a workable solution. Ken Thomases的帖子给了我找到可行解决方案所需的基本信息。 An additional conditional was needed. 需要另外的条件。 Here's what worked 这是有效的

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM