Anti-grain 2D graphics library

Status
Not open for further replies.

Projectitis

Well-known member
Hi all,

I came across the anti-grain 2D graphics library this morning. It seemed really promising for high quality rendering on T_3.5/T_3.6 (high memory requirement because of the frame buffer). The reading seems good (and looooong) - It's supposed to be fast, though that's not "optimized for chipset" fast (which would be my next job), but capable of awesome stuff such as sub-pixel accuracy, thick lines (with different capping), filled polygons etc.

Anyway, to cut a long story short I made a couple of minor tweaks to get it to compile using Arduino IDE, and then implemented a very basic example that did nothing except create an instance of a couple of low level objects required for using the library (a rendering buffer and a pixel format). It does nothing else (i.e. no drawing, no outputting to a display).

Already my program uses 137544 bytes of global variables. Eek! that's more than half (52%) of dynamic memory for global variables associated with the parts of the library I've loaded (which is very little). Because a 32x240 frame buffer is around 154k it just wouldn't work.

I'm pretty sure this is mostly LUT for things like SQRT and so forth, which T_ could use DSP for instead of LUT, and others could be moved to flash.

Probably going to spend a couple of hours and investigate the global variables and see which I could ditch before I make a decision on going forward with this library - I'm sure many of the global vars would be unused in a minimal T_ implementation and others could be moved out of dynamic mem.

One question - is there a way I can get Arduino IDE/compiler to spit out a list of all global vars and how much memory they use? That would help immensely.

Cheers,
Peter
 
Last edited:
I've found where the global variables are being introduced. When I #include "agg_color_rgba.h" the dynamic memory usage jumps dramatically. I'm pretty sure it is allocating memory for a gamma LUT somewhere, but I can't find where!

Here is a minimal sketch to illustrate:
Code:
#include "agg_color_rgba.h"

void setup() {}

void loop() {}

Inside agg_color_rgba.h there are several other includes, including #include "agg_gamma_lut.h". However, if I just include agg_gamma_lut.h in my sketch, the dynamic memory allocation is minimal.

I've been looking through agg_color_rgba.h for the past hour I just cannot find where the global variable (assuming one or more LUT) is being allocated/defined!

If someone with better c++ knowledge than myself is able to check this out, I would be very much appreciated. Relevant source files attached.
 
For anyone following this up at some later date, I found the culprit.
The library has some gamma converters from RGB to sRGB color space that involve a couple of big LUTs - two at 65535 in length infact, and a couple more at 256*2.
These are in the file agg_gamma_lut.h as below:
Code:
    // Common base class for sRGB_conv objects. Defines an internal 
    // sRGB_lut object so that users don't have to.
    template<class T>
    class sRGB_conv_base
    {
    public:
        static T rgb_from_sRGB(int8u x)
        {
            return x; //lut.dir(x);
        }

        static int8u rgb_to_sRGB(T x)
        {
            return x; //lut.inv(x);
        }

    private:
        //static sRGB_lut<T> lut;
    };

	/*
    // Definition of sRGB_conv_base::lut. Due to the fact that this a template, 
    // we don't need to place the definition in a cpp file. Hurrah.
    template<class T>
    sRGB_lut<T> sRGB_conv_base<T>::lut;
	*/

At this stage I'm not planning on converting between colorspaces so I've commented out the LUTs and fudged the rgb_from_sRGB and rgb_to_sRGB methods. If I do end up implementing them I'll have to calculate instead of looking up the values.

However, because I'm not creating an instance of the sRGB_conv_base class anywhere (that I can tell) I still have no idea of why this has resulted in all the dynamic memory use... I guess I don't understand template classes/functions enough yet. Unfortunately the author of anti-grain died a couple of years ago, so he can't be asked either! :(
 
I haven't been successful at getting AGG working properly on Teensy yet. Unfortunately the author passed away before he could finish the documentation! The problem for me is that although AGG supports 565 color, the demos don't use it by default and I'm having a hell of a time figuring out which parts to change to support 565. According to the authors notes it is "possible" and "easy" to use regular RGB input color, and configure the output to 565 for displays like ILI9341.

Anyway, I've parked that for now and been working on my own primitives renderers.

So far I have an anti-aliased and blended line drawing method based on Wu's algorithm running at ~12,000 lines per second with sub-pixel accuracy (i.e. coordinates are floats and can be partial pixels).
Kurt's _t3n does aliased (jaggy) lines using Bresenham (as per _t3 library) to the framebuffer at ~26,500 per second, so I'm pretty happy with that trade-off (about 1/3 the speed, but gain alpha-blending and accuracy).

I'm currently working on a triangle rasteriser, which will lead to thick lines and then more complex polys.
 
agg-teensy.jpg

I know it might not look like much, but it's the start of AGG running on Teensy. So excited right now!
I'm running it here on T3.6 with ILI9341 at 4x pixel scaling (for a smaller framebuffer). Just a static image right now, but watch this space :)
 
Status
Not open for further replies.
Back
Top