c++ - SDL 导致 CEF3 产生额外的窗口

标签 c++ windows sdl sdl-2 chromium-embedded

我正在尝试让 CEF3(Chromium 嵌入式框架:https://bitbucket.org/chromiumembedded/cef)与 SDL(简单 DirectMedia 层:https://www.libsdl.org/)一起工作。

我对这两个库的预期用途是使用 SDL 打开一个窗口,从中接收事件并渲染 OpenGL 图形(与 GLEW 等其他库一起使用)。我想使用 CEF3 在屏幕外渲染用户界面的图形元素,然后通过 OpenGL 纹理将它们显示在屏幕上。所有这些都有效,我可以打开 SDL 窗口,处理事件,我可以绘制 OpenGL 纹理并从 CEF3 中的屏幕外渲染中获取 OpenGL 兼容数据。

问题是,如果我在测试环境中同时运行 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++ 编译了解不多,但如果这个问题仍然存在,我会尝试一下。

谢谢。

最佳答案

多个窗口可能是 CEF 产生它的子进程、GPURender 等。

对于子进程,您只需调用 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;
}

关于c++ - SDL 导致 CEF3 产生额外的窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31415228/

相关文章:

C++: vector 实现和动态内存分配

c++ - SDL调整窗口大小

在 C 中将 Uint16 转换为字符串

python - 'from .. import module' 是什么意思?

c++ - 模板化函数的C++模板子类参数

c++ - 下标运算符重载 : returning reference problems

c++ - 使用 MPI_Barrier() 后 MPI_Wtime() 的巨大差异?

c - 如何在 C (Windows) 中打印方框字符

windows - GetMessage 是否需要 GUI

c++ - 程序运行时没有任何反应(并且没有创建窗口)