Greetings,

Since llceflib has been made public and I could also find Callum's
viewer-cef branch on bibucket, I decided to give a try at a Linux build.

******** CHAPTER 1: an adventure (just kidding !) *********

As I anticipated, having llceflib built from the pre-built CEF3 binaries
( https://cefbuilds.com/ ) was quite easy (just a matter of writing two
CMakeLists.txt files, a llceflibimpl.cpp file, a build script (since I
don't use automake and the Linux stuff for it was missing anyway), and
fixing some non-ISO C++ conformant lines that made gcc choke).
Under three hours after I started (which includes the time it took to
backport the plugin code from viewer-cef to the Cool VL Viewer), I had
a successful build...

What I did not anticipate, however, was that libcef.so, while it was
working fine when used from the example cefclient shipped with CEF,
lamentably crashed when loaded from SLPlugin/media_plugin_cef...
The crash was:
*** glibc detected ***
/usr/local/CoolVLViewer-i686-1.26.15.0/bin/llplugin/SLPlugin: free():
invalid size: 0x08442000 ***
======= Backtrace: =========
/lib/i686/libc.so.6(+0x6cf32)[0xb722bf32]
/usr/local/CoolVLViewer-i686-1.26.15.0/lib/libcef.so(+0x8fe725)[0xb3720725]

The problem comes from the fact that libcef.so includes... tcmalloc !..
Of course, memory (i.e. classes, etc) allocated by SLPlugin before it
loads media_plugin_cef (which itself causes libcef.so to be loaded by
the dynamic linker), cannot be released afterwards (because then,
SLPlugin gets infected by tcmalloc, and ends up releasing with
tcmalloc's free() strucures that were allocated with the system
malloc()).
That's *really* a *very* stupid thing to link a custom memory allocator
to a dynamic library that may be loaded at any moment (and not only at
the consummer program's startup): CEF coders, shame on you !

The only solution is to rebuild libcef.so without tcmalloc (I also tried
and built the Cool VL Viewer with tcmalloc, since it's one of the options
I can enable with the flip of a cmake variable, but even this doesn't solve
the issue, since the two tcmalloc instances got different heaps and memory
pointers).

After rebuilding, the new, tcmalloc-less libcef.so works just fine. All
in all, and not counting the rebuilding time (building CEF from sources
involves the downloading of 16Gb of sources which take several hours to
compile), it took me just under 6 hours of actual work to have a
functional Linux build of the Cool VL Viewer with CEF.

******** CHAPTER 2: HOWTOs *********

I will give hereafter:

- For TPV developers, the pointers to ready-to-use files so to easily
  integrate CEF to their TPV Linux builds.

- For both TPV developers and Linden Lab (the latter stubornely refusing
  to reuse my code without a privacy-threatening CA, even though the said
  code is GPL/LGPL), directions/hints/advices on how to rebuild CEF on
  Linux and integrate it in a Linux viewer build (directions, hints and
  advices don't involve any copyright issue, so LL can reuse them without
  a CA !... No excuse any more, LL !).

A.- Ready to use stuff (for TPV developers):

- llceflib pre-compiled package with Linux binary (built on a Rosa 2012
  system with the following requirements for target systems: glibc v2.13
  or newer, libstdc++.so.6.0.16 (gcc v4.6) or newer, libX11 v1.5.0 or
  newer, libXi v1.6.0 or  newer (the latter two are in fact libcef.so
  requirements, see the chapter about runtime dependencies below).
  Get it from:
  http://sldev.free.fr/libraries/llceflib-linux-no_tcmalloc-20150709.tar.bz2
  md5sum: 3dd8afe90b8460da060362fad1de85fd

- Diff file, summing up all the changes I had to do to the Cool VL Viewer
  sources. Of course, that diff won't be directly usable as a patch file
  for your own viewer, but it will give you pointers and methods to what
  need to be changed in your own viewer. The diff file also includes the
  backport of Callum's viewer-cef code, with the necessary bug fixes. It
  also provides a new feature I implemented, allowing to switch between
  the WebKit and the CEF plugin in real time via the new UseCEF debug
  variable (i.e., after changing that variable, every newly spawn plugin
  uses the corresponding embedded browser). Get it from there:
  http://sldev.free.fr/libraries/patches/CoolVLViewer-CEF-diff.txt
  The diff was made against the current experimental version of the Cool
  VL Viewer, which sources are available (till next Saturday, after they
  will be updated to the next release) here:
  http://sldev.free.fr/sources/slviewer-src-cool_vl_viewer-1261318.tar.gz

- If you wish to rebuild your own lllceflib library yourself, first make
  sure you got the 'ninja' build tool installed on your system as well as
  a recent version of cmake (3.0 or newer).
  Then simply download the tcmalloc-less CEF3 bundle from:
  
http://sldev.free.fr/libraries/sources/cef_binary_3.2272.32.gbda8dc7_linux32-no_tcmalloc.tar.bz2
  as well as LL's 3p-llceflib sources from:
  https://bitbucket.org/lindenlab/3p-llceflib/get/tip.tar.bz2
  Untar 3p-llceflib, and inside its directory, untar the CEF3 bundle.
  Then get the following patch:
  http://sldev.free.fr/libraries/patches/llceflib.patch
  and apply it from inside 3p-llceflib directory, like so:
  patch -p1 -s </path/to/downloaded/patch/llceflib.patch
  and finally:
  sh ./linux-build
  (if not run as root, you'll be asked twice for a password, so that
  the "chrome-sandbox" binary can be chowned to root and set SUID).
  At the end of the short building process, you'll end up with a
  pre-packaged (tar-bziped) library and the script even gives you its
  md5sum.

B.- Directions/hints/advices for building a tcmalloc-less CEF3

If you are really masochistic and don't wish to reuse the build
(no code of mine involved there, just a pure rebuild from CEF3's
official sources) I made and uploaded, at:
http://sldev.free.fr/libraries/sources/cef_binary_3.2272.32.gbda8dc7_linux32-no_tcmalloc.tar.bz2
then you can follow the same recipe I followed/elaborated.
This build has been done via the procedure given at:
https://bitbucket.org/chromiumembedded/cef/wiki/BuildingOnDebian7.md
(BuildingOnDebian7) with the following adaptations:

1.- In step 1, I didn't use Debian 7 64 bits (or rather, I did first,
but had to abandon), because Debian 7 got an utterly broken multilib
support, and building a 32 bits CEF3 from a 64 bits Debian 7 is a
nightmare. Instead, I used Debian 7.8 (Wheezy) 32 bits, as available
here:
https://www.debian.org/releases/oldstable/debian-installer/
I used the i386 "netinst CD image" and installed it as a VirtualBox
VM running a on 64 bits Linux host (64 bits host, because else
VirtualBox won't allow setting the VM's RAM to over 3.5Gb, even when
both the host and guest OS got PAE support and thus 64Gb addressable
space...).

2.- In step 4, use the following command line instead:
./install-build-deps.sh --no-arm --no-chromeos-fonts --no-nacl
(i.e., omitting --no-lib32).

3.- Before step 8, create a ".gyp" directory in your home directory
(since BuildingOnDebian7 told you to run as root in step 4, you can
just stay as root during the whole building and thus create the
.gyp directory as /root/.gyp).
Inside that directory, create an include.gypi file and inside it,
put the following lines:
{
  'variables': {
        'use_allocator': 'none',
  },
}
That's how we tell to the build system to mind its own ass and not
forcefully link tcmalloc into libcef.so !

4.- In step 8, add "--no-debug-build" to the command line, after
"--force-build". We don't need the (enormous) Debug binaries, and
they would probably exhaust the 3Gb of virtual address space available
to the 32 bits ld anyway...

Note that step 5 takes about 2-3 hours (depending on potential retries
due to network glitches) with a 20Mbps download speed...
Step 8 will take 2 to many more hours, depending on your CPU speed
(do make sure to allow all cores to be used at 100% by the VirtualBoxed
Debian VM !). In fact, it would be a good idea to write a small bash
script that would include all commands from step 5 to 8 and launch
it in the evening before you go to bed; the next morning you'd get the
zipped distribution ready...

C.- Directions/hints/advices for Linux additions to 3p-llceflib,
aimed at the poor Lindens who are forbidden by LL's (bureaucratic,
narrow minded, UE privacy Law violating and totally paranoid) lawyers
to even glance at my code...

Once you got a rebuilt CEF3, you can include its directory in your
3p-llceflib sources.

The llceflib sources themselves need to have the Linux stuff added,
which is pretty simple. You'll need to write a CMakeLists.txt for
each the src/ and src/llceflib_host directories. For the
src/CMakeLists.txt, use the -fPIC compile option, so to get a
position-independent code.
In src/llceflib.h, you will have to add the LLCEFLIB_VERSION stuff
for Linux and also to change the non-ISO-C++ conformant code: it's
not allowed any more to initialize member variables in class/
structure declarations and (not so) recent versions of gcc choke
on it; simply use a default constructor for the LLCEFLibSettings
stucture and initialize the members in it.
Same thing with llceflibimpl.h: mViewDepth shall be initialized in
the constructor instanciated in llceflibimpl.cpp. Still in
llceflibimpl.cpp, beware of the include filename cases (Linux is
case sensitive for filenames) and you'll need to add a few
(trivial) lines in the three #if/#endif blocks for Linux...

You of course will also have to add a src/llceflibimpl_linux.cpp
file. I simply reused the code of llceflibimpl_mac.mm, with the key
codes inferred from:
http://src.chromium.org/viewvc/chrome/trunk/src/ui/events/keycodes/keyboard_code_conversion_x.cc

That's pretty much it... After adding the necessary commands
in your build-cmd.sh script, of course.

D.- Directions/hints/advices for inclusion of llceflib in Linux
viewers (again, mostly aimed at our poor, bureaucracy-impaired,
Lindens, but also of some interest for TPV developers).

In viewer-cef's indra/cmake/CEFPlugin.cmake file, the Linux
CEF_PLUGIN_LIBRARIES must account for the fact that, if not
told otherwise, ld will garabage-collect the linked static
libraries (libcef_dll_wrapper.a and libllceflib.a), and since
those contain functions that are interfaces to (and also called
by) libcef.so, but are not called from the CEF plugin itself,
ld will fail to retain these functions, causing unresolved
symbols errors to spawn at run time. You must therefore ensure
that the static libraries are included whole, by enclosing them
between -Wl,-whole-archive and -Wl,-no-whole-archive linker
directives.

In viewer-cef's indra/media_plugins/cef/media_plugin_cef.cpp,
be careful again with the filename case in the #includes...

In order for CEF to find its resource files (icudtl.dat, *.pak
files and locales, but also the *_blob.bin files which made
their appearance in CEF 3.2272), SLPlugin, media_plugin-cef,
llceflib_host, chrome-sandbox and all the resource files
and locales directory shall be kept in the same sub-directory.
Else, the icudtl.dat and *.pak files will first be searched
in the directory where SLPlugin resides, then in the one the
other executables (sandboxes, media-plugin) reside...
I solved this issue for my viewer by moving SLPlugin from
the bin/ sub-directory into the bin/llplugin/ sub-directory,
and installing all the CEF3 resources there as well.

In order for CEF to find its sandbox, you will need to add to
the newview/linux_tools/wrapper.sh file a couple of exports
(one for the PATH, including bin/llplugin/, and one for the
CHROME_DEVEL_SANDBOX variable, pointing to the chrome-sandbox
executable in bin/llplugin/).

******** VOLUME 3 ( or was that CHAPTER 3 ?... :-P ):
         first impressions on CEF *********

1.- Dependencies.

Unlike QtWebKit, CEF3 (and more accurately, libcef.so) depends
on MANY system libraries (try ldd libcef.so...), and it means
that it will be harder for 64 bits Linux users to get a 32 bits
viewer to run on their system (they will have to watch the
unresolved symbols error lines on a console and install the
corresponding 32 bits libraries on their system... I could cite,
from memory, ORBit2, libgio, libgamin, libcap, libxtst, libnss,
libnspr, and quite a few others... all of which were not needed
for 32 bits viewers using QtWebKit...

You also need a system with a recent libX11 (v1.4 or older won't
suffice and you'd get a _XGetRequest unresolved symbol) and a
recent libXi (v1.6 or newer) with XITouchClass implemented.
My Rosa 2012 system (released in 2012 as its name implies) still
had libX11 and libXi v1.4 and I therefore got unresolved errors
at first. The good news is that libX11 abd libXi updating doesn't
involve updating the whole X11 shebang, but it still excludes all
but the one and half year old or so Linux distros (unless their
user knows how to update and rebuild themselves some of their
distro's packages).

The rendering by CEF3 is MUCH SLOWER than what we get with QtWebKit
(the SL v3 login page will typically take from 30 seconds to 1
minute (!) to load, when only a dozen of seconds, at worst, were
enough for QtWebKit to render it). I'll have to investigate this
further, since I think I remember about an issue with WebKit (and
even before that, with mozilla when it was used for the built-in
browser) that involved the plugin eating up a full CPU core (and
IIRC, that was solved with a sleeping mechanism that could perhaps
get in the way now with CEF).

The font rendering by CEF3 is mediocre, to say the least (especially
for small size of fonts), but it might be a problem with how the
viewer uses fontconfig for itself. This will have to be investigated
as well prior to any release...

There's apparently a bug that causes CEF3 media to render upside-
down on prims with shared media...

Here are a few screen shots I took with the Cool VL Viewer in
both QtWebKit and CEF3 modes:
http://sldev.free.fr/pictures/CoolVLViewerCEF.png
http://sldev.free.fr/pictures/CoolVLViewerWebKit.png
http://sldev.free.fr/pictures/CoolVLViewerCEFV3Login.png
http://sldev.free.fr/pictures/CoolVLViewerWebKitV3Login.png
http://sldev.free.fr/pictures/CoolVLViewerCEFMedia.png
http://sldev.free.fr/pictures/CoolVLViewerWebKitMedia.png

As a last note, and interestingly, if you are curious enough, you
will notice that CEF3 is built upon... WebKit !... That pretty much
makes it a "bloated WebKit", and one could wonder if it won't be
more efficient to update/develop further QtWebKit than to adopt
CEF3, which seems to be having quite a few issues still to be
solved...

In the hope it will help.

Henri Beauchamp.
_______________________________________________
Policies and (un)subscribe information available here:
http://wiki.secondlife.com/wiki/OpenSource-Dev
Please read the policies before posting to keep unmoderated posting privileges

Reply via email to