Jul 172007
 

The idea of using OpenGL as a future core rendering architecture for Gtk+ has been brought up a couple times at GUADEC (and then some variations thereof). However there are good reasons to avoid that and major issues with the suggested approaches, in particular these need to be considered:

1) A dependency on OpenGL for a library as portable and as widely used as Gtk+ these days, could only ever be a weak one. That is, OpenGL features may or may not be used, depending on whether the current platform a Gtk+ application runs on actually has OpenGL available or not (e.g. by animating widgets conditionally to only be carried out when acceleration support is present).

2) The OpenGL 2D drawing API is effectively unusable for Gdk/Gtk+ drawing primitives. The main problem here is that OpenGL doesn’t provide pixel-perfect 2D drawing operations which are necessary for accurate input event processing and a coherent visual presentation (it also doesn’t always provide anti-aliasing in the 2D drawing API either). Here is a very good web page with nice screenshots summarizing the problems with OpenGL pixel-perfectness: OpenGL: “not pixel exact”, Hardware AntiAliasing.

3) By using XRENDER and hardware-accelerated X drivers, Cairo is already being performance optimized to utilize hardware acceleration. Trying to use a portable OpenGL subset instead (pixel shaders / triangle rendering) would be fairly pointless, it’d effectively be using the available portable hardware acceleration facilities through another indirection. So with more and more Gtk+-based platforms/applications moving to Cairo-based drawing, there is no additional infrastructure or support code needed to make use of available hardware acceleration facilities. Essentially, the portably usable hardware acceleration subset is brought to you automatically through Cairo and X.

For the lazy, here’s a quick overview of the artifacts presented on the OpenGL comparison page:

.

 Posted by at 20:22  Tagged with:
Jul 142007
 

For Rapicorn i need a simple and nicely readable way to special case code on various strings, which isn’t a problem in most scripting languages but is not provided by C/C++. Switching on strings turns out to be a widely investigated topic: SOS (agay), TheScript, JavaBug (CNFW), CodeGuru, CLC-FAQ and google has lots more.

Now here goes my approach to switching on strings for C/C++, caveats upfront:
- The strings may only consist of identifier chars: [A-Za-z_0-9];
- Convenient application is based on a GNU Preprocessor feature: -imacros;
- Macro implementations use a GCC-ism: Statement Expressions;
- The convenient command line variant uses a bash-ism: Process Substitution;
- One compile-time script is needed, currently implemented in python (though it could be written in any language).

With this out of the way, let’s dive into the code. This is the syntax:

	switch (SOSID_LOOKUP (sample_string))
          {
          case SOSID (hello): printf ("Hello ");   break;
          case SOSID (world): printf ("World! ");  break;
          case 0: default:    printf ("unknown "); break;
          }

This is how the code needs to be compiled: gcc -Wall -O2 -imacros <(sosid.py <input.c) input.c

The actual implementation is fairly simple, sosid.py extracts all identifiers from SOSID() statements and generates a handful of macro definitions: SOSID(), SOSID_LOOKUP(), SOSID_LOOKUP_ICASE(), ... Plus input specific macros: SOSID__hello, SOSID__world, ... GCC will pick up those definitions via the -imacros option. That is enough to implement SOSID_LOOKUP() so that it can yield the integer IDs that the SOSID(*)/SOSID__* statements expand to for any string that corresponds to one of the SOSID(identifiers) occurring in the source file.

Example:
call_switch ("hello"); call_switch ("foo0815"); call_switch ("world");
Yields:
Hello unkown World!

The lookups are implemented via a binary search and the strings are sorted in a way so that binary searches for case sensitive and case insensitive lookups are both possible. That means for large string lists, the lookups which are of complexity O(ld N) actually have a performance advantage over lengthy if..else if..else constructs with O(N) complexity.
The code is available as a single script at the moment: sosid.py.

Note that the bash-ism, imacros-use and GCC-isms are not mandatory, ordinary temporary files can be generated by the script and be included instead and it could be adapted to generate portable inline functions. The identifier-chars restriction is a hard one though. It comes from the fact that SOSID(ident) must yield valid C/C++ integers, and that can only be accomplished by token pasting. Depending on GCC is good enough for Rapicorn, so people will have to express active interest in this, in order for me to make the script more portable.

 Posted by at 11:46  Tagged with: ,