2015-07-14 3 views
1

Я пытаюсь получить CEF3 (Chromium Embedded Framework: https://bitbucket.org/chromiumembedded/cef) для совместной работы с SDL (простой DirectMedia Layer: https://www.libsdl.org/).SDL заставляет CEF3 создавать дополнительные окна

Назначение этих двух библиотек - использование 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 должен выполняться для визуализации страницы, и, похоже, он не работает корректно, если не запускается в основном потоке.
  • ИнтерфейсBrowserClient - это класс, реализованный на основе CefClient, который просто возвращает renderHandler, когда он был создан, и ничего не делает.
  • InterfaceRenderHandler - это класс, реализованный на основе CefRenderHandler. Он предоставляет размеры предполагаемой области визуализации для CEF3 и получает готовые данные изображения из CEF3.
  • Я разместил код для классов здесь http://pastebin.com/sBm9AAQZ в случае, если кто-то должен их увидеть.

Если я инициализировать SDL окно перед запуском этого кода, появляются два дополнительных окна, один появляется new InterfaceBrowserClient(renderHandler);, а другой появляется, когда CefRunMessageLoop(); достигается. Эти окна имеют те же размеры, что и окно SDL, и имеют одинаковый заголовок и один и тот же контент (чистый белый). Затем даже сидите в точно таком же положении на экране, чтобы видна только верхняя. Однако, когда исходное окно реагирует, Windows считает эти окна неактивными, как будто они не имеют циклов событий. Я попытался изменить размер рендеринга, чтобы он отличался от размера окна (это делается внутри InterfaceRenderHandler), и я уверен, что это размер окна SDL, которое они копируют, а не размер области визуализации.

Если я не инициализирую окно SDL, окна вообще не отображаются (за исключением командной строки), и рендеринг выполняется как обычно (это можно идентифицировать из предупреждений консоли при печати при загрузке страницы) ,

Кто-нибудь, кто знает больше об оконной системе, понимает, почему это происходит и что еще более важно, как мне избавиться от этих дополнительных окон? Я не тестировал это на каких-либо других операционных системах, потому что я мало разбираюсь в компиляции Linux C++, но я попытаюсь, если эта проблема сохранится.

Спасибо.

+0

Я не вижу CefExecuteProcess() вызывается. Вам нужно проверить его код выхода и вернуть его, поскольку CEF запускает несколько процессов. См. Примеры cefclient и cefsimple: https://bitbucket.org/chromiumembedded/cef/src/aefb5ccce879f308f0bcc3ac719c86defe2f9715/tests/cefsimple/cefsimple_win.cc?at=master –

+0

Я вставил 'CefExecuteProcess (cefArgs, nullptr, nullptr);' перед вызов CefInitialize, никаких изменений в поведении, рендеринг по-прежнему прекрасен (как и раньше, мне удалось извлечь файл изображения, а рендеринг действительно работает по назначению), и окна все еще появляются. – user573949

ответ

1

Множественные окна, вероятно CEF нерест это суб-процессы, GPU, Render и т.д.

В случае суб-процессов вам просто нужно позвонить CefExecuteProcess и вернуть его код выхода. Это должно произойти до выполнения другого кода. Вы можете увидеть рабочий пример как часть приложения cefsimple.

https://bitbucket.org/chromiumembedded/cef/src/aefb5ccce879f308f0bcc3ac719c86defe2f9715/tests/cefsimple/cefsimple_win.cc?at=master#cl-51

// CEF applications have multiple sub-processes (render, plugin, GPU, etc) 
// that share the same executable. This function checks the command-line and, 
// if this is a sub-process, executes the appropriate logic. 
int exit_code = CefExecuteProcess(main_args, app.get(), sandbox_info); 
if (exit_code >= 0) { 
    // The sub-process has completed so return here. 
    return exit_code; 
} 
+0

Я смущен, конечно, если я вернусь, я не могу запустить остальную часть кода? Я попытался запустить CefExecuteProcess (cefArgs, nullptr, nullptr); '(без возврата) до CefInitialize и ничего не изменилось. – user573949

+0

https://bitbucket.org/chromiumembedded/cef/src/aefb5ccce879f308f0bcc3ac719c86defe2f9715/include/cef_app.h?at=master#cl-52 'Если вызывается для процесса браузера (не указано значение командной строки типа" type ") он немедленно вернется со значением -1'. Для вашего основного приложения код будет проигнорирован, так как проверка выполняется для '> = 0', для ваших приложений подпроцесса они будут выполняться правильно. – amaitland

+0

См. Я думаю, вам может потребоваться прочитать https://bitbucket.org/chromiumembedded/cef/wiki/Architecture.md#markdown-header-process-considerations – amaitland

Смежные вопросы