CEF的那点事

CEF 是Chromium Embedded Framework的简称,是 Google 公司开发的一个浏览器内核框架,以开源库的方式提供,可以内嵌到第三方程序中用于显示网页以及和网页进行交互。

CEF 主要使用 C++语言进行开发,目前也有 CEF 的其他语言的绑定,比如 CefSharp 就是 C#的绑定。

CEF 老版本使用的 WebKit 内核,但从 2013 年开始,CEF 已经使用 Google 自主研发的 Blink 内核(网上也有人说,Blink 是基于 Webkit 修改而来,这个无从考证)。

官网

CEF 的官网是:https://bitbucket.org/chromiumembedded/cef/wiki/Home,国内用户访问可能不会太顺利。

版本

CEF 经历了 CEF1 和 CEF3 两个大版本,CEF1 现已基本被淘汰,目前主流的是 CEF3。

CEF3 在3683版本之前的版本定义规则为:CEF X.YYYY.A.gHHHHH ,
例如:CEF 3.3626.1895.g7001d56 / Chromium 72.0.3626.121

1
2
3
4
"X" :cef3的主版本号;
"YYYY" :Chrominum 分支号;
"A" : 代表当前分支中,提交次数的一个增量;
"gHHHHHHH" :取Git Commit的哈希值的7个字符,g为git的首字母

3683以后,CEF3 的版本定义规则发生了变化,改成了如下样式:CEF 73.1.3+g46cf800

我们可以从include\cef_version.h文件获取 CEF 版本相关的一些宏:

1
2
3
4
5
6
7
8
9
10
#define CEF_VERSION "3.3626.1894.g90eb8cc"
#define CEF_VERSION_MAJOR 3
#define CEF_COMMIT_NUMBER 1894
#define CEF_COMMIT_HASH "90eb8ccacc520cd83910a64dbb8fadd1a6c22258"
#define COPYRIGHT_YEAR 2019

#define CHROME_VERSION_MAJOR 72
#define CHROME_VERSION_MINOR 0
#define CHROME_VERSION_BUILD 3626
#define CHROME_VERSION_PATCH 96

预编译文件下载

CEF 官方提供了 Linux(32/64/ARM/ARM64)、MacOS X 64、Win32、Win64 平台的预编译好的库文件供下载,下载地址为:http://opensource.spotify.com/cefbuilds/index.html

以 Win32 平台为例,我们一般下载Standard Distribution即可。

Windows XP 支持

CEF 2623版本是最后一个支持 Windows XP 的版本,目前官方已经不提供预编译文件供下载,如果需要获取 2623 版本,有 2 种方式:

  1. 从第三方源下载。
  2. 从官方 git 下载 CEF 源码 checkout 到 2623 版本进行编译,当然这是一个漫长的过程。

作者已经将编译好的 CEF 2623 版本上传到https://github.com/winsoft666/cef_binary,该版本集成了对 MP4 的支持。

渲染模式

窗口模式

这个是 CEF 的默认模式,在这个模式下,CEF 会自动在指定的父窗体下创建一个子窗体,CEF 负责图形的绘制、鼠标键盘事件、窗体大小改变事件等,开发者不需要为这些事情操心。更重要的一点,在该模式下 CEF 支持 GPU 混合加速,性能更高,兼容性也更好,Chrome 等浏览器默认都是采用该模式。

混合加速可以通过--enable-gpu-compositing--disable-gpu-compositing参数来开启或关闭

我们可以通过 Spy++查看 CEF 自动创建的 D3D 子窗体。

离屏渲染模式

离屏渲染(Off-Screen Rendering)简称OSR

在该模式下,CEF 不会自动创建任何窗体,而是将图像数据返回给调用者,由调用者来负责图像的绘制工作,同时调用者还需要负责鼠标键盘事件、窗口大小改变等事件的处理。

所以,离屏渲染模式可以理解为:调用者将鼠标键盘事件、窗口信息(如大小,DPI 等)等传递给 CEF,CEF 根据这些信息将网页渲染到内存中,然后将内存数据传递给调用者,由调用者来负责显示。

采用这种模式虽然开发工作量比较大,但是灵活性更高,能满足各种定制要求,比如实现透明的、不规则的页面显示。

值得注意的是,该模式不支持混合加速,这就意味着在渲染复杂页面时(特别是有动画的页面)CPU 和 GPU 的占用将高于前面介绍的窗体模式。

源码编译

本文以CEF 3626版本为例,其他版本的编译可以用其作为参考。

准备工作

  • automate-git.py下载到E:\sourcecode\cef\automate-git.py
  • depot_tools下载到d:\soucecode\cef\source\depot_tools,并已经添加D:\sourcecode\cef\source\depot_tools到 Path 环境变量的头部

目录结构如下:

1
2
3
4
cef目录
- automate-git.py
- source目录
- depot_tools目录

源码下载

新建d:\sourcecode\cef\source\update_3626.bat文件:

1
2
3
set GN_DEFINES=use_jumbo_build=true proprietary_codecs=true ffmpeg_branding=Chrome
set GN_ARGUMENTS=--ide=vs2017 --sln=cef --filters=//cef/*
c:\Python27\python.exe ..\automate-git.py --download-dir=D:\sourcecode\cef\source --depot-tools-dir=D:\sourcecode\cef\source\depot_tools --no-distrib --no-build --branch=3626

然后,以管理员权限运行该文件,该文件中的命令会将 cef 源码下载d:\sourcecode\cef\source目录。

添加proprietary_codecs=true ffmpeg_branding=Chrome选项可以使 CEF 支持 MP4 等格式。

创建 Visual Studio 解决方案

创建D:\sourcecode\cef\source\chromium\src\cef\create.bat文件:

1
2
3
4
set Path=%Path%;D:\sourcecode\cef\source\depot_tools
set GN_DEFINES=use_jumbo_build=true proprietary_codecs=true ffmpeg_branding=Chrome
set GN_ARGUMENTS=--ide=vs2017 --sln=cef --filters=//cef/*
call cef_create_projects.bat

然后,以管理员权限运行该文件,该文件中的命令会创建visual studio 2017解决方案。

编译 Debug/Release 版本

创建D:\sourcecode\cef\source\chromium\src\x86_debug.bat文件:

1
ninja -C out\Debug_GN_x86 cef

创建D:\sourcecode\cef\source\chromium\src\x86_release.bat文件:

1
ninja -C out\Release_GN_x86 cef

分别执行x86_debug.batx86_release.bat即可分别编译 debug、release 版本。

打包

执行如下命令:

1
D:\sourcecode\cef\source\chromium\src\cef\tools\make_distrib.bat --ninja-build --output-dir=D:\sourcecode\cef\source\chromium\src\cef\binary_distrib

参考:
MasterBuildQuickStart > BranchesAndBuilding