Я пытаюсь установить CEF3 (Chromium Embedded Framework: https://bitbucket.org/chromiumembedded/cef ) для работы вместе с SDL (простой уровень DirectMedia: https://www.libsdl.org/).
Мое предполагаемое использование этих двух библиотек - использовать SDL для открытия окна, получения от него событий и визуализации графики OpenGL (вместе с другими библиотеками, такими как GLEW). Я хочу использовать CEF3 для визуализации графических элементов пользовательского интерфейса за пределами экрана, а затем отображать их на экране с помощью текстур OpenGL. Все это работает, я могу открывать окна SDL, обрабатывать события, я могу рисовать текстуры OpenGL и получать данные, совместимые с OpenGL, из внеэкранного рендеринга в CEF3.
Проблема в том, что если я запускаю SDL и CEF3 вместе в тестовой среде, CEF3 порождает несколько дополнительных окон.
Это код, который я использую для CEF3.
void Example::webTest()
{
//Args
CefMainArgs cefArgs;
//Settings
CefSettings cefSettings;
cefSettings.pack_loading_disabled = true;
cefSettings.windowless_rendering_enabled = true;
//Initialize
CefInitialize(cefArgs, cefSettings, nullptr, nullptr);
//Render Handler
renderHandler = new InterfaceRenderHandler();
//Window Info
CefWindowInfo cefWindowInfo;
//cefWindowInfo.SetAsWindowless(0, true);
cefWindowInfo.windowless_rendering_enabled = true;
cefWindowInfo.transparent_painting_enabled = true;
//Interface Browser
CefRefPtr<InterfaceBrowserClient> cefClient;
cefClient = new InterfaceBrowserClient(renderHandler);
//Browser
CefBrowserSettings cefBrowserSettings;
cefBrowserSettings.windowless_frame_rate = 60;
CefBrowserHost::CreateBrowser(cefWindowInfo, cefClient.get(), "http://www.stackoverflow.com", cefBrowserSettings, nullptr);
//Threaded Loops
thread renderThread(renderLoop);
thread sdlThread(sdlLoop);
//Main Loop
CefRunMessageLoop();
//Unthread
renderThread.join();
sdlThread.join();
//Shutdown
CefShutdown();
}
Несколько примечаний по этому коду:
- Функция renderLoop предназначена для сбора готовых текстур, но в настоящее время ничего не делает.
- Функция sdlLoop просто опрашивает окно SDL на предмет событий, а затем отбрасывает их.
- CefRunMessageLoop блокирует программу. (Я предполагаю, что где-то внутри есть петля).
- Для отрисовки страницы необходимо запустить CefRunMessageLoop, и, похоже, он не ведет себя правильно, если не выполняется в основном потоке.
- InterfaceBrowserClient - это класс, который я реализовал на основе CefClient, который просто возвращает renderHandler при вызове, с которым он был создан, и больше ничего не делает.
- InterfaceRenderHandler - это класс, который я реализовал на основе CefRenderHandler. Он предоставляет размеры предполагаемой области рендеринга в CEF3 и получает данные готового изображения из CEF3.
- Я поместил здесь код классов http://pastebin.com/sBm9AAQZ на тот случай, если кому-то понадобится их.
Если я инициализирую окно SDL перед запуском этого кода, появляются два дополнительных окна, одно появляется в new InterfaceBrowserClient(renderHandler);
, а другое появляется при достижении CefRunMessageLoop();
. Эти окна имеют те же размеры, что и окно SDL, и имеют тот же заголовок и такое же содержимое (чистый белый цвет). Затем даже сядьте в точно такое же положение на экране, чтобы был виден только верхний. Однако, хотя исходное окно является отзывчивым, Windows считает эти окна невосприимчивыми, как будто в них нет запущенных циклов обработки событий. Я попытался изменить размер рендеринга, чтобы он отличался от размера окна (это делается внутри InterfaceRenderHandler), и я уверен, что они копируют размер окна SDL, а не размер области рендеринга.
Если я не инициализирую окно SDL, никакие окна не появляются вообще (за исключением, конечно, командной строки), и рендеринг выполняется как обычно (это можно определить по консоли, выводящей предупреждения при загрузке страницы).
Кто-нибудь, кто знает больше об оконной системе, понимает, почему это происходит, и, что более важно, как мне избавиться от этих дополнительных окон? Я не тестировал это ни на каких других ОС, потому что я мало знаю о компиляции Linux C ++, но я попробую, если проблема не исчезнет.
Спасибо.
CefExecuteProcess(cefArgs, nullptr, nullptr);
перед вызовом CefInitialize, никаких изменений в поведении, рендеринг по-прежнему завершается нормально (как и раньше, мне удалось извлечь файл изображения, и рендеринг действительно работает, как задумано), и окна все еще появляются. - person user573949   schedule 14.07.2015