C++ SDL导致CEF3生成额外的窗口

C++ SDL导致CEF3生成额外的窗口,c++,windows,sdl,sdl-2,chromium-embedded,C++,Windows,Sdl,Sdl 2,Chromium Embedded,我正试图让CEF3(Chromium Embedded Framework:)与SDL(Simple DirectMedia Layer:)一起工作 我对这两个库的预期用途是使用SDL打开窗口,从中接收事件并呈现OpenGL图形(与其他库(如GLEW)结合使用)。我想使用CEF3在屏幕外为用户界面渲染图形元素,然后通过OpenGL纹理在屏幕上显示它们。所有这些工作,我可以打开SDL窗口,处理事件,我可以绘制OpenGL纹理,并从CEF3的屏幕外渲染中获得与OpenGL兼容的数据 问题是,如果我在

我正试图让CEF3(Chromium Embedded Framework:)与SDL(Simple DirectMedia Layer:)一起工作

我对这两个库的预期用途是使用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();
}
void示例::webTest()
{
//Args
头孢菌素头孢菌素;
//背景
CEF设置CEF设置;
cefSettings.pack\u loading\u disabled=真;
cefSettings.windowless_rendering_enabled=true;
//初始化
CefInitialize(cefArgs、cefSettings、nullptr、nullptr);
//渲染处理程序
renderHandler=新的InterfaceRenderHandler();
//窗口信息
ceffindowinfo ceffindowinfo;
//ceffindowinfo.SetAsWindowless(0,true);
cefWindowInfo.windowless_rendering_enabled=true;
ceffindowinfo.transparent\u painting\u enabled=true;
//界面浏览器
CefRefPtr cefClient;
cefClient=新的InterfaceBrowserClient(renderHandler);
//浏览者
CefBrowserSettings CefBrowserSettings;
cefBrowserSettings.windowless_frame_rate=60;
CefBrowserHost::CreateBrowser(cefWindowInfo,cefClient.get(),”http://www.stackoverflow.com“,cefBrowserSettings,nullptr);
//螺纹环
线程渲染读取(renderLoop);
螺纹sdlThread(sdlLoop);
//主回路
CefRunMessageLoop();
//无线程
renderThread.join();
sdlThread.join();
//关闭
CefShutdown();
}
关于此代码的一些注释:

  • renderLoop函数用于收集完成的纹理,但目前没有任何功能
  • 函数sdlLoop只是轮询SDL窗口中的事件,然后丢弃它们
  • CefRunMessageLoop锁定程序。(我想它里面的某个地方有一个环)
  • 需要运行CefRunMessageLoop才能进行页面呈现,如果不在主线程中运行,它的行为似乎不正确
  • InterfaceBrowserClient是我基于CefClient实现的一个类,它在创建renderHandler时只返回renderHandler,而不执行其他任何操作
  • InterfaceRenderHandler是我基于CefRenderHandler实现的一个类。它向CEF3提供预期渲染区域的尺寸,并从CEF3接收完成的图像数据
  • 我把这些类的代码放在这里,以防有人需要看到它们
如果我在运行此代码之前初始化了一个SDL窗口,则会出现两个额外的窗口,一个出现在
newinterfacebrowserclient(renderHandler)上CefRunMessageLoop()时出现另一个已到达。这些窗口的尺寸与SDL窗口相同,并且具有相同的标题和内容(纯白色)。然后甚至坐在屏幕上完全相同的位置,这样只有最上面的一个是可见的。然而,虽然原始窗口是有响应的,但Windows认为这些窗口没有响应,就好像它们没有运行事件循环一样。我已经尝试将渲染大小更改为不同于窗口大小(这是在InterfaceRenderHandler中完成的),并且我确信他们复制的是SDL窗口的大小,而不是渲染区域的大小

如果不初始化SDL窗口,则根本不会显示任何窗口(当然,命令提示除外),渲染将正常进行(这可以从控制台在加载页面时打印警告中识别)

对窗口系统有更多了解的人是否理解为什么会出现这种情况,更重要的是,我如何摆脱这些额外的窗口?我没有在任何其他OSES上测试过,因为我对Linux C++编译了解不多,但是如果这个问题仍然存在,我会尝试它。
谢谢。

多个窗口可能是
CEF
生成其子进程、
GPU
渲染

对于子进程,只需调用
CefExecuteProcess
并返回其退出代码即可。这必须在其他代码执行之前发生。您可以在
cefsimple
应用程序中看到一个工作示例


我没有看到调用CefExecuteProcess()。您需要检查其退出代码并返回,因为CEF运行多个进程。参见cefclient和cefcomple示例:我插入了
CefExecuteProcess(cefArgs,nullptr,nullptr)在调用CefInitialize之前,没有对行为进行任何更改,渲染仍然很好地完成(就像以前一样,我设法提取了一个图像文件,渲染确实按照预期工作),窗口仍然出现。我很困惑,如果我返回,我肯定无法运行其余的代码?我试着运行
CefExecuteProcess(cefArgs,nullptr,nullptr)(不返回)在初始化之前,没有任何更改<代码>如果为浏览器进程调用(由无“type”命令行值标识),它将立即返回值-1
。对于您的主应用程序,代码将被忽略,因为它的检查是针对
>=0
,对于您的子进程应用程序,它们将正确执行。请参阅,我认为您可能需要仔细阅读这些页面,我已经查看了这些页面,并在CefExecuteProcess中添加了return(返回不会发生)。我仍然有多个窗口,我尝试基于您发布的示例中的SimpleApp实现我自己的CefApp,其代码如下:。你还有其他建议吗?好的,我已经修好了,结果我需要在
// 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;
}