Recently I’ve been working on Calc and Impress tiled rendering, with some results now becoming visible:
Impress Tiled Rendering is now integrated into master — there are still some issues, i.e. foreground images are not shown yet (this is a bug that’s shared with calc tiled rendering), and it’s not yet possible to select between rendering only slides, only notes, or both (i.e. we currently default to whatever mode the document was last opened in). However in general it seems to work quite well:
Impress Tiled Rendering: Unfortunately no Image rendered
In fact very little work had to be done to get tiled rendering working here — the hardest part was figuring out what part of Impress to plug into: once I’d gotten my head around Impress’s architecture, connecting up the rendering was a matter of a few lines of code.
The calc work is somewhat more substantial, primarily due to the way that scaling for cell rendering works: calc calculates on-screen pixel based sizings in a number of steps using its own scaling methods, which can sum up to noticeable errors between expected and rendered content (which would result in discrepancies when later compositing tiles). This means that there is a significant amount of work needed in rewriting parts of the scaling: while the tiled rendering itself is beginning to look acceptable, the normal UI for Calc is now partly broken, primarily in that scrolling is rather glitchy (however this is being fixed bit by bit, and it is hoped will be mergeable in a useable state soon). This work is still staying on a branch for now — i.e. until it doesn’t break the usual way of using Calc.
Similarly to Impress, images in the foreground aren’t being rendered yet — this as far as I can tell is the same underlying issue, and is what I’m currently working on fixing.
Calc Tiled Rendering: charts work too!
In addition to the work on actual tiled rendering, there have been some further additions in the surrounding code and testing tools:
- “Zoom” Controls for the gtk tiled viewer. (Zooming is however quite slow as we’re repainting a huge tile…)
- A part selector for the gtk tiled viewer, i.e. permits switching between tabs in a spreadsheet, or slides in a presentation (writer documents are however rendered all as one huge block).
- Associated zoom and part selection methods for the LokDocView gtk+ widget.
- A quad-tiled widget for testing (nothing to do with real tile composition…): this allows for inspecting tile transitions/borders (and was useful for finding some more glaring issues in the calc implementation).
- Some automated tests that aren’t yet fully enabled due to some further bugs that have been uncovered (which would cause them to fail).
Easily integrating LibreOffice directly into any other application is now a step closer thanks to the new GTK+ lok_docview widget (currently only on the feature/gtkbmptiledviewer2 branch, API and naming liable to change, usual disclaimers, etc.).
It currently sports a very simple api, consisting of the following two methods:
GtkWidget* lok_docview_new (LibreOfficeKit* pOffice);
gboolean lok_docview_open_document (LOKDocView* pDocView,
The gtktiledviewer has been upgraded to use this widget, and looks much as it did before (although with some notable improvements, more below):
As mentioned above, there have been some further improvements to the tiled rendering in general:
- All document content is now rendered, we don’t have missing text/images outside of the top-left section anymore.
- Alpha channel is now set correctly in the tiled rendering output (less relevant for the widget where we could easily hide that, but useful for other uses of tiled rendering where additional manipulation of buffers can now be avoided).
I’m hoping to get started on tiled rendering support for calc next (currently only writer documents are supported). I’m also optimistic that we’ll be able to merge back onto master (allowing for more widespread experimentation) soon.
(For now we just dump one bitmap for the entire document within our widget — not hugely efficient, but simple and useable. Hopefully in the long run we’ll be able to move to having some form of proper tile compositing and also get rid of bitmap rendering — all of which can be hidden away within the widget implementation.)
This summer I’m going to be working on (hopefully) helping to add Tiled Rendering support to LibreOffice Calc and Impress.
As a first stage I’ve been experimenting with implementing a pure GTK+ tiled rendering app, to allow for active testing of tiled rendering work, i.e. using the existing tiled rendering in writer. (On desktop platforms we already do have a basic testing app, but that’s based on VCL — it shows a background window of the document in addition to wherever the tiled rendering happens.)
This application is being developed on the basis of LibreOfficeKit (formerly liblibreoffice) — i.e. avoiding the need to interact with LO internals — which is being extended with the (currently experimental only) necessary API calls to allow rendering to a bitmap buffer (in the longer run OpenGL would probably be most appropriate, but bitmap rendering is still quite useful for some applications. More importantly support for this already exists whereas OpenGL would require a chunk of extra work). Hopefully we’ll soon also have a simple GTK+ viewer widget to allow for simple reuse in other applications (meaning we can then change the internal implementation at will and upgrade to faster rendering as appropriate), perhaps modelled on the basis of the WebViewGtk widget.
The current tiled viewer looks somewhat like this (there are still problems with document rendering, i.e. portions are not rendered in our test document in odk/examples/java/DocumentHandling/test/test1.odt ):
And if you get the rowstride (and colourspaces) mixed up you can get some more interesting effects such as:
Recently some distros have started shipping Bluez 5 — this introduces a completely new DBus API, meaning that bluetooth support for Impress Remote was broken on such systems (openSuse and Fedora being the more notable distros now shipping Bluez 5, whereas e.g. Ubuntu still seems to be sticking with Bluez 4 for now).
LibreOffice has gained Bluez 5 support — this is now available in LO 4.1.6, and will also be included in 4.2.4 (to be released soon).
API Changes: Bluez 4 -> Bluez 5
There is not a huge amount of documentation explaining the changes between Bluez 4 and 5. Fortunately the new API turns out to be fairly clean, and overall is much simpler to use than what we had to do for Bluez 4. However in LibreOffice we restrict ourselves to the low-level dbus library (“If you use this low-level API directly, you’re signing up for some pain.“) which makes things a bit harder and hugely verbose (this is primarily for buildability on older systems and to avoid new dependencies — there is hardly enough dbus use to warrant a slew of new dependencies). (Python however seems to be a much more elegant language for dbus work, as is evidenced by the Bluez 5 unit tests.)
The key differences between the Bluez 4 and 5 DBus APIs that are likely to be of interest to those wanting to add Bluez 5 support to their applications can be found in a document on the bluez homepage, however it’s probably worth adding:
- In most cases you probably no longer need to retrieve any Bluetooth adapters, since Profile registration no longer happens via the devices (unless you want to fiddle with things like discoverability). This is good as the DefaultAdapter no longer exists, so to get hold of an adapter we need to retrieve all objects from the Bluez ObjectManger and filter that for adapters (a complete pain with the low-level library due to multiple levels of dicts which have to be traversed).
- Trying to portray ourselves as a “server” (via the properties passed in to ProfileManager1.RegisterProfile) prevented connections from reaching LibreOffice — this still needs some investigation on my part… (Overall, profile registration is much simpler than with Bluez 4 since we can now just pass in a UUID and not have to construct our own XML SDP record as before.)
- No need to detect Adapters appearing/disappearing (as happens on resume/suspend) in order to reregister profiles thanks to the ProfileManager doing this for us — much simpler main loop as a result.
- New connections are passed to us via the org.bluez.Profile1 callback object which we (the application) have to implement (which provides a socket, connected to the remote device, ready to use in any pre-existing network code you may have, i.e. you can jump straight into send/recv’ing) — however you need to make sure to provide an (empty) reply when you receive the NewConnection call, or Bluez will simply shut down your connection after some timeout.
It’s worth noting that there is also a direct C library for bluez which appears to be quite stable (and as far as I can tell would’ve been the simplest way to do our SDP registration in combination with manual socket management as before — however as I’ve never used it I may be completely misguided on this) — however it is GPL’d and hence not of much use for LibreOffice.
Unfortunately Bluez 5 doesn’t seem fully reliable yet, i.e. it can seemingly randomly (but fortunately rarely) break after a suspend/resume cycle (no obvious reproduction recipe known yet, I’m still to get round to debugging in detail). The kde bluetooth management tools in openSuse 13.1 are also a bit crash-prone (but that is known and mentioned in the release notes — the relevant libraries are still in active development). If you are after a more reliable experience it is probably best to stick with Bluez 4 for a while longer.
(Bluez 4 support in LibreOffice continues to exists without change.)
One of the major motivations for my GSOC project this summer was to get rid of the somewhat inefficient use of Java from C++. One immediate difference noticeable from early on when working on Firebird integration is the disappearance of a large pause when loading a database caused by startup of the jvm. (Unfortunately we still need Java for various wizards within Base which still need rewriting in C++/Python/etc. — for now this pause just happens at a different point in time.)
However the main speedup to be expected was in actual manipulation of data. Hence a insertion/retrieval test was developed — currently we only test the insertion and retrieval of 120’000 strings (a dump of the aspell dictionary), the results of which show a significant advantage for Firebird:
It should be noted that this test is not an accurate comparison of Firebird and HSQLDB in their native environments, this is only an accurate comparison of the two databases accessed via SDBC drivers, i.e. going via C++ — I suspect the slowness of HSQLDB is mostly due to the use of JNI and the C++/Java transition.
It would probably be interesting to add further tests to compare the performance when working with numeric types, however the performance boost of using firebird should already be clear. The tests and documentation can currently be found in dbaccess/qa/unit/emeddeddb_performancetests.cxx.
It’s now possible to select the driver to use for embedded databases within Base thanks to the new selector:
The default database remains HSQLDB, however this change allows easy creation of new firebird based .odb files (mainly for testing purposes at the moment), whereas previously manual extraction and editing of the .odb file was necessary to create such a file. This also means that in future, once the default database can be changed to Firebird, it will still be possible to create HSQLDB files for compatibility with older version of LO/OO/etc.
After spending some time trying to figure out why firebird didn’t like quoted identifiers I discovered that I had missed that the database supports multiple sql “dialects” (quoted identifiers are needed e.g. in ‘CREATE TABLE “aTableName”….’ — Base uses quoted identifiers everywhere in fact — previously quotation marks were replaced with spaces which was a somewhat ugly/wrong solution to the problem). These dialects are:
- 1: The original dialect for IB5.5 and earlier which doesn’t supported quote identifiers, the various sql date/time types etc.
- 3: The dialect for IB6 and newer which supports quoted identifiers, various sql date/time types etc.
Previously dialect 1 had been in use, and I had no clue that this was the issue. As part of the journey towards discovering this I did however manage to add support for passing usernames/password to firebird (although this is unused so far — remote db support still needs to be added, but only really involves parsing a connection string — embedded dbs are accessed without usernames and passwords), some of the database metadata definitions were also cleaned up/implemented.
In other news, the sdbc driver can now list the names of all the columns in a table except for the first column. It doesn’t seem to be an off-by-one error as the methods to get column names are all called and return data as expected — but it definitely is a bug somewhere in the driver.
Firebird has now been integrated into LibreOffice master!
It now builds on Mac and Windows in addition to Linux. (I’ve only tested on Linux but will be testing/fixing as necessary on Mac/Windows this week.)
The database driver itself is almost unusable at the moment as I’ve been refactoring various things to do with transaction control and execution of statements. More and more functionality should be appearing in the course of this week, making the driver more usable .
For now hsqldb will still be the default embedded db. To use firebird for embedded files you either have to set EmbeddedDatabases/DefaultEmbeddedDatabase/Value in the registry to “sdbc:embedded:firebird”; or create a new .odb file with base, edit the content.xml within and replace “sdbc:embedded:hsqldb” with “sdbc:embedded:firebird”, then reopen the .odb. At the moment the driver can only work with databases embedded in the .odb; support for external and/or remote databases however doesn’t look particularly complicated so should hopefully appear soon.
The embedded firebird driver can now create new .odb’s using firebird, and open and save existing files — when running the firebird db is stored in a temporary file, this is copied into the .odb file every time it is saved — and extracted as necessary on startup. The sdbc driver is still somewhat incomplete meaning that this isn’t particularly usable yet, however in principle LO can now use Firebird as it’s embedded Database. This means I can now work on the actual sdbc driver!
Currently it is only usable on Linux: Windows compiles but crashes — I’ll be setting up a debug build to run over the weekend meaning I should hopefully be able to debug at the beginning of next week. Mac is currently not buildable — it looks like fixing this shouldn’t be too difficult though, I’ve managed to obtain a mac which I’ll be setting up soon in order to work on this.
The sdbc driver won’t be exclusive to embedded firebird — it should eventually be able to also support external firebird database files, and even connect to remote firebird servers — this should be only a very small amount of work, mostly to do with the gui needed to set up a connection.
Things have been taking slighty longer than expected with the first stage of the Firebird integration project, I have however finally gotten Firebird building within LibreOffice both on Linux and Windows (Mac OS still to be tested).
Firebird (2.5) is officially only supported using MSVS 7 or 8 on Windows, however LibreOffice should support 10 (2010) or 11 (2011), hence I had to do some work patching Firebird to compile within the LibreOffice build system. This now works and LibreOffice build successfully — unfortunately the sdbc driver itself now crashes on Windows, which will need fixing.
I’m now starting to look at the SDBC driver itself (which Javier Fernandez and Andres Gomez of Igalia originally started writing) as well as looking at how to have the firebird db stored within the .odb file itself (the driver currently assumes a db in a temp. directory). Whereas HSQLDB writes directly to the .odb, for Firebird — at least initially — the database file will be stored externally and extracted from / written into the .odb file as appropriate. Ideally the driver would be able to deal both with having a completely separate db file, and having the db within the .odb — it looks like this should not be particularly difficult to implement.