2012-02-18 1 views
2

Я разрабатываю плагин с использованием FireBreath в Windows (на данный момент), который помимо прочего показывает отображение веб-камеры с использованием OpenGL. Я использую оконный плагин, и я рисую из отдельного потока. Код можно посмотреть здесь:Плагин OpenGL сбой Chrome при изменении видимой области

Заголовочный файл

https://github.com/EvilTengil/kinect-at-home-plugin/blob/0007beecf136ff2e5e1aa50be94d4906447a8f43/Win/KinectAtHomeWin.h

Исходный файл

https://github.com/EvilTengil/kinect-at-home-plugin/blob/0007beecf136ff2e5e1aa50be94d4906447a8f43/Win/KinectAtHomeWin.cpp

(Игнорировать странный код в onWindowResized, это лишь некоторые испытания, которые остались в коммит .)

Проблема в том, что как только окно браузера будет r e-size так, чтобы видимая область плагина была изменена или расширение как-то прокручивалось за пределами видимой области окна прокрутки, плагин сбой в Chrome. У меня нет установленного Firefox, но я предполагаю, что это приложение NpApi, так как оно работает в Internet Explorer.

Я считаю, что происходит то, что Chrome выпускает и создает новый HDC всякий раз, когда изменяются видимые размеры плагина. Вероятно, это приводит к тому, что контекст визуализации недействителен, но он все еще используется в плагине и вызывает сбои.

Я заметил, что NPP_SetWindow get вызывается, когда это происходит, но эти вызовы игнорируются в NpapiPluginModule_NPP.cpp, так что я не могу подключиться к этому событию.

У меня есть Google уже несколько часов, но не нашел никакой помощи. У кого-нибудь есть опыт?

У меня есть идея, что он может работать, если я создаю свое собственное дочернее окно в окне плагина, где я мог бы обрабатывать собственный DC. Я сделал несколько быстрых тестов, которые не удались, что, вероятно, связано с моими слабыми навыками Win32. Но может ли это работать с еще большей работой? Еще одна идея, которую я имею, - это как-то отслеживать видимый регион, но я пока не обратил на это внимания.

+0

Был бы быстрый взгляд на это, но нет времени копать глубже. Достаточно просто настроить OGL без рисования, что происходит в FF и Chrome, а не в FF, когда отключены внепроцессные плагины. Отключение подкласса окна FBs не помогает. Прикрепите Visual Studio с настроенным сервером символов Microsoft (возможно, [Mozillas] (https: //developer.mozilla.org/en/Using_the_Mozilla_symbol_server), и вы увидите, что он сбрасывается с переполнением стека в обработке обработки окон (видимо, бесконечная рекурсия). BTW, 'SetWindow' проходит через' FB :: NpapiPluginWin' здесь. –

ответ

1

Ошибки в работе Windows с ошибкой не должны приводить к сбою программы за так. Но OpenGL, а именно его расширения, требует особых предосторожностей, особенно если хост-программа также использует OpenGL.

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

HDC hOldDC = wglGetCurrentDC(); 
HRC hOldContext = wglGetCurrentContext(); 

// first unbind old context/DC from current thread 
wglMakeCurrent(NULL, NULL); 

// then bind our context 
wglMakeCurrent(hMyDC, hMyContext); 

// this is essential, as in Windows the addresses of extensions 
// may depend on the active context, so you must reinitialise 
// extension function pointers! 
reinitialize_extensions(); 

/* NOW USE OPENGL FUNCTION 

// cleaning up once we're done: 
wglMakeCurrent(NULL, NULL); 
wglMakeCurrent(hOldDC, hOldRC); 
// remember that we also need to reset extension 
// function pointers to the other context 
reinitialize_extensions(); 

Поскольку в окне функции расширения указатели зависят от контекста, имеет смысл поместить их в структуру и вызывать их через тот. Это экономит всю вещь для повторной инициализации. В C++ вы можете обернуть весь контекст OpenGL в классе для этого.

Помните, что вам нужно пройти эту настройку/разрывы каждый раз, когда ваш плагин вызывается через NP-API.

+0

Просто из любопытства у вас действительно были проблемы из-за недействительных указателей расширений? Я делал GL на Windows годами без проблем, но мне, возможно, повезло из-за выделенного оборудования, а не слишком часто возиться с несколькими одновременными контекстами. – rotoglup

+0

OP имеет код установки и рисования OpenGL в отдельном потоке, а [документы] (http://msdn.microsoft.com/en-us/library/dd374387 (v ​​= vs.85) .aspx) говорят, что вы получить один текущий контекст GL в потоке –

+0

@GeorgFritzsche: Если OP следовал моему совету, он также поддерживает многопоточность. Дело в многопоточности OpenGL заключается в том, что контекст должен быть активен только в одном потоке за раз и каждый поток имеет ровно один контекст. Но контекст может прекрасно переноситься между потоками. Вышеупомянутый код также будет заботиться о безопасности нескольких потоков. – datenwolf