Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Extensions can't draw without thebes symbols

2 views
Skip to first unread message

Alex Graveley

unread,
Jul 5, 2007, 6:48:35 PM7/5/07
to vlad...@pobox.com, bsme...@mozilla.org
Hi,

Picking up from this thread from last year: http://tinyurl.com/2oo2uo.

Without thebes symbols exported on static FF3 builds, binary
extensions wishing to draw directly will not work. This is a new
issue in FF2 since it allowed access the underlying toolkit drawable.

Without the symbols to manipulate e.g. a rendering context's thebes
object, the extension must try to access it's cairo context directly.
This can mean passing objects between the mozilla-internal cairo and
the system install or bundled version of cairo that the extension must
link-to instead. The two versions may have non-shared internal state,
or incompatible compiler flags, leading to trouble.

On my Linux system, at worst it brings the X server to it's knees with
unbounded alloc, and at best it just doesn't draw anything. I am
currently faced with supporting only shared builds of FF3, which is
sad.

My project is Linux-specific, and I suppose it could be argued that
trouble is more likely on Linux systems which have a cairo already
installed. I'd be happy if this was only fixed or Linux builds, but I
think the problem exists everywhere.

Even if there were no static data mismatches with multiple cairos in
the same process, and I build one to exactly match that of Mozilla's,
it would still tie the extension to specific release bincompat. So
why not just expose thebes?

-Alex

Benjamin Smedberg

unread,
Jul 9, 2007, 10:27:46 AM7/9/07
to
Alex Graveley wrote:

> Without thebes symbols exported on static FF3 builds, binary
> extensions wishing to draw directly will not work. This is a new
> issue in FF2 since it allowed access the underlying toolkit drawable.

Via what API?

In Firefox 2 cairo was statically linked into firefox.exe, so it was
inaccessible to extension authors (and thebes wasn't in use then).

The normal solution to "drawing arbitrary stuff on the screen" is a plugin.
Then you get a native drawable and you can use your own thebes/cairo without
worrying about any binary compatibility with the Mozilla versions. Is this
not an option for some reason?

> Even if there were no static data mismatches with multiple cairos in
> the same process, and I build one to exactly match that of Mozilla's,
> it would still tie the extension to specific release bincompat. So
> why not just expose thebes?

There are at least three issues here:

1) The thebes public headers [a] #include cairo headers and introduce
dependencies on cairo symbols. This is especially a problem on Linux when
you don't know whether you'll be in a system using system-cairo or
internal-cairo.

2) Thebes is a C++ API, which means you are inherently crippled in terms of
binary compatibility. This is epecially true because GCC has changed minor
aspects of their ABI over versions. This is one of the many reasons why we
are only freezing C symbols and only exporting frozen symbols from libxul.

3) Typically we don't make any changes to exposed APIs on a stable branch.
This would have the unfortunate effect of flash-freezing thebes when we
release 1.9, which I don't think is desirable. What if there are bugs which
require changing the thebes classes? Otherwise we'd have to say that the
thebes API could change at any time, which reduces the bincompat of your
extension anyway.

a:
gfxAtsuiFont.h calls cairo_set_scaled_font in an inline function
gfxPangoFonts.h #includes cairo.h but I'm not sure why
All the other usages seem to be safe (i.e. only struct pointers are used in
the headers, not any function references)

--BDS

Alex Graveley

unread,
Jul 10, 2007, 4:11:35 PM7/10/07
to
Yo,

On Jul 9, 7:27 am, Benjamin Smedberg <benja...@smedbergs.us> wrote:
> Alex Graveley wrote:
> > Without thebes symbols exported on static FF3 builds, binary
> > extensions wishing to draw directly will not work. This is a new
> > issue in FF2 since it allowed access the underlying toolkit drawable.
>
> Via what API?

By retrieving the native gdkdrawable for an nsIRenderingContext and
either drawing on it using gdk, or creating a system-cairo context for
it's X drawable, and rendering to that.

> In Firefox 2 cairo was statically linked into firefox.exe, so it was
> inaccessible to extension authors (and thebes wasn't in use then).
>
> The normal solution to "drawing arbitrary stuff on the screen" is a plugin.
> Then you get a native drawable and you can use your own thebes/cairo without
> worrying about any binary compatibility with the Mozilla versions. Is this
> not an option for some reason?

In my case I am implementing a <canvas> backend, so a plugin is not an
option. This same issue effects the 3dcanvas extension, which is also
currently broken for the same reason.

> > Even if there were no static data mismatches with multiple cairos in
> > the same process, and I build one to exactly match that of Mozilla's,
> > it would still tie the extension to specific release bincompat. So
> > why not just expose thebes?
>
> There are at least three issues here:
>
> 1) The thebes public headers [a] #include cairo headers and introduce
> dependencies on cairo symbols. This is especially a problem on Linux when
> you don't know whether you'll be in a system using system-cairo or
> internal-cairo.

Any instances of cairo poking through seem like bugs to me. (a) is a
pretty small set, which would seem to back this up.

> 2) Thebes is a C++ API, which means you are inherently crippled in terms of
> binary compatibility. This is epecially true because GCC has changed minor
> aspects of their ABI over versions. This is one of the many reasons why we
> are only freezing C symbols and only exporting frozen symbols from libxul.
>
> 3) Typically we don't make any changes to exposed APIs on a stable branch.
> This would have the unfortunate effect of flash-freezing thebes when we
> release 1.9, which I don't think is desirable. What if there are bugs which
> require changing the thebes classes? Otherwise we'd have to say that the
> thebes API could change at any time, which reduces the bincompat of your
> extension anyway.

These are both bad, but I see no alternatives proposed. The lack of a
clear solution is actively hurting code in the tree, and arbitrarily
limiting that extensions cannot implement <canvas> backends, which
seems sad as it's a pretty big win for moz extensibility.

-Alex

Vladimir Vukicevic

unread,
Jul 10, 2007, 4:16:15 PM7/10/07
to
On Jul 9, 4:27 pm, Benjamin Smedberg <benja...@smedbergs.us> wrote:
> Alex Graveley wrote:
> > Without thebes symbols exported on static FF3 builds, binary
> > extensions wishing to draw directly will not work. This is a new
> > issue in FF2 since it allowed access the underlying toolkit drawable.
>
> Via what API?
>
> In Firefox 2 cairo was statically linked into firefox.exe, so it was
> inaccessible to extension authors (and thebes wasn't in use then).
>
> The normal solution to "drawing arbitrary stuff on the screen" is a plugin.
> Then you get a native drawable and you can use your own thebes/cairo without
> worrying about any binary compatibility with the Mozilla versions. Is this
> not an option for some reason?
>
> > Even if there were no static data mismatches with multiple cairos in
> > the same process, and I build one to exactly match that of Mozilla's,
> > it would still tie the extension to specific release bincompat. So
> > why not just expose thebes?
>
> There are at least three issues here:
>
> 1) The thebes public headers [a] #include cairo headers and introduce
> dependencies on cairo symbols. This is especially a problem on Linux when
> you don't know whether you'll be in a system using system-cairo or
> internal-cairo.

These are bugs that are easily fixed; Stuart went through and removed
all (or almost all) of these cases a little while back.

> 2) Thebes is a C++ API, which means you are inherently crippled in terms of
> binary compatibility. This is epecially true because GCC has changed minor
> aspects of their ABI over versions. This is one of the many reasons why we
> are only freezing C symbols and only exporting frozen symbols from libxul.

Sure; Thebes would not be a frozen API, and no compatability would be
guaranteed or would be allowed to be presumed. We could even
arbitrarily break compat in some way with every minor release (make a
random hex value #define that you have to pass to some initializer
function that changes in every dot release? something.). For many
(most, even) use cases, this is totally acceptable.

> 3) Typically we don't make any changes to exposed APIs on a stable branch.
> This would have the unfortunate effect of flash-freezing thebes when we
> release 1.9, which I don't think is desirable. What if there are bugs which
> require changing the thebes classes? Otherwise we'd have to say that the
> thebes API could change at any time, which reduces the bincompat of your
> extension anyway.

See above; Thebes would not be a frozen API, and it could change at
any time. The bincompat of the extension would be for the exact
release it was compiled for, and nothing more. I realize that in the
past this has caused us to have to support non-frozen symbols that
others depended on, but that's a policy issue, that was compounded in
the past by long release cycles.

There is no reason that Thebes shouldn't be exported, other than
"people might depend on it and then their code will break". I think
that's fine -- if anything, require a #define
MOZ_THEBES_PRIVATE_API_DEPENDENCY or something for anyone building
with thebes to reinforce that notion whenever anyone writes such
code. There are many advantages; letting people prototype and
experiment via binary extensions hurts noone.

- Vlad

Vladimir Vukicevic

unread,
Jul 10, 2007, 4:22:54 PM7/10/07
to
On Jul 6, 12:48 am, Alex Graveley <alexgrave...@gmail.com> wrote:
> Hi,
>
> Picking up from this thread from last year:http://tinyurl.com/2oo2uo.
>
> Without thebes symbols exported on static FF3 builds, binary
> extensions wishing to draw directly will not work. This is a new
> issue in FF2 since it allowed access the underlying toolkit drawable.
>
> Without the symbols to manipulate e.g. a rendering context's thebes
> object, the extension must try to access it's cairo context directly.
> This can mean passing objects between the mozilla-internal cairo and
> the system install or bundled version of cairo that the extension must
> link-to instead. The two versions may have non-shared internal state,
> or incompatible compiler flags, leading to trouble.

Just to clarify -- we're talking specifically about a canvas context
implementation and the implementation of that interface, which
includes a Render method that is given a gfxContext. There is no
general functionality for "extensions wishing to draw directly"; as
bsmedberg said, that's the general domain of plugins. The rendering
context bit is somewhat of a loophole, and isn't a general purpose
mechanism; though it is useful for experimentation and prototyping.

- Vlad

Benjamin Smedberg

unread,
Jul 12, 2007, 9:05:56 PM7/12/07
to Mike Connor
Vladimir Vukicevic wrote:

> There is no reason that Thebes shouldn't be exported, other than
> "people might depend on it and then their code will break". I think
> that's fine -- if anything, require a #define
> MOZ_THEBES_PRIVATE_API_DEPENDENCY or something for anyone building
> with thebes to reinforce that notion whenever anyone writes such
> code. There are many advantages; letting people prototype and
> experiment via binary extensions hurts noone.

It is not so much that "their code will break" but that users will be
confused and upset that Firefox is breaking their extensions. Assuming that
we want these prototypes to get any adoption at all, when we release a
security update, Firefox gets blamed for "breaking" their extension. Or
worse, users turn off automatic update.

If we want extensibility, we should design a stable (even just for a single
branch) API and promote it. We should not be exporting inherently unstable
APIs: if extensions use the API, we would as a matter of policy have to
discourage users from installing them and disallow those extension from AMO.

If you're proposing that we expose the API just for developer
experimentation, what is wrong with doing that experimentation with
self-built or dynamic builds?

--BDS

Alex Graveley

unread,
Jul 15, 2007, 4:53:37 PM7/15/07
to
Hi,

It seems preferable to me to have users annoyed that an extension
doesn't work for some finite amount following a version upgrade, than
to incense extension hackers by severely limiting what they can
productize using a released build.

A few other options for consideration:
1) Create simple COM wrappers for whatever parts of libthebes you
decide it's safe to export. Native gfxContexts would be treated as
opaque pointers by extensions and passed to the COM wrapper's
constructor. Internal code would just call methods directly. This
allows you to save any vtable overhead internally, and strictly define
the public parts of thebes.

2) Allow an extension bundled libthebes to play nicely with the
internal one. You could export a single GetThebesVersion call, that a
bundled thebes would use to decide version compat, and fail requests
accordingly.

3) Apply this patch:

--- public/gfxTypes.h 14 Oct 2006 04:46:03 -0000 1.10
+++ public/gfxTypes.h 15 Jul 2007 20:52:34 -0000
@@ -48,5 +48,3 @@
-#if defined(MOZ_ENABLE_LIBXUL) || defined(MOZ_STATIC_BUILD)
-# define THEBES_API
-#elif defined(IMPL_THEBES)
+#if defined(IMPL_THEBES)
# define THEBES_API NS_EXPORT

Why being the first browser with basic scriptable 3D-support isn't
higher on the FF3 feature list, given solution (3), I have no idea.</
rant>

-Alex

bre...@mozilla.org

unread,
Jul 18, 2007, 5:22:06 PM7/18/07
to
I ruled in favor of Stuart in https://bugzilla.mozilla.org/show_bug.cgi?id=388663.

API design requires a lot of experience, along with some skills in
several sub-disciplines (both domain specific per API and related to
languages, toolchains or OS issues, and the like). I don't mean to
make light of good API design. But I'm presuming goodness in Thebes,
and stipulating that we do an API review of it before 1.9 betas so we
can be sure it's as good as other APIs we've managed to support
without XPCOM.

I'm also willing to say that if the GNU toolchain or Linux distros'
versions of it continues to thrash the C++ ABI, then too bad. Linux
will die even faster if the ABI isn't as stable and expressive as
Microsoft's C++ ABI (things like hiding symbols by default, sane/fast
calling conventions, etc.). Ultimately, I don't want this tail wagging
the dog of better APIs that can be C++ (i.e., without forcing C or
XPCOM).

Fundamentally, I think we've erred in trying to cathedralize API
design in this sense: we froze slowly and without many users actually
beating on the APIs that were frozen. And of course we exported
unfrozen APIs, because otherwise you couldn't even make an embedded
Eclipse browser, or a Camino, or whatever.

(As an aside, I think we organized our APIs using a superficially
bazaar-like approach, which put public/*.h or idl/*.idl all over the
source tree -- that was my mistake as much as anyone's, and I don't
think it was helpful to have so many would-be cooks. But the actual
freezing and embedding work was done by far fewer hackers than those
who plunked down .h files originally, or .idl files later, in public-
seeming directories, and exported them to dist/*.)

If we have the right API hackers and focus (e.g., Thebes for canvas
extensions as a starting experiment), we should be able to get more
users giving us feedback, and more usefulness from our APIs, than if
we silo our work too much.

If we fail, then at least we tried; and how is keeping our would-have-
failed APIs locked up and unexported necessarily better? It could be
better in many cases where there's no overt need for a public API, but
here's a case where customers are calling. So let's try it with Thebes
and see how it goes.

The issue of standard embedding APIs is a bit separate from this whole
thread. For Mozilla 2, we're open to emulating the preferred OS APIs
(e.g., MSHTML's on Windows), but we haven't committed. Anyone
interested should read and contribute to http://wiki.mozilla.org/Mozilla_2#Embedding_API_Design.

/be

0 new messages