Skip navigation

Tag Archives: webkit

Hey yall, in case you missed it, I’ve just put out a new demo and video for the upcoming release of Awesomium v1.0!

You can check it out at my new blog or find out more information at the new info page for Awesomium.

This will probably be my last post on this blog, so make sure to subscribe to my new one!

Advertisements

Get it while it’s hot over at the download page!

Here’s an overview of the major changes since v0.5:

  • Support for Flash plugins
  • Enhanced rendering performance on multi-core machines
  • Support for mouse-wheel input (WebView::injectMouseWheel)
  • The ability to grab the contents of the current page as plain text (WebView::getContentAsText)
  • Refactoring of callbacks to use WebViewListener instead

After much deliberation, hair-pulling, and running around my wee little room screaming at the debugger, I’ve managed to put together a decently stable (as in, it now crashes less often that it used to) build that supports Flash plugins– you can check it out of the SVN now as revision six.

I also spent a bit of time on optimization to take more advantage of multi-core processors. Previously, WebView::isDirty did a synchronous query of the internal WebViewProxy object on the core thread to test for dirtiness– I realized a better way to implement this was for the internal WebViewProxy object to directly update a local member of the WebView object on the main thread via a mutex so that calling the function doesn’t cause any blocking. Also, since the mutex would only be locked if the dirtiness state was being set to true (it’s only set to false during the synchronous WebView::render), if the mutex failed to be acquired instantly, WebView::isDirty immediately returns true.

Furthermore, I implemented a compromise to issue 3 and that is that WebView::isDirty now asynchronously flags the associated WebViewProxy on the core thread to begin layout/painting of the frame if it is dirty. This allows at least part of the rendering to take place on another thread concurrently with any blitting preparations that may take place on the main thread (such as the locking of a HardwarePixelBuffer in Ogre3D).

Testing shows that these additions have significantly improved the performance of several operations (such as scrolling, javascript/canvas animation, etc.)– I was seeing about a 20% improvement in the rendering speed of Google Maps.

Success!

Turns out my guess about what why the Flash plugins weren’t continuously rendering was right– I set up a repeating timer to intermittently do a Peek/Translate/Dispatch on the internal thread and suddenly everything was animating.

Mouse/keyboard input still was having issues and so I tried a lot of elaborate solutions to try and solve it– creating off-screen dummy windows, manually injecting window messages, etcetera. I eventually emulated Chrome’s existing input-handling routines for windowless plugins and got it working.

Windowed plugins still proved to be a major problem and I wrestled a lot with it over the period of a few days. It’s embarassing to admit that the final solution was really quite simple: when loading a plugin, I override the wmode parameter to force all Flash plugins to be loaded as windowless.

There were several other complex issues I had to contend with as well such as the throttling of certain messages, the timing of the peek/translate/dispatch cycle, and destruction order but I think the majority of the implementation is there. It’s still not entirely stable yet and so I’m not going to commit the new changes to the SVN just yet.

If you’re feeling curious, you can download a demo to test out the early Flash support. A few notes:

– Try to run it in windowed mode, you may need to close manually if Esc fails to work.

– F1: Print FPS to console

– F2: Navigate to Google

– F3: Toggle between forced-rendering and normal-rendering.

– Forced-rendering is useful for when the rendering freezes (it’s one of the bugs I’m working on)

I spent a bit more time working on Flash support– after fiddling around, I realized I could hook in a ‘WebPluginDelegate’ to handle the load of a plugin and duly wrap it however I want (foregoing any muckery with the NPAPI). After a few hours, I had Flash (almost) rendering! Er, well, only the first frame of any windowless (wmode=transparent) Flash movie:

As for why it stops at the first frame, it seems almost as if the plugin’s internal message loop isn’t being processed– I think it’s trying to post messages via the WinAPI but is being negated by the fact that I’m running it all in a seperate thread from the UI and am not passing any sort of HWND to the plugin. Oh well, it’s gonna take a bit more hacking to get this implemented. 😀

In an attempt to better organize discussion of Awesomium (replying to comments just isn’t cutting it), I’ve started a discussion group over at Google Groups. I normally would set up a big forum and wiki on my own webspace but users have been having trouble with e-mail confirmations (apparently my server resides in a blacklisted IP block).

Also, I’ve started using the issue tracker on the Google Code project page to coordinate and record issues/bugs/enhancements. If you spot a bug or simply want to make a suggestion about Awesomium, please feel free to add it to the issue tracker if it doesn’t already exist.

As for the future of Awesomium, there are several things I’m currently working on and hoping to get implemented. Support for true transparent backgrounds is one that tops my list as there is significant demand for such a feature. I haven’t had much luck getting this implemented natively and so I may end up altering the Chromium source– we’ll see how my hacking attempts go.

Another big thing I’ve been hearing requests for lately is support for Flash and other plugins. There’s several problems right now getting the Flash plugin to work: it requires a window handle (we have none), it renders directly to the window, and it isn’t painted with the WebView when invoking an offscreen paint. Nevertheless, I’ve got an idea: attempt to force the Flash plugin to always initialize in windowless mode (thereby it doesn’t require a window handle) and then intercept whenever it paints offscreen to its HDC (requires modification to Chromium). I’m still a noob at the NPAPI however and so to hone my skills, I’m currently working on creating a standalone plugin execution sandbox (so I can embed plugins like Flash without a browser).

The first official Awesomium SDK (v0.5) is out now for MSVC8! You can download it here.

The main header is “WebCore.h”, so include that to access the entirety of the API. Almost everything is documented using standard Javadoc commenting and so it should be pretty easy to understand (I’ll probably generate online docs later using Doxygen). If you need any tips on usage or an idea of how to embed Awesomium within your application, take a look at the ‘app’ project in the SVN source.

Good luck and have fun!

P.S., remember to copy over the ICU DLL (it’s in bin/common) into your executable’s directory as well. If you don’t, everything will probably still run however various operations (mostly text-input and unicode-related stuff) will most definitely fail, causing undefined behavior.

 

P.P.S., I’ve started a discussion group to discuss development/support of Awesomium, check it out here!

fancy awesomium logo

fancy awesomium logo

I’m very proud to announce the very first release of Awesomium!

Version: v0.5
License: LGPL
Platform: Windows & MSVC8 only (for now)
Demo: Download here *

* Try this alternative version if the demo instantly closes upon startup.

The source code is now online at its SVN repository. Please be aware that this release is really only for hardcore developers only– it lacks documentation and is a little tough gathering the necessary dependencies. Nevertheless, if you’re too impatient for an SDK release or just eager to start hacking at the source yourself, to build Awesomium you will need to first obtain Chromium and build it (I used a Sept. 6th revision so try to sync with that date). Then, check Awesomium out into the directory adjacent to your chromium distribution (the project assumes you’ve named your chromium folder “chromium”), open the solution, and compile the ‘Awesomium’ project. If you wish to build the demo (project ‘App’), you will need to have installed the Ogre3D SDK.

For the most part, this release is quite stable however I’m still working on a few issues, in no particular order: node memory leaks, support for transparent backgrounds, minor stall during a clipboard copy, and support for certain plugins.

I would write a much longer and more eloquent article detailing all of my thoughts about the current state and future plans of Awesomium but I’m frankly exhausted due to my pulling an all-nighter to get this release out. Anyways, I hope yall have fun trying out the demo and good luck to those who wish to try compiling it from source!

Okay, enough about the hurricane– let’s talk shop.

Last week, I was having some problems with keyboard input and random freezes during certain interactions. A little tracing found that a global timer was being instantiated and would greedily respawn itself during a single cycle of the browser’s message loop.

Me, in my brilliance (or rather, my unwillingness to spawn a separate thread), decided to kill the global timer every time we cycled through the message loop. This solved all of the hangs but it still didn’t fix keyboard input and caused some secondary problems (like utter failure of all Javascript timers).

It was then I realized that I couldn’t implement this thing correctly without dipping my toes into the deep, dark depths of multi-threaded programming. I needed to encapsulate the core and components of Awesomium within a separate thread, run a dedicated message loop within said thread, and handle inter-thread communication and synchronization.

It took me five days of banzai, headache-inducing coding to implement but I’m proud to declare that Awesomium is multi-threaded (and stable!). It was one of the most complex tasks I’ve ever achieved as a programmer but it’s so cool seeing both of my laptop’s cores work at the same time.

Despite the multi-threading, I still wasn’t able to get keyboard input working. I finally went code diving (about 2 hours of tracing) and realized that the problem was linked with some assertions about the unicode text encoding: as I had suspected earlier, ICU wasn’t being initialized correctly. Upon inspection of the ICU initialization source, it had seemed to be attempting to load a DLL that it had assumed would be in the working directory. I located the ICU DLL, copied it to my working directory and voila– keyboard input worked and the runtime text encoding assertions disappeared. Unfortunately, this means that my previous statement about the total dependency size was incorrect: the ICU DLL is about 8 MB and the Awesomium DLL (release) is about 7 MB, so together, that’s a total dependency size of about 15 MB. It’s not too bad I suppose– people who need the absolute tiniest dependency size can always gzip the DLL’s and load them at runtime.

But hooray! Almost everything critical now works and is pretty stable. Popup-widgets (such as drop-down combo-boxes) are now supported by compositing them with the main web-view texture. Event listeners are also implemented– you can currently receive notifications for the beginnings of navigations, title receptions, and finishing of loads. Dirty-rectangle optimization and querying for ‘dirty’ render state is implemented. The only other ‘big’ point left on my to-do list is support for Javascript evaluation/callbacks. Getting that working seems to be a little more tricky than I thought and so I may put it off for later.

Oh and yes, in true ninja style, I’ve written this latest post using Awesomium.

I pulled another late-night coding session and am happy to report that a majority of the functionality is finished:

  • Mouse input injection
  • Rendering to an arbitrary BGRA buffer
  • Callbacks for load events
  • Invalidation detection
  • Ability to load from URLs, local files, or HTML strings

After spending the past 10 hours testing Awesomium out within an Ogre3D context, I’m now even more confident that WebKit certainly trounces Mozilla Gecko in such a setting. For comparison:

Gecko:

  • Total size added to application: ~15 MB
  • Startup time: ~2 seconds

WebKit-Chromium-Awesomium:

  • Total size added to application: ~6.8 MB
  • Startup time: non-discernible, practically instant

Furthermore, the API is absolutely excellent (there’s so much great stuff, I don’t know what to expose!), it seems easier to port to other platforms, builds in much less time (by about an order of magnitude), and it just feels faster. I have yet to do any true performance benchmarks but I think I can predict the winner.

Anyways, I’ve still got some other things left that I want to finish up before the initial alpha release:

  • Keyboard input injection
  • Efficient rendering of invalidated areas (dirty-rectangling)
  • Javascript evaluation/binding

I’m shooting to get some code up in an SVN within the next two days, so stay tuned!