Berkelium
Over the past three months, we’ve been working on a new BSD-licensed browser engine called Berkelium. Berkelium is a library that provides off-screen browser rendering via Google’s open source Chromium and takes advantage of Chromium’s multi-process rendering engine, allowing us to safely isolate browser instances.  Best of all, it is independent of Sirikata—you can incorporate it into any project to get a simple, easy to use API for off-screen web browsers.  We’ve started using it in Sirikata to allow arbitrary 3d objects to contain browsers, and in the future, objects may be able to run a user interfaces and even entire object scripts within the sandbox of a browser window.
Berkelium should support plugins, but currently that support is limited to Flash (on all platforms). Hopefully many needs will be addressed by new features in HTML5. For those that aren’t, we believe Flash is able to fill the gap. (For the curious with some spare time, it may be possible to use a hooked HDC on Windows, and to use the X11 Composite extension to render plugins to OpenGL on Linux. However, we suspect enabling arbitrary plugins and programs in this way would take a good month of work to get right.)
And, of course, we wouldn’t leave you without a demo of the browser in action in Sirikata:
December 26th, 2009 at 18:18
Congratulations and thanks for releasing this. I look forward to trying it, I have many potential uses for server-side and in-memory browser rendering. I'm intrigued though – I thought I saw a few Sirikata mailing list comments about Awesomium – does Berkelium fill the same role as Awesomium? What differences are there? They look to cover the same ground using the same unerlying engine.
December 27th, 2009 at 03:36
Neil – They do fill a very similar need. Berkelium uses a layer of Chromium built on top of WebKit instead of using some of the WebKit code directly. There are a couple of benefits to this. The two primary ones are that, first, the API for this layer is much more stable than the one that Awesomium uses, which makes it much less of a hassle to track the main Chromium tree, and second, that by using this layer we get the multiprocess rendering almost for free, which is great for isolating pages from each other from both a security and performance point of view.
So from a technical perspective they are different solutions to the same problem with different tradeoffs. Beyond that, we also prefer libraries that are developed in the open and that are easier for us to participate in the development of. While Awesomium has a similar feature list, and in fact has quite a few features Berkelium doesn't, it didn't feel like quite the right fit for our project. Just like in the browser space, we think its worthwhile exploring a number of different avenues of development before settling on a long term solution.
December 27th, 2009 at 10:29
OK, thanks for that – a very comprehensive and comprehendable reply. Do you know if anyone right now is likely to be working on any C# bindings for Berkelium? I appreciate that it isn't quite that kind of component yet, being open source with no binary distribution, but I thought I'd ask anyway :-)
December 27th, 2009 at 16:16
Neil – I don't think anybody is currently working on bindings, but the API is currently pretty thin (see the small set of files in the berkelium/include/ directory) so I think it would be pretty easy to get a binding up and running.
February 21st, 2010 at 10:50
I hacked together a C++/CLI wrapper for Berkelium along with a simple example in C# that implements a mostly working browser.
You can check out the source at http://code.google.com/p/berkelium-sharp/ if you're interested. It seems pretty likely that this could be taken all the way for fully functional embedding.
February 21st, 2010 at 14:51
Very cool! I am still evaluating if to go and invest time in Berkelium (I need a WPF based webkit component) and this layer is definitely a good thing for me. Thanks.
Do you happen to have a simple demo exe that includes the necessary dlls I could test? I would rather test that before going to build chromium and berkelium… Thanks a bunch!
February 23rd, 2010 at 10:05
The demos come with all the necessary binaries.
http://berkelium-sharp.googlecode.com/files/Berke…
February 23rd, 2010 at 10:44
Thank you so much for this Kevin!
One problem though, I cannot run it… I get an unhandled exception when running BerkeliumSharp.exe (cannot load file or assembly BerkeliumSharp…) and I get a crash at start up when running BerkeliumXNATest.exe.
Any idea? anything I am doing wrong?
Thanks
December 27th, 2009 at 10:54
[…] have been pretty excited about our embedded browser Berkelium and it was good to see Patrick pull the trigger on it. Within our group there is an emerging sense that this technology is going to mean something and I […]
January 4th, 2010 at 05:40
Is there a binary distribution available? Or are there any plans to make one available? Building Chromium is a pain and if one can avoid it, it is a blessing…
January 4th, 2010 at 13:55
Hi,
It seems pretty nice!
I am currently using Awesomium 1.08 (the latest open source version…) and I have few problems with it, especially one: Clicking on Flash files only works if the action is handled by the flash itself (like clicking on "play" in youtube). If the click is supposed to trigger a browser event (navigate to URL) then click on Flash does not work…
Can you tell me if this is also the case with Berkelium? Do you have any demo app I can install in order to try by myself (I would like to avoid compiling, building a demo app and so on at this stage!)
Last, same question as above… any binaries available?
Thanks!
January 4th, 2010 at 11:48
[…] client stack. This would allow a Sirikata viewer, such as one based upon their new browser engine Berkelium, to connect with […]
January 4th, 2010 at 19:55
Hi benjo
Sorry for the delayed response, but you can see Berkelium in action through our nightly builds and downloading an empty scene file with just a camera
I've done so here
http://graphics.stanford.edu/~danielrh/SirikataBe…
download, unzip and use the + on the browser bar to make a new window… It doesn't show the window in 3d yet, but it does reside on a texture so we could just as easily translate it around… making a more flashy prebuilt demo like the one you saw the video of for windows is not on the radar right now, but you can download the source and build it if you wish. Otherwise this should let you know if the feature you need is supported yet
-Daniel
January 5th, 2010 at 15:13
Hi Daniel and thank you and your team for great Berkelium :)
I tried SirikataBerkelium demo. First i tried to run proximite.exe and then space.exe and after that i runned cppoh.exe. Sirikata window opened but i got only blue screen with grey box. Grey box is where the Chromium addressbar should be. If i click this grey area the demo crashes. Do you have any clues where the problem could be? Am I doing all the reguired steps to start the demo?
January 6th, 2010 at 08:16
Your steps sound right… What a gray box means is that berkelium loaded but when it tried to spawn the browser subprocesses something wrong happened–maybe the subprocesses didn't have the right resources available or maybe there were windows permission problems.
Generally when that fails so, too, does double clicking berkelium.exe, which should launch a full-featured chrome browser.
What happens when you double click berkelium.exe? Also maybe sending your console output during the run would be helpful– the blue screen is expected since no objects were in the test scene I zipped
January 6th, 2010 at 10:01
For Berkelium to work in Windows Vista and Windows 7, you need an extra wrapper program for the sandbox to work. I don't think our install script installs this yet.
You can download it directly from the chromium source tree here:
http://src.chromium.org/svn/trunk/src/sandbox/wow…
Then, put it into the same binary directory as berkelium.exe and all the dlls.
January 7th, 2010 at 06:28
Thanks Daniel and Patrick :) I downloaded the wrapper program and now everything works great :)
January 4th, 2010 at 19:56
Ronen: yes there is a binary Berkelium SDK for windows that lets you avoid building the whole thing yourself
http://sirikatawin32.googlecode.com/svn/trunk/ber…
the other platforms have automated build scripts that come with the berkelium source, so you just hit make and it does the rest (downloading, etc)
January 5th, 2010 at 07:03
Thanks for the reply and links!
One more question though (even if it might sound like a newbie one:-)!):
Awesomium is 8Mb (unzipped) and I needed as well icudt38.dll which was another 8Mb so all together I have an overhead of 16Mb in my app. I see that the SDK is 56.5Mb! So my question is what is the minimum overhead I can get to have a functional browser? do I need the all 56Mb in release?
Thanks
January 6th, 2010 at 20:14
Awesomium avoids the chrome layer and merely routes around it, using only the webkit internals (which is why it was so difficult to keep it up to date with the bug and security fixes of chrome). We need a fully functioning chrome browser so that you can execute the new process in berkelium.exe
Note that if you double click berkelium.exe you get a full featured chrome browser: this is necessary to have the multiprocess work and bring with it all the safety and futureproofing that multiprocess gets you. You probablby can strip down the .pak files somewhat, and only include english locales, etc depending on your target audience. Let me know how far you get in your experimentation with stripping down the .pak files. Also however the chrome team packs up chrome we can probably do the same thing for berkelium since we include a virtually unmodified browser in the berkelium.exe dll–and I think they've gotten it way down below 56 megabytes–so maybe the place to go is investigation of the chrome setup/install tools
January 7th, 2010 at 07:52
Thank you Daniel for the explaination. I will play with it as you suggested.
As you pointed out, it is really great to have a full embed-able browser already… I'll worry about the size later! :-)
January 5th, 2010 at 16:04
Thank you Daniel! This is great. Any thoughts about getting Silverlight to work in addition to Flash?
January 6th, 2010 at 20:08
I played with silverlight a bit–it does not apparently respect the ordering constraints that you can ask Flash to respect— by asking Flash to remain in the proper ordering with the rest of the webpage it coordinates well with Chrome and delivers a buffer past the interprocess mark that's got all the correct pixels for the webpage+flash.
Apparently silverlight ignores this ordering request and hence expects berkelium to hand it a hWnd and then composite it manually into a memory buffer after the interprocess layer. I'm not exactly sure how to get this offscreen hWnd in windows, being primarily a linux dev. If someone has the wherewithal to help with silverlight and java plugins, I'm sure it's possible to get it working, but it will need some windows dev smarts.
January 8th, 2010 at 19:15
Looks great! Can't wait to dig into the further. The demo still leaves me with a question though, does berkelium support transparency?
January 8th, 2010 at 20:35
It supports transparency in the sense that you can munge the data before passing it to your rendering pipeline. For instance, you could easily filter a special color, marking the alpha channel as 0 for those pixels. I'm not sure about not fully opaque output directly from Berkelium, but that's more a matter of whether Chromium supports transparency rather than Berkelium. If you're curious about the equivalent of transparency in Awesomium, that was accomplished by filtering a special color, which isn't built into Berkelium but is trivial to implement.
January 9th, 2010 at 09:45
I do believe there is an option per window to turn on full fledged translucency for that window (certain webpages look really bad with transparency but we can use it for drag and drop/other things)
I remember I had a javascript test webpage up that was transparent.
In fact that's one of our small patches to chrome to fix their white-padded RGB channel to actually have transparency if you wanted it.
January 28th, 2010 at 16:27
I've been playing around with the source for a while now and I finally got it to compile *almost* properly (in Windows). Release build works fine, I've only tested the ppmrender example but it worked just fine. Unfortunately debug builds are a real pain in the arse.
The first brick wall I hit was the annoying DCHECK macros in Chromium debug build. This could be solved by redefining the macros to actually work like they do in Release builds (shows an error dialog but then continues execution). After this little tweak and recompilation of Chromium source the Berkelium subprocess now runs. Unfortunately another problem surfaced straight away, the ppmrender example crashes straight away after Berkelium::Window::create() when we actually try to do something with the window. I'm not entirely sure where to put my finger on that one but the error being an access violation without a sensible call stack I'm guessing it might have something to do with memory allocation, after all Chromium uses tcmalloc itself and ppmrender probably (?) does not and in the end links to the default libcmt, causing problems. The strange thing is that Release build works just fine but Debug does not! I'm not quite sure how to deal with it, I've tried fiddling with /NODEFAULTLIB with no success.
Has anyone else run into these problems? Perhaps I'm just dumb in this department and the solution is obvious, if that is the case then please educate me ;)
I love the library, it has a nice minimal interface with full Chrome awesomeness but the whole build process is unfortunately quite painful…
January 28th, 2010 at 18:41
We ran into the same problems, and never resolved them. However you'll note that in visual studio the release builds work fine with a debug app since the API consists of C-like calls (const char *'s and integers rather than std::strings)
so feel free to link against the release builds. If you get any crashes cus of it let us know, but we've tested our very huge app against berkelium in Debug and Release, both linking against a Berkelium Release and it worked snappy
January 28th, 2010 at 18:53
Ah, good to know :) I never even thought about mixing debug and release since it's usually such a no-no. Thanks for the tip Daniel! :)
January 29th, 2010 at 10:11
Ugh, unfortunately it does not seem as easy as it first sounded. Simply linking to the release version of Berkelium in the ppmrender debug build doesn't work, it produces the same problem as before.
Exacly what settings do you have to successfully build and run ppmrender_d.exe linked against release Berkelium?
January 29th, 2010 at 10:20
The strange thing is that when I enable optimizations /O2 the build works (except that I can't obviously debug it anymore) and when optimizations are disabled ppmrender crashes. :(
February 1st, 2010 at 17:37
Replying to my own post: I think I've found the source of the problems with the ppmrender debug build:
The WindowImpl constructor in Berkelium
Like I explained the error gets traced into Window::create() which leads to the WindowImpl constructor, this code:
WindowImpl::WindowImpl(const Context*otherContext):
Window(otherContext),
mController(this, profile())
{
…
}
This I changed to:
WindowImpl::WindowImpl(const Context*otherContext)
{
mContext = (otherContext->clone());
mController = new NavigationController(this, profile()); // mController changed to a pointer
…
}
The compiler reports a warning from the first code snippet and for a reason: this is where it ultimately crashes. Now, changing mController from NavigationController to a pointer and then creating it with _new_ (did this because it was easier than changing the constructor code and/or creating a copy constructor) _inside the constructor body_ ultimately solved the crash problem.
I also built a wrapper to completely isolate the DLL to work on its own, loaded with LoadLibrary on demand with a pure virtual interface, not sure if that had something to do with the end result. However the isolated DLL crashed just like in my previous attempts until I found the culprit in WindowImpl and fixed it.
February 2nd, 2010 at 09:50
Wow thanks for debugging this–we'll investigate adding it to our git tree!
February 2nd, 2010 at 10:31
Thanks, I've pushed the fix to master. I'm worried that this was not the source of the crash (perhaps it was nondeterministic or related to the act of rebuilding), but nonetheless, using 'this' in an argument list is very shaky ground, since one small mistake in one of the dependent classes can cause a bug like this.
February 7th, 2010 at 08:45
I have been playing with it for the last couple of weeks and have been very impressed from Berkelium's stability over Awesomium which kept crashing for me every once in a while. The one issue I came across to date is the inability to correctly render pages from crackle.com. The flash video does not show while I do hear the audio. This does not happen when I run berkelium.exe, just the demo. Any idea?
February 9th, 2010 at 05:40
The reason is that we add a parameter called wmode="transparent" onto flash videos in order to tell them to render directly into the browser window, unless the website already set a wmode parameter.
Without wmode="transparent", the plugin doesn't render onto the browser's canvas and instead goes into a child window that in normal browsers gets positioned in exactly the right place. In our case, that isn't possible since the browser isn't necessarily on-screen. On Linux, we popup the plugin as a separate window–on Windows, this is taken care of by the renderer process, so the plugin just doesn't render (a hidden HWND).
It seems that crackle.com seems to explicitly specify wmode="window", which puts us in a hard position. Do we ignore the webmaster's explicit request to make the Flash plugin windowed, or do we not display the plugin?
We have a patch to chromium sources at patches/chromium_wmode_opaque.patch
The file it changes is "chrome/renderer/webplugin_delegate_proxy.cc" inside chromium/src. If you want to experiment, you could go to line 268 in that file, in the for loop, and add:
arg_values[i] = "transparent"
so as to always override the webmaster's default (I think "opaque" should work too.)
February 11th, 2010 at 20:32
Thanks. I would love to experiment but have not yet figured how to build Chromium on Windows. If by any chance you can somehow provide a binary with this patch, I would love to test it.
Thanks again for the detailed explanation!
February 11th, 2010 at 14:19
Thinking about trying to build Berkelium on a linux vps, but wondering how much disk space you need during the build? ONe comment on the sirikata wiki about building Awesomium says you need 10s of Gb to build Chrome?
February 11th, 2010 at 18:49
Neil – A fairly recent build on my computer shows about 3.4 GB used. Not sure where the 10s of GB figure is coming from, maybe from Windows or maybe we're not checking out and building everything in Chromium anymore (e.g. omitting tests).
One current caveat is that we aren't doing an install-style step on Chromium, so it just lives in the directory it was built in, meaning that currently none of the space is recovered after you're finished building.
February 11th, 2010 at 19:31
OK, well that isn't too bad so maybe I'll give it a go – thanks.
February 17th, 2010 at 06:00
Just came across a crash in berkelium.dll on the page http://www.nfl.com/videos/nfl-game-highlights/090… This happen consistently when playing the ad before the video (ad says "welcome to the now network, 3 skiers are…" then crash), when the ad does not come up and the actual video plays the crash does not occur so reproducing it might not be trivial. When running berkelium.exe as standalone app the crash does not occur either.
February 17th, 2010 at 15:44
Sorry that was a false alarm, please ignore.
February 18th, 2010 at 06:25
In fact it is crashing when injecting a click due to the fact that clicking on an ad pops up a window and when that happens berkelium crashes. I think I saw somewhere that this is a known issue. Is there any way to silently ignore these windows and avoid a crash?
February 19th, 2010 at 12:24
I had the same problem and it was pretty trivial to fix.
The place to look at is in WindowImpl.hpp and cpp. You'll notice there are two overloads of CreateNewWindow(…). The other is not really implemented (it's merely a {} in the header). That's the problem. Whenever a new window is created, 1. CreateNewWindow() is called and it is followed by 2. ShowCreatedWindow(). In this case what happens is that the CreateNewWindow() that hasn't been implemented, is being called before ShowCreatedWindow() and since the method did not create a new window ShowCreatedWindow() has no new window to work with, which is why it crashes. To solve this, simply copy the CreateNewWindow implementation to the unimplemented method.
I have no idea why the other CreateNewWindow() wasn't implemented in the first place. The funny thing is that the implemented one never even seems to get called.
February 25th, 2010 at 04:21
Thanks!
February 17th, 2010 at 06:00
Just came across a crash in berkelium.dll on the page http://www.nfl.com/videos/nfl-game-highlights/090… This happen consistently when playing the ad before the video (ad says "welcome to the now network, 3 skiers are…" then crash), when the ad does not come up and the actual video plays the crash does not occur so reproducing it might not be trivial. When running berkelium.exe as standalone app the crash does not occur either.
February 21st, 2010 at 19:54
[…] spent the past day or so hacking together a managed wrapper for Sirikata’s Berkelium library. Berkelium allows you to easily embed a WebKit-based browser into games and other applications. […]
March 25th, 2010 at 22:35
Have you encountered this error on Mac OS X before?
"LaunchApp: execvp(./berkelium) failed: Permission denied"
It has me very confused right now. Any ideas how to fix it? The crash occurs in the demo apps too.
(This is snow leopard)
June 1st, 2010 at 17:28
Tired compiling the glut demo using the win32 sdk (http://sirikatawin32.googlecode.com/svn/trunk/). I just get a black box.
September 2nd, 2010 at 11:11
Hi, I'm trying berkelium but I can't get it to call the onPaint event, this is what I'm doing:
class HtmlDelegate : public Berkelium::WindowDelegate {
void onPaint(Berkelium::Window *wini,
const unsigned char *bitmap_in, const Berkelium::Rect &bitmap_rect,
size_t num_copy_rects, const Berkelium::Rect *copy_rects,
int dx, int dy, const Berkelium::Rect &scroll_rect) {
cout << endl << endl << "——–PAINT————" << endl << endl << endl;
}
};
…
Berkelium::init(Berkelium::FileString::empty());
html_context = Berkelium::Context::create();
html_window = Berkelium::Window::create(html_context);
delete html_context;
html_window->resize(512, 512);
html_window->setDelegate( new HtmlDelegate() );
html_window->setTransparent(true);
html_window->focus();
std::string url = "http://www.google.com";
html_window->navigateTo(url.data(), url.length());
…
And then in my main loop I call:
Berkelium::update();
…every frame. Am I missing something, or is there any way to get more information of what's going on? I wasn't able to debug inside init().
October 19th, 2010 at 12:40
Err, are you sure you can delete the context? I'd remove the delete html_context line.
Also check the exact signature of onPaint. Add a virtual and compile with -Woverloaded-virtual
September 2nd, 2010 at 11:19
Nevermind, I realized what was going on. I hadn't copy berkelium.exe in my path. It isn't good that a library depends on an exe guys. So if a user goes to the task manager and terminates berkelium.exe my application gets crippled? Are you planning to re-architect this in a way that only a dll is required? The way it is now it's unusable for me. At least could you make it re-run berkelium.exe automatically if it's terminated. Well that wouldn't be good either, as state information would be lost. Please consider removing the exe.
September 2nd, 2010 at 11:36
Me again! Here's a compromise, how about letting us know if berkelium.exe gets terminated through ErrorDelegate, so that we can finish the host application and tell the user to never terminate that process again? Know that depending on an exe would still be hackish for a library but this would make it an acceptable temporary solution. You should still consider removing it on the long term.
Also, another simple thing to do would be to let us customize the name of the exe (maybe as a parameter to Berkelium::init()) without having to rebuild the SDK. That way we could easily rename "berkelium.exe" to the same name than our product. Say, if Starcraft used berkelium.exe, they could have named it "starcraftb.exe" and people would know that is related to the game and would not terminate the process.
Thanks for your attention!
September 2nd, 2010 at 12:55
The extra executable is the model Chromium uses to sandbox its browser windows/tabs, so that's not going to go away. If you run Chromium/Chrome, you'll notice a bunch of chromium-browser processes, many of which are –type=renderer.
It might be possible to disable the sandboxing and have it run the renderer in the same process, thus only requiring the dll. Otherwise, the callback to ErrorDelegate might be possible. I think allowing customizing the exe name wouldn't be too hard and should be able to accept parameters as well so you could use the same approach as Chromium where the renderer processes just take a special parameter. This would require you to include code similar to that used by the berkelium.exe executable.
Your best bet is to propose an approach on the dev list (http://groups.google.com/group/platformtalk/topics).
October 13th, 2010 at 07:08
First, Excellent work on this guys!
Did some testing with the transparency support and it looks like the rgb values are premultiplied with the alpha? Thus leaving the correct alpha in the alpha channel. Removing the blending by chrome should speed things up i think.
October 19th, 2010 at 12:41
There seem to be a bug when building under linux caused by the size of wchar_t being 4 whereas the code expects 2. I think building with -fshort-wchar should fix that.
November 16th, 2010 at 11:46
Hi there
This is a nice library – I wonder if someone can help solve a problem I have come across though.
I’m trying to use berkelium to embed the facebook authorisation web pages in a C++ application and I’m finding that if the user clicks on certain links in the sign in page the library calls on onCreateWindow without a prior call to onNavigateTo. I then have to deal with this new window by assigning a delegate and handling it too, when what I want to do is control which links are to produce popups and which aren’t before it gets to this stage.
My workaround is to call stop() on the new window in onStartLoading and delete the new window and then navigate to the same URL in the old window. Not nice!
Have I missed something somewhere or does this sound like a bug?
I’m using the OS X ore-built binaries dated 31st October.
KUTGW
July 28th, 2011 at 17:08
Source and unity3dpackage files, please………. by e-mail. edusystem@paran.com
July 28th, 2011 at 17:09
window64bit
October 6th, 2011 at 21:10
I have to ask though, what version of Chromium did you use with Berkelium? I'm asking because I just pulled the latest Chromium sources and compiled them, then tried to compile Berkelium but ran into a big bunch of errors. It seems that some things have changed in Chromium and compiling it with the latest version probably won't work – the interfaces have changed. For example, ViewHostMsg_PaintRect_Params is no longer defined (or has been renamed), digging into older SVN entries shows it being there in previous versions but in the newer ones it has disappeared, I think it's now ViewHostMsg_UpdateRect_Flags (the contents of the structs look the same).
So… if anyone is attempting to compile this with the latest Chromium, better not. You'll be wasting many hours like I did
Would be nice to know which version is the right one to use to be able to compile Berkelium cleanly.