Table of Contents
List of Tables
Bugle is an toolkit for debugging and profiling OpenGL applications running on UNIX-like systems. It consists of two parts: a collection of filter-sets that observe and sometimes modify calls to the OpenGL API, and a graphical debugger that helps in examining state, setting breakpoints, and capturing errors.
Bugle is still in active development, and is considered
“alpha”. What this means is that while there are a lot of
features, any given one of them might be broken on any given day. If
you do find a bug, please let me know
(<bmerry@users.sourceforge.net>
).
To get started with bugle, first read the installation instructions, and refer to the FAQ if you run into any problems. If you just want to use the debugger, you can skip straight to its manual page. Otherwise, start with the overview manual page for bugle to learn how to use it, then find the filter-sets you want in the reference manual.
Table of Contents
Bugle is intended to work on any POSIX-compliant operating system
that use the X Windowing System, dynamic linking, and
LD_PRELOAD
for library interposition. If it fails
to work on such an operating system, please let me know (I only
use it on GNU/Linux). It is also supported on Windows, although
this support is less complete. It also includes highly
experimental and incomplete support for OpenGL ES 2 on Windows.
The following packages are required to compile bugle:
The following packages are not required, but if present, will enable extra functionality:
This will enable line editing in the console debugger. The GUI debugger is the preferred method of debugging.
This is needed for the GUI debugger.
This is needed for the texture and framebuffer viewers in the GUI debugger.
GLEW is also needed for texture and framebuffer viewers.
If FFmpeg is available, the included libavcodec
is used
for video capture.
Bugle uses the standard configure command for
compile-time configuration. Generic instructions may be found in
INSTALL
in the root of the source directory.
In general, configure will auto-detect optional
packages and use them only if present, but you can also prevent it
from depending on certain packages with the following flags.
FFmpeg (lavc) in particular is a moving target and if you get
compilation failures, you should try disabling it.
--without-lavc
--without-readline
--without-gtk
--without-gtkglext
Bugle does not use threads itself, but applications that it
debugs might, and bugle needs to use appropriate locking and
thread-local storage libraries. The correct option should be
auto-detected, but you can force it with
--enable-threads
=model
.
Valid models are posix
and
win32
.
Finally, bugle intercepts events from X11 and Windows. While
there are no known cases of this causing problems, it is difficult
to make the interception completely transparent, and so the
--disable-input
option is available to disable it
at compile time. It is also required when using EGL on a platform
other than X11 or Windows.
If possible, the best way to do cross-compilation is to use scratchbox, where it should all work seamlessly. However, scratchbox only supports a limited set of cross-compilation targets. If you want to do cross-compilation, you will need to jump through some extra hoops.
First, run configure in the top-level
directory, passing the appropriate --host
option for your cross-compiler. Also make sure that the
appropriate header files and libraries for the
cross-compilation target are available. You might also need to
pass extra options to configure to disable
optional features that are incorrectly detected (see above).
Next, change into the budgie
subdirectory and run
the configure script there (if you are configuring in a
different directory from the source, you will need to be in
the budgie
subdirectory
of the build directory, running the
configure script from the budgie
subdirectory of the
source. When doing this, configure for your
native compiler. This is necessary
because the program that is built in this directory is run on
the build machine to produce source code, not on the host.
Compilation is as simple as running make
.
Before installing, you should remove any previous installation of
bugle to avoid leaving old versions of files around. If you do not
have your original installation tree to run make
uninstall
, you should at least remove the files in
and
/usr/local/lib/
bugle
.
To install the new version, run /usr/local/lib/
libbugle*make
install
as root
.
Next, you need to install some files for the user that will run
bugle. Create a directory $HOME/.bugle
, and copy
doc/examples/filters
and
doc/examples/statistics
into it.
Installing from source on Windows is supported, but it is significantly trickier than on UNIX-like systems, and currently only recommended for experts. The intended target is MinGW; you can try using Cygwin as well, but it is not tested.
Here is the list of steps I used to install on Windows, including support for the debugger. The versions numbers were the latest available at the time, but newer versions should work too.
Install MinGW 5.1.4, including GCC and G++, but not make.
Install MSYS 1.0.10.
Install msysDTK 1.0.1.
Alternatively, if you have Cygwin installed, add Cygwin's
bin
directory to
the end of PATH
.
Downloaded
mingw-libgnurx-2.5.1-bin.tar.gz
and
mingw-libgnurx-2.5.1-dev.tar.gz
from
the MinGW page, and unpacked
both into /mingw
(i.e., the directory in which
MinGW is installed).
Download the GTK+ bundle
(2.12.11) from gtk.org,
and unpack it into /mingw
.
Get the gtkglext installer from
http://www.bonifazi.eu/appunti/, and
install it into /mingw
.
Download the source for GLEW
1.5 and unpack it into a temporary location and built it
using make, then install it with the command
make GLEW_DEST=/mingw install
.
Grab the latest glext.h
and
wglext.h
headers, and put them in
/mingw/include/GL
.
After installation, you will have a
opengl32.dll
file installed. When debugging a
program, you need to place this on the path ahead of the real one.
This can be achieved by copying it to the same directory as the
program you intend to debug.
Table of Contents
bugle has partial support for OpenGL ES. The OpenGL ES 2.0 support has been tested using the AMD OpenGL ES Emulator 1.3, and OpenGL ES 1.1 support has been tested on a hardware platform. OpenGL ES 1.0 support has not been tested and is probably broken. For OpenGL ES 1.x, only the Common (CM) profile is supported.
The testing shows that basic features work. These include tracing, and the debugger using breakpoints, examining state, and examining shaders. Texture and buffer viewing does not currently work (due to limitations of the query mechanisms in OpenGL ES). Many of the filtersets do not work, either because they intrinsicly depend on features excluded from OpenGL ES, or because they have not yet been ported. The test suite is not supported.
It should be noted that when using an emulator that works on top of OpenGL, an alternative approach to debugging is to use bugle as a regular (desktop) OpenGL debugger. This will reveal data such as textures and framebuffers. However, it cannot access the error checking that is done in the emulation layer. For example, an INVALID_ENUM error will not be caught by the debugger if it is generated entirely within the emulation layer.
Support on top of X11 rather than Windows is theoretically present and compiles, but has not been tested. Feedback from anyone with a working OpenGL ES implementation on an X11 system is welcomed.
Configuration can be done largely as described in Section 2.2, “Configuring”. To indicate that OpenGL ES is
desired,
--with-target=
must be passed to configure, where
config
config
is one of the values below:
OpenGL ES 1.x Common profile with EGL on a UNIX-like operating system (only tested with GNU/Linux).
OpenGL ES 1.x Common profile with EGL on a Windows
system. This is set up for the legacy integration
guidelines, with a single library
(libGLES_CM.so
) containing both
EGL and OpenGL ES functions, and using the
__cdecl
calling convention.
OpenGL ES 2.x with EGL on a UNIX-like operating system (untested).
OpenGL ES 2.x with EGL on Windows
Desktop OpenGL header files and libraries are still required for the GUI debugger.
Currently OpenGL ES 1.x on Windows is not supported, but this can easily be added.
You also need to ensure that your various paths are set correctly.
The headers, libraries and DLLs for the OpenGL ES implementation
need to be listed in CPATH
,
LIBRARY_PATH
and PATH
respectively,
unless the compiler is already configured to find them.
Apart from the usual installation step, some extra setup is
required on a Windows system when using OpenGL ES 2.0, due to the
limitations of the dynamic linker. Create copies of the system
libEGL.dll
and
libGLESv2.dll
called
bglEGL.dll
and
bglGLESv2.dll
respectively. Then modify each
of these
files so that links to the other use the replacement name. This
can be done as follows, although you might find that the version
of sed provided with MSYS is too old:
$
sed -b 's/libGLESv2/bglGLESv2/g' libEGL.dll > bglEGL.dll
$
sed -b 's/libEGL/bglEGL/g' libGLESv2.dll > bglGLESv2.dll
You should check that the new files are exactly the same size as
the originals. Next, make sure that the versions of
libEGL.dll
and
libGLESv2.dll
installed by bugle are the
first on the path, and that the renamed libraries you generated
are also on the path.
Table of Contents
This chapter is aimed at developers who wish to implement new filter-sets for bugle. Bugle uses a module system to make this relatively easy to do without making intrusive changes to the base system.
It is also worth reading for anyone interested in hacking on the bugle core.
The API has been designed so that filter-sets can be maintained separately from bugle, even if the filter-set depends on OpenGL extensions that were not available at the time bugle was compiled. It has also been designed so that installing a newer (or older) version of bugle will not necessarily break separately installed filter-sets purely because the set of OpenGL headers has changed.
The API is still changing regularly and there is room for optimisation, so upgrades to bugle may break the API or ABI.
This section contains stylistic guidelines and best practices. You should follow them if you hope to get your filter-sets included in the bugle source code, or want them to be generally useful to other users.
Indenting is four spaces.
Use spaces not tabs.
Both opening and closing braces go on their own line.
Function return types go on the same line as the rest of the prototype.
Filter-sets, and any other code that will be
preloaded into a user program, should link against as
few libraries as possible, since if the user program
uses a different version there will be conflicts. As a
result, C++ code cannot be used if it links against
libstdc++
.
Functions that act on
type
should be named
.
See below for when to prefix the name with
type
, _action
bugle_
.
Names of types should generally not have a
bugle_
prefix, unless it is needed
to clearly disambiguate it. This is an area where
consistency could be improved.
Functions in the core code should have a
bugle_
prefix if and only if they
are meant to be called from filter-sets or from the
debugger. Such functions are generally safe for
filter-sets to use unless marked otherwise.
A constructor for a type that returns a
malloc
ed instance should be named
,
whereas a constructor that modifies existing memory is
called
type
_new
.
The corresponding destructors are
type
_init
and
type
_free
.
For a module of code, initialisation and shutdown
functions should be named
type
_clear
(note spelling) and
module
_initialise
.
This in particular applies to filter-sets.
module
_shutdown
Functions in filter-sets should be declared static
, unless they are to be
exported to other filter-sets. These functions must
have some vendor prefix. This is
bugle_
for the filter-sets
distributed with bugle, but should be something else
for other filter-sets to avoid conflicts.
C files should contain conforming C89 syntax as
far as possible. That means no variable initialisers,
no variable-length arrays, and no C++-style
(//
) comments.
POSIX, BSD and X/OPEN library functions are
acceptable if the appropriate feature macros are
defined (_POSIX_C_SOURCE and so on).
For filter-sets distributed with bugle,
gnulib should be used for memory-allocating functions
(xmalloc
and
xasprintf
, for example) and for
non-portable functions. Unfortunately, gnulib symbols
cannot be exported since they may conflict with
different implementations in the debugged application.
Most of the state in OpenGL is associated with a particular context. Each thread may have a different current context, or no context. Each context can be current in at most one thread. You should keep this in mind when you attempt to track any particular OpenGL state. If you are using a global variable then your code is almost certainly not correct for multi-threaded or multi-context applications.
The object sub-system in bugle makes it easy to associate data with a particular context, and is the recommended method.
BuGLe tries to support systems that only have
runtime support for OpenGL 1.1, to
support the Windows software rasteriser. However, as of July
2008, a glext.h
supporting OpenGL 2.0
is a requirement, so you may assume that the reflection system
knows about these functions. For any post-2.0 functions,
you should favour the
BUDGIE_GROUP_ID(glFunction
)
definition with the oldest name, which is generally an
extension function. You should also protect any such code with
a test for the GL extension define e.g.,
GL_ARB_multitexture.
At present there are no aclocal macros
to set up bugle, but there is a
pkg-config configuration file. Note
that with the default install paths for bugle, not all
pkg-config installations will look in
the right place. You might need to set PKG_CONFIG
to something like /usr/local/lib/pkgconfig
.
Apart from the basic CFLAGS
and
LDFLAGS
extracted from
pkg-config, you should also ensure that
your module is compiled with suitable flags to make it
thread-safe. Using libtool is
recommended, in which case you should use the
-thread-safe
.
The installation directory can also be extracted from pkg-config:
pkg-config --variable=filterdir bugle
The mechanisms for intercepting and modifying OpenGL function calls are arranged in a four-level hierarchy. From largest to smallest, these are:
Filter libraries, which are a loose collection of filter-sets. These allow filter-sets to be grouped together to avoid having hundreds of files. It also makes shared access to data easier.
Filter-sets, which are tightly coupled groups of filters. Each filter-set may have state, may depend upon other filter-sets and may only be loaded or unloaded as a unit.
Filters, which are used to control sequencing. For example, some filter-sets need to have some code run before calls are executed and other code after. These pieces of code would be placed in separate filters. The plugin author may list ordering dependencies between filters.
Callbacks, which are the actual functions that act on calls. A filter may register multiple callbacks, each of which acts on some subset of the possible calls.
In order to allow modifiers to be turned on or off on the fly, there is a distinction between loading and activation. All filter-sets listed in the chain are loaded, but should alter the behaviour of the program only when active. Filter-sets are loaded only at startup and unloaded at program termination, but can be activated or deactivated arbitrarily. Most callbacks are only called when the filter-set is active, but it is possible to register callbacks that are called even when the filter-set is inactive. This allows the filter-set to monitor state so that it can do the right thing during activation, or to execute cleanup code after deactivation.
Budgie is the module within bugle that generates huge
amounts
of code automatically. Apart from the code to override each
OpenGL function, it also generates a lot of reflection
information about functions and types. The API for the
generated code isn't currently documented. Refer to existing
filter-sets or to the header files in include/budgie
.
In bugle terminology, a function is
simply an OpenGL function. Both
glActiveTexture
and
glActiveTextureARB
are functions, and
they are referred to internally by the symbols
FUNC_glActiveTexture and
FUNC_glActiveTextureARB respectively.
At this point, you're probably thinking “but they're the same function!” Bugle deals with this using groups, which are sets of functions with different names but the same signatures and semantics. The group that contains these two functions may be referred to as either GROUP_glActiveTexture or GROUP_glActiveTextureARB. The symbols expand to the same value.
The values of these symbols can change every time the OpenGL
headers are modified, so the symbols should not be used in
filter-sets (in fact, the corresponding headers are not even
installed by bugle). Instead, you should use
budgie_function_name
,
budgie_function_id
and
budgie_function_group
to map between
these numbers and symbolic names on the fly. If you know the
name of the function as a literal piece of text at compile
time, you can write, for example, BUDGIE_FUNCTION_ID(glGetString)
to
get the symbol for glGetString
. At
present this simply wraps budgie_function_id
with
a cache variable, but in future there may be further
optimisations. In core code that includes budgielib/defines.h
, this
macro reduces to FUNC_glGetString. There are
similar macros BUDGIE_GROUP_ID and
BUDGIE_TYPE_ID.
Each library must contain an initialisation function with the following signature:
void bugle_initialise_filter_library(void);
This is the literal name of the function. It will be called by bugle's loader code, and you should not mark it as a constructor or anything similar. Note that it will always be called, even if the corresponding filter-sets are not requested by the user.
This function does any global initialisation required, registers filter-sets, and registers ordering requirements between filter-sets:
#include <bugle/filters.h> filter_set *bugle_filter_set_new(filter_set_info *info);
The filter_set_info must be constant and have global lifetime, since bugle will continue to refer to it after the call returns. It has the following fields:
typedef struct { const char * name; filter_set_loader load; filter_set_unloader unload; filter_set_activator activate; filter_set_deactivator deactivate; const filter_set_variable_info * variables; const char * help; } filter_set_info;
The fields have the following meanings:
name
The name of the filter-set, as it will appear in
~/.bugle/filters
.
load
, unload
, activate
, deactivate
Callback functions that are used to load, unload, activate and deactivate the filter-set. They are described in more detail in Section 4.6.3, “Filter-set initialisation and destruction”.
variables
An array describing the variables that may be configured by the user. This is described in Section 4.6.2, “Filter-set variables”.
help
A one-line description of the filter-set, which is displayed if an unknown chain is requested by the user.
Many filter-sets are configurable via variables that are set
in the configuration file. The
variables
field of a
filter_set_info points to an array of
filter_set_variable_info structures,
which have the following format:
typedef struct { const char * name; const char * help; filter_set_variable_type type; void * value; bool (*callback)(const filter_set_variable_info *var, const char *text, const void *value); } filter_set_info;
The name
and
help
fields have the same use as
they do in filter_set_info. The
type
is one of the enumerants in
Table 4.1, “Filter-set variable types”.
Table 4.1. Filter-set variable types
Enumerant | C type | Checks |
---|---|---|
FILTER_SET_VARIABLE_BOOL | bool | |
FILTER_SET_VARIABLE_INT | long | |
FILTER_SET_VARIABLE_UINT | long | ≥ 0 |
FILTER_SET_VARIABLE_POSITIVE_INT | long | > 0 |
FILTER_SET_VARIABLE_FLOAT | float | finite |
FILTER_SET_VARIABLE_STRING | char * | |
FILTER_SET_VARIABLE_KEY | bugle_input_key | valid |
FILTER_SET_VARIABLE_CUSTOM | any |
With the exception of the
FILTER_SET_VARIABLE_CUSTOM type, each
enumerant corresponds to a C type. Set the
value
field to a pointer to a
C variable of this type, and it will be overwritten with the
value specified by the user. The C variable is not modified if
the user does not specify a value, so it is best to initialise
it with an appropriate default value.
Sometimes it is necessary to perform some extra validation or
initialisation when a variable is passed. For example,
bugle-showstats(7) accepts the show
variable
multiple times to indicate which statistics should be
displayed. The callback
field may be
set to a callback function, which is passed a pointer to the
corresponding
filter_set_variable_info object, the
raw string present in the configuration file, and a pointer to
the interpreted value. Note that at the time of the callback,
the variable passed will not have been
modified. The callback should return
false if the value was invalid and
true otherwise.
Apart from initialising internal structures, a filter-set loader registers filters and callbacks. The function to register a filter within a filter-set is
filter * bugle_filter_new(filter_set *handle, const char *name);
A filter * is an opaque handle to a filter. It is passed to the following functions to register callbacks:
void bugle_filter_catches(filter *f, const char *group, bool inactive, filter_callback callback); void bugle_filter_catches_function(filter *f, const char *function, bool inactive, filter_callback callback); void bugle_filter_catches_all(filter *f, bool inactive, filter_callback callback);
These respectively register callbacks for a single group, a
single function, or all functions. The
inactive
says whether the callback
should apply when the filter-set is inactive. Usually you will
want to set this to false, but in some cases
it is necessary to track some state even when the filter-set
is inactive. When using a group, you can use the name of any
function in that group, although it is best to use the one
with the oldest name as bugle is most likely to know about
it. If bugle was compiled without OpenGL headers exposing
that function, it is ignored.
A filter-set should also indicate ordering dependencies between filters. This is done by calling
void bugle_filter_order(const char *first, const char *second);
This does not require that either filter is actually loaded.
It simply indicates that if both are present, then they are to
be run in the specified order. The most common use is to
specify an ordering relative to
invoke
, the filter that is
responsible for passing a function call on to the real OpenGL
library.
In the functions above, callback
is a
function with the signature
bool callback(function_call *call, const callback_data *data);
The callback should generally return true.
Returning false
aborts any further processing of the call (including
execution if the invoke
filter has
not yet run). This can
be useful if you want to suppress a call, but if possible
it is better to allow execution and undo the effects
afterwards so that later filters get a chance to run.
Callbacks that handle multiple OpenGL functions will need
to know which function was called; the function is found in
call->generic.id
, but more useful
is the group found in call->generic.group
. One can also
get access to the arguments: if the call is known to be
gl
,
then Function
*call->
is the glFunction
.argi
i
th argument, and *call->
is the return value. If the function is not known at compile
time, then the arguments can be accessed via the
void pointers glFunction
.retncall->generic.args
and [i
]call->generic.retn
. These
values can also be modified to change the arguments used or
the value returned to the application, respectively.
The data
is currently still undergoing
revision, so it will not be documented yet.
Bugle has support for associating data with OpenGL objects such as contexts, textures, calls and so on. It is implemented using a generic interface that is not OpenGL-specific, and utility code to deal with specific types of objects is implemented on top of this.
A class is like an OOP class, in that objects are instantiations of classes with data.
Several units of code may wish to attach storage to an object, and they need to be kept separate from each other. Each such unit is known as a registrant. There is no explicit structure to represent registrants: it's just a piece of terminology for the documentation.
An object holds all the data that all registrants have attached to a single OpenGL object. It should be treated as being opaque.
This term is somewhat ambiguous. The object_view type is a key used to fetch a particular registrant's data from objects of a particular class. In some places, however, it also means the actual data that is stored in the object.
Each registrant is free to define these data in
any way it likes. The memory will be suitably
aligned for all built-in data types (at present
the memory is allocated with
malloc
, but this may well
change for efficiency reasons).
This has nothing to do with inheritence. It refers to the scope at which an object can be considered to be current. For example, each thread has a current context, and each context may have a current display list, so display lists have context scope. Bugle allows you so specify what the current object for each class is (which may be NULL), and retrieve it later.
Class structs are generally declared as global pointers with external linkage, so that code that uses them may access them directly.
#include <bugle/objects.h> object_class *bugle_object_class_new(object_class *parent); void bugle_object_class_free(object_class *klass);
These are the constructor and destructor for classes. The
parent
is either the class defining the scope of
the new class, or NULL to indicate that the
new class has thread scope (like an OpenGL context).
The bugle_object_class_free
function
does not delete instances of the class. They must be
manually deleted first. Attempting to manipulate objects
once their class (or any ancestor class in the scope tree)
has been deleted will lead to undefined behaviour.
object_view bugle_object_view_new(object_class *klass, void (*constructor)(const void *, void *), void (*destructor)(void *), size_t size)
This function creates a new view on an existing class. The
constructor is described later. The destructor is simply
called when the object goes away, and receives a pointer to
the view data. It is responsible for cleaning up, but it must
not attempt to free
the pointer.
The size
is the number of
bytes that the registrant wishes to associate with each
instance of this class. It is legal for the size to be zero,
in which case no data is associated but the constructor and
destructor will still be called to provide notification of
object creation and destruction.
Since the object system has no knowledge of OpenGL, each type of object requires some management code to shadow creation and destruction of OpenGL objects, and to keep track of which object is current.
object *bugle_object_new(object_class *klass, const void *key, bool make_current);
This instantiates a new instance of the given class.
Instantiate an instance of the given class. Firstly, if
make_current
is true
then the new object is immediately made the current object of
its class. Then, for each registrant the constructor is called
to initialise the data in its view. The constructor is passed
key
and the view data (the
key
parameter exists
only to pass extra information to the constructor, usually
about the associated GL object). Before calling the
constructor, the view data is filled with zero bytes. The
constructor is optional and may be NULL.
void bugle_object_free(object *obj);
For each registrant of the class, calls the destructor (if any), passing a pointer to the view data. It then frees the memory associated with the object. Don't forget that some OpenGL objects don't actually die when you delete them, only when they are no longer referenced.
object *bugle_object_get_current(const object_class *klass); void bugle_object_set_current(object_class *klass, object *obj);
These functions get and set the current object, within the context of that class. For example, when setting the current display list, it is made current within the current OpenGL context, and switching OpenGL contexts will yield a new current display list. It is legal for the current object to be NULL, and in fact this is the initial state.
If the current object is destroyed, then NULL becomes the new current object.
void *bugle_object_get_data(object *obj, object_view *view); void *bugle_object_get_current_data(object_class *klass, object *obj);
This retrieves the view data stored in
obj
. The view
is
the handle returned by
bugle_object_view_register
. One can get
the data from the current object with the convenience function
bugle_object_get_current_data
(if it is
certain that the current object is not NULL).
Manipulations of a particular class must be serialised, as there is no internal protection against concurrent access. This is seldom a problem since modification of a class is usually done during startup and shutdown, which are serialised.
The object manipulation functions are safe to use
concurrently, since the object structures are not modified.
Setting the current object is thread-safe unless the class has
a parent in the scope tree and an instance of that parent is
current in more than one thread. Even then, it is safe on most
reasonable machines, since setting the current object amounts
to overwriting a single pointer. Note that
bugle_object_new
and
bugle_object_free
may both set the
current object implicitly.
Manipulation of the view data is of course up to each individual registrant, and it is responsible for managing any concurrency issues that arise.
The functions listed above are the minimal set needed to write a
filter-set. This section describes a number of utilities which
simplify the job of writing a more powerful filter-set. Most of
the functions described here are defined in bugle/gl/glutils.h
.
Many OpenGL functions may not be called between
glBegin
and glEnd
.
To facilitate checking for this, the
glbeginend
filter-set provides the
boolean function bugle_gl_in_begin_end
which
indicates whether the current context is in this state. This
function is defined in the header bugle/gl/glbeginend.h
. You must also
also call bugle_gl_filter_post_queries_begin_end("
as part of the filter-set initialisation, for filters that run
after invocation. Failing to do so may yield incorrect results
during interception of filtername
")glBegin
or
glEnd
.
Do not call
bugle_gl_filter_post_queries_begin_end
for filters that run before invocation, or you will
generate a cyclic dependency.
If there is no current OpenGL context, this call will return true. This means that whenever the call returns false, it should be safe to issue OpenGL commands. Refer to Section 4.8.3, “Making calls to OpenGL” for more information about making OpenGL calls from within a filter-set.
It is often useful to know whether an OpenGL call generated an
OpenGL error. If your filter-set
filterset
wishes to do this, it
must call bugle_gl_filter_set_queries_error("
during library initialisation. To actually retrieve the error,
call filterset
")bugle_gl_call_get_error(data->call_object)
.
This mechanism is not totally reliable. It is illegal to call
glGetError
when there is no OpenGL
context or when between glBegin
and
glEnd
. In these cases,
GL_NO_ERROR may be returned even though the
call did not succeed.
In the current implementation, enabling this mechanism also
drasticly reduces performance, as every function call is
intercepted to call glGetError
.
If you attempt to call an OpenGL function directly, the
interception system will intercept the call and bugle will
be entered recursively. There is protection against this (the
call will be forwarded to the real OpenGL library without
further action), but it is nevertheless a performance hit. To
call an OpenGL function
,
you should call it as
glFunction
CALL(glFunction
)(args
);
This should only be done if you put the actual name of the
function as literal text. If you have a string containing the
name, it can be passed to
budgie_function_address_real
instead.
If glFunction
was not known when
bugle was compiled, this will generate a call to
glFunction
. If the OpenGL library
does not have this symbol (which it need not, since OpenGL
entry points beyond OpenGL 1.2 should be queried with
glXGetProcAddressARB
), then you will get
an unresolved symbol error at run-time. On Windows, you will
get a link failure.
If the function is not defined by OpenGL 1.1, you must first check that the extension is supported at run time, and if it is not defined by OpenGL 2.0, you must also check that it is defined at compile time. This is described in Section 4.8.4, “Checking for OpenGL extensions”. Note that bugle will first try the function whose name exactly matches what you pass, but if that does not exist, it will then try the other functions in the same group.
For OpenGL (as opposed to GLX) functions, it is also important to have a valid context which is not inside begin/end. Some utilities are provided to simplify the interaction with begin/end checking. A filter-set that wishes to make OpenGL calls must be registered at library initialisation time with
bugle_gl_filter_set_renders("filter-set
");
and any filters that make such calls and which run after invocation must be registered during filter-set initialisation with
bugle_gl_filter_post_renders("filter
");
To begin a section of code that wishes to make OpenGL function
calls, call bugle_gl_begin_internal_render()
. It
will return a boolean, indicating whether it is safe to
proceed. If it is, you must terminate that block of code by
calling
bugle_gl_end_internal_render("
The first parameter is
a descriptive name for the section of code (typically the
name of the containing function), which is logged if the code
generates any OpenGL errors. Setting the second parameter to
false, however, suppresses the warning, which
should only be done if you have intentionally written code
that may generate OpenGL errors.
name
", true);
Like functions and groups, bugle enumerates the extensions
it knows about, but the enumeration may change frequently and
so is not part of the API. Mapping between names and the
enumeration can be done with
bugle_gl_extension_name
and
bugle_gl_extension_id
, and the macro
BUGLE_GL_EXTENSION_ID can be used with the
literal unquoted name of the extension.
The following macros simplify checking for the presence of an OpenGL extension in the current context:
#include <bugle/gl/glextensions.h> bool BUGLE_GL_HAS_EXTENSION(GL_EXT_some_extension
); bool BUGLE_GL_HAS_EXTENSION_GROUP(GL_EXT_some_extension
); bugle_filter_set_depends("myfilterset"
, "glextensions");
An extension group is a set of extensions with similar
functionality. For example, when passing
GL_EXT_pixel_buffer_object to
BUGLE_GL_HAS_EXTENSION_GROUP
, it will return
true if any one of
GL_EXT_pixel_buffer_object,
GL_ARB_pixel_buffer_object, or OpenGL 2.1 is
available.
Unlike with function groups, there associations are not usually symmetric, because extensions supersede others rather than having identical functionality.
There are also some special extension groups, defined in
gengl/gengl.perl
, that are
convenient ways to test for certain functionality that is
provided by several extensions but is not the sole function of
any of them.
Apart from extensions, you can also check for OpenGL versions using symbols such as GL_VERSION_2_0. The list of extensions is parsed once per context, so these checks are reasonably cheap. If there is no current context, the function returns false.
Remember that you also need to do a compile-time check before using any of these symbols; see Section 4.3.3, “OpenGL extensions” for details.
Table of Contents
Wherever possible, autoconf, libtool and gnulib are used to hide the gory details of porting to different operating systems. However, because bugle interfaces directly into the host system in a number of ways, some work is required to port bugle to new systems.
While other projects may have simply a “Windows” port and a “GNU” port, for example, but it is not so simple for bugle. For example, one might run on Windows but using Cygwin with an X server, or on Linux but using EGL rather than GLX. Instead, a target system is based on a number of categories:
The binary format determines the details of how dynamic linking is done and how it may be subverted. For example, the Windows PE format explicitly indicates which symbols come from which library, and hence require an entire library to be impersonated, while ELF files just list dependent libraries and dependent symbols, making it easy to replace certain symbols.
This determines how things like segfault handling and other low-level operations are performed. Examples are POSIX and Win32.
The main effect of the windowing system is to determine how keyboard and mouse events may be intercepted.
This determines how GL interacts with the windowing system. Usually there is a one-to-one mapping (e.g., AGL, WGL, GLX), but EGL applies on any windowing system.
This determines where to look for files, namely bugle configuration files and system libraries, and potentially temporary files.
Rather than conditionally compiling code based on the particular system in use, each system is characterised by a set of defines that describe its essential properties. This makes it easier to port bugle to similar but not identical systems in future: new code is needed only for those parts either specific to the system in question, or where the new system behaves in an entirely novel way.
The following properties are defined as either 0 or 1, meaning false or true; the descriptions indicate the meaning if true:
The binary format lists the external library that is to be used for each external symbol.
Bugle is injected by LD_PRELOAD
or an equivalent mechanism. If false, the bugle
library is given the same name as the usual OpenGL
library (e.g., opengl32.dll
on Windows), and loads the original library with a
full path.
At present the supported binary formats are PE (BUGLE_BINFMT_PE) and ELF (BUGLE_BINFMT_ELF), although other formats could well be similar enough to be put in the same category.
For the most part, code that needs to be OS API aware needs to
have code implemented for each target OS. The only use of this
in the API at present is the use of
signal
and
siglongjmp
to return useful information
in the face of an access violation, and these functions may be
detected via autoconf.
For this reason, no preprocessor symbols are currently defined to indicate the OS API. This is subject to change should a need arise.
As for OS porting, code that is windowing system specific needs to be written for each windowing system. The following window systems are defined:
BUGLE_WINSYS_X11
BUGLE_WINSYS_WINDOWS
The primary difference between GL-Windowing integration APIs is whether extension function pointers are context-dependent or constant. This is determined by BUGLE_GLWIN_CONTEXT_DEPENDENT. The only currently supported instance of this is WGL (BUGLE_GLWIN_WGL). EGL (BUGLE_GLWIN_EGL) and GLX (BUGLE_GLWIN_GLX) both require function pointers to be the same in any context.
Filesystem layout determines the conventional placement of files. Three variants are defined
Configuration files are stored in
$
and system libraries are searched for in
HOME
/.bugle/usr/lib
.
Configuration files are stored in
$
,
but system libraries are searched for in
HOME
/.bugleGetSystemDir()
.
Table of Contents
The debugger component of bugle uses a wire protocol to communicate data between the debugger filter-set and the debugger application. The protocol is documented here.
It should be noted that this protocol has many shortcomings:
It is unversioned, so the endpoints may be using different versions of the protocol and not be aware of this until something goes catastrophically wrong.
It is not endian-safe. While the control codes this is easily fixed for the control codes, there is little point in doing so until the data being transferred can be placed into a canonical representation.
It may in places be dependent on the pointer size of the system, in particular when transferring GL pointer state.
Packets do not contain a length field, making it impossible to skip unknown packets.
In spite of these limitations, it has been successively used to debug an OpenGL ES application running on an ARM CPU with the debugger running on top of OpenGL on a 64-bit Intel CPU.
The goal is to eventually address these limitations, and patches are welcomed.
The protocol is a binary packet-based protocol. The debugger makes requests to the filter-set, which returns responses. Packets have identifiers to facilitate pipelining. In addition, there are certain responses that may be generated asynchronously by the filter-set.
Name | Description |
---|---|
UINT32 | 32-bit big-endian unsigned integer |
INT32 | 32-bit twos-complement big-endian signed integer |
CODE | same as UINT32, but for debugger protocol enumerated values |
GLENUM | same as UINT32, but for OpenGL enumerated values |
BOOL | A UINT32 with the value 1 (true) or 0 (false) |
STRING | A length (as UINT32) followed by that number of bytes. The character set is UTF-8, in most cases it will be plain ASCII. |
BLOB | A piece of binary data, encoded in the same way as STRING |
Over the lifetime of the debugged process, it will move between three states. When it first starts, it is in the startup state, and waits for instructions from the debugger. At this point, the debugger will send breakpoints and other requests that need to be in place before the program starts issuing GL commands. Once the REQ_RUN request is received, the program enters the running state. From this point, it will alternate between running and stopped. The filter-set will accept commands in both states (although if no GL commands are issued, the filter will not run and so will not be responsive). However, in the stopped state, the filter-set will block and wait for commands and will prevent the thread it is in from running, while in the running state, it will only process commands that are available[1] and will allow its thread to continue running normally.
These are the requests that the debugger may make to the
filter-set. The values for CODE fields are listed
symbolically; the symbol values can be found in
common/protocol.h
.
Each request starts with the request type and a request ID. Request IDs are arbitrary values chosen by the debugger to identify requests. Responses include the request ID, to facilitate matching of responses to requests. Request IDs need not be unique.
Starts the program running. Once it is running, the response RESP_RUNNING is returned, ahead of any asynchronous response that might result.
Type | Description |
---|---|
CODE | REQ_RUN |
UINT32 | request ID |
Set or clear a breakpoint on a function.
Type | Description |
---|---|
CODE | REQ_BREAK |
UINT32 | request ID |
STRING | name of the function |
BOOL | true to set, false to clear |
Set or clear a breakpoint on an event class.
Type | Description |
---|---|
CODE | REQ_BREAK_EVENT |
UINT32 | Request ID |
CODE | one of
|
BOOL | true to set, false to clear |
This is an obsolete command, equivalent to REQ_BREAK_EVENT with an event type of REQ_EVENT_GL_ERROR.
Type | Description |
---|---|
CODE | REQ_BREAK_ERROR |
UINT32 | request ID |
BOOL | true to set, false to clear |
Requests a running program to stop at the next available point. It is ignored if the program is already stopped when the command is received.
Type | Description |
---|---|
CODE | REQ_ASYNC |
UINT32 | request ID |
Filter-sets can be enabled or disabled on the fly by the debugger, similarly to the way they can be activated or deactivated using key sequences.
Type | Description |
---|---|
CODE | REQ_ACTIVATE_FILTERSET or REQ_DEACTIVATE_FILTERSET |
UINT32 | request ID |
STRING | name of the filter-set |
Requests a readout of all the GL state.
Type | Description |
---|---|
CODE | REQ_STATE_TREE_RAW |
UINT32 | request ID |
State can also be requested in a text form, but this is deprecated:
Type | Description |
---|---|
CODE | REQ_STATE_TREE |
UINT32 | request ID |
Request data from a GL object. This command has a common header, and a number of possible sub-types.
Type | Description |
---|---|
CODE | REQ_DATA |
UINT32 | request ID |
CODE | REQ_DATA_TEXTURE |
UINT32 | GL name of the texture object |
GLENUM | texture target |
GLENUM | texture face (used only for cubemaps, otherwise ignored) |
UINT32 | texture level |
GLENUM | format parameter
to glGetTexImage |
GLENUM | type parameter
to glGetTexImage |
Type | Description |
---|---|
CODE | REQ_DATA |
UINT32 | request ID |
CODE | REQ_DATA_FRAMEBUFFER |
UINT32 | GL name of the framebuffer object (zero for the window-system framebuffer) |
GLENUM | framebuffer target (currently ignored but should be GL_FRAMEBUFFER) |
GLENUM | read buffer |
GLENUM | format parameter
to glReadPixels |
GLENUM | type parameter
to glReadPixels |
Type | Description |
---|---|
CODE | REQ_DATA |
UINT32 | request ID |
CODE | REQ_DATA_SHADER |
UINT32 | GL name of the shader object (either GLSL or ARB shader) |
GLENUM | shader type (GLSL) or target (ARB shader) |
This is used for shader or program info log of a GLSL shader. It is valid to query for ARB programs, but the info log is always empty.
Type | Description |
---|---|
CODE | REQ_DATA |
UINT32 | request ID |
CODE | REQ_DATA_INFO_LOG |
UINT32 | GL name of the shader or program object |
GLENUM | shader type, or GL_PROGRAM_OBJECT_ARB for GLSL programs (even in OpenGL ES, where is not a defined enum) |
Synchronous responses are replies to requests. Each synchronous response start with a response type and the request ID of the request it is in response to. Responses are always returned in the same order as the requests were received, but may potentially be intermixed with asynchronous responses.
This is a general-purpose error response to any request which failed. The error code is currently unused and will always be zero. It is reserved for future use, where defined error codes may facilitate automatic interpretation of the error.
Type | Description |
---|---|
CODE | RESP_ERROR |
UINT32 | request ID |
CODE | error code |
STRING | human-readable error message |
This is a general-purpose successful answer response. The
meaning of the value
field is
determined by the corresponding request. Currently, no requests
use this field and its value is undefined.
Type | Description |
---|---|
CODE | RESP_ANS |
UINT32 | request ID |
UINT32 | value |
This is sent in response to REQ_RUN, to indicate that the debugger has successfully initialised.
Type | Description |
---|---|
CODE | RESP_ERROR |
UINT32 | request ID |
The GL state is returned as a contiguous block of responses, with no intermediate asynchronous responses. Each node in the tree is encoded as a RESP_STATE_NODE_BEGIN_RAW (which contains information about the root of the tree, if any), then the children encoded recursively, then a RESP_STATE_NODE_END_RAW response to indicate the end of the children. The same request ID is used for the whole set of responses.
Type | Description |
---|---|
CODE | RESP_STATE_NODE_BEGIN_RAW |
UINT32 | request ID |
STRING | name of the state (empty for the root state) |
UINT32 | numeric name of the state, which is state dependent (typically it is a GL name) |
GLENUM | enum name of the state, which is
state dependent (typically it is a
pname parameter to
a GL query function)
|
STRING | the mangled type name, as returned by
budgie_type_name |
INT32 | element count for an array, −1 for a non-array, and −2 if an error occurred in trying to retrieve the value |
BLOB | the value of the state (currently using host object representation) |
Textual state dumps work similarly to binary state dumps, except that the state is formatting into a human-readable string by the filter-set. It is recommended that clients do not attempt to parse these strings, and should instead use a binary state dump if they intend to inspect values.
Type | Description |
---|---|
CODE | RESP_STATE_NODE_BEGIN |
UINT32 | request ID |
STRING | name of the state (empty for the root state) |
UINT32 | numeric name of the state, which is state dependent (typically it is a GL name) |
GLENUM | enum name of the state, which is
state dependent (typically it is a
pname parameter to
a GL query function)
|
STRING | the human-readable value of the state |
The response to data requests varies by the sub-type of the request. In each case, the data is returned as a binary blob, exactly as it was returned by the appropriate GL query function. The client pixel pack state is set to the default, except that GL_PIXEL_PACK_ALIGNMENT is set to 1.
Type | Description |
---|---|
CODE | RESP_DATA |
UINT32 | request ID |
CODE | REQ_DATA_TEXTURE |
BLOB | texture data |
UINT32 | width |
UINT32 | height (1 for 1D textures) |
UINT32 | depth (1 for 1D and 2D textures) |
Type | Description |
---|---|
CODE | RESP_DATA |
UINT32 | request ID |
CODE | REQ_DATA_FRAMEBUFFER |
BLOB | framebuffer data |
UINT32 | width |
UINT32 | height (1 for 1D textures) |
Type | Description |
---|---|
CODE | RESP_DATA |
UINT32 | request ID |
CODE | REQ_DATA_SHADER |
STRING | shader source |
Type | Description |
---|---|
CODE | RESP_DATA |
UINT32 | request ID |
CODE | REQ_DATA_INFO_LOG |
STRING | info log |
Asynchronous responses are generated when the program transitions from running state to stopped state. Except where otherwise noted, they can occur any time the program is running, potentially interleaved with synchronous responses.
Asynchronous responses include a request ID field, which contains the request ID of the last request that started the program running.
This response is sent when the program is stopped just before executing a function call. This can be due to a user breakpoint on the function, or reaching the next function after a REQ_STEP or REQ_ASYNC.
Type | Description |
---|---|
CODE | RESP_BREAK |
UINT32 | request ID |
STRING | description of the function call |
This response is used when the program is stopped just after executing a function call, as a result of something that occurred in the debugged application (such as a GL error).
Type | Description |
---|---|
CODE | RESP_BREAK_EVENT |
UINT32 | request ID |
STRING | description of the function call |
STRING | description of the event |
The previous sectiosn describe the individual request and response packets. Here we describe their relationship to each other and the transitions between states in the system.
The intention is that except where otherwise noted, illegal requests should result in an error being returned. However, this is not fully implemented and you should not depend on this.
The table below shows the valid states for each command, the resulting state on success (empty meaning no change), and the expected non-error, synchronous response.
Request | Old state | New state | Response |
---|---|---|---|
REQ_RUN | startup | running | RESP_RUNNING |
REQ_CONT | stopped | running | none |
REQ_STEP | |||
REQ_BREAK | any | RESP_ANS | |
REQ_BREAK_EVENT | |||
REQ_BREAK_ERROR | |||
REQ_STOP | stopped, running | stopped | none |
REQ_QUIT | stopped, running | dead | none (process exits) |
REQ_ACTIVATE_FILTERSET | stopped, running | RESP_ANS | |
REQ_DEACTIVATE_FILTERSET | |||
REQ_STATE_TREE_RAW | stopped, running | sequence of RESP_STATE_NODE_BEGIN_RAW and RESP_STATE_NODE_END_RAW | |
REQ_STATE_TREE | sequence of RESP_STATE_NODE_BEGIN and RESP_STATE_NODE_END | ||
REQ_DATA | stopped, running | RESP_DATA (with matching subtype) |
[1] Actually, as long as there is data available on the connection, it will consume a complete command. Thus, sending a partial command and stopping will cause a stoppage. This should probably be fixed.
Table of Contents
Q: | How do I build a 32-bit version of bugle on an AMD64 system? |
A: | The exact details will depend on your OS. Here is what I do on Gentoo:
Gentoo also tries to be clever by putting in a
|
Q: | Why is a recent (>3.0) version of GCC required? |
A: |
Bugle is driven by a number
of tables that list all the information about the
various types and functions in OpenGL. To capture this
information, it is necessary to parse the OpenGL
header files. It would be very difficult to write a
parser to do this robustly, but GCC already knows how
to do this. Unfortunately, the ability to extract a
parse tree from GCC (the
|
Q: |
Why I am getting an error like |
A: | You need to use a version of GCC that supports this flag. See the previous question for details. |
Q: |
I get an error trying to move
|
A: |
You are probably using GCC
4.0, which has broken support for
|
Q: |
When I compile with GCC 4.2, compilation seems to hang
on |
A: |
There is a performance bug in GCC 4.2.2, possibly
#30052
but possibly not. Either downgrade to 4.1, upgrade to
a version where the bug is fixed , or compile without
optimisation ( |
Q: |
I am getting the error |
A: |
You need to have this file, as it defines extensions
to OpenGL that an application might use. You can
obtain the latest copy from http://www.opengl.org/registry. If you
don't want to put it in your system include
directories, you can create a |
Q: | I am using the NVIDIA header files, and I am getting errors about conflicting definitions. |
A: | Try upgrading to the latest NVIDIA drivers. The 60 series seem to fix many of the problems in older header files.
Alternatively, use the headers from Mesa. You can
place them into a |
Q: |
I am using Gentoo, and during compilation of bugle I
get errors similar to this:
|
A: | This seems to be a problem with Gentoo's system for switching between OpenGL drivers, that causes part of the build process to use the X11 software drivers. A workaround is to switch to the X11 drivers for compilation and installation of bugle:
|
Q: |
I have an x86-64 (Athlon 64/Opteron/EM64T) machine
with 64-bit OS, and compilation fails with the message
|
A: |
This has been reported on Fedora Core 5, where
libtool incorrectly
tries to link against the 32-bit version of
and re-run make. If this still
doesn't work, see if your 64-bit |
Q: |
I am using Fedora 10, and when I run
glxgears under bugle it
exits with the message
|
A: |
This seems to be caused by having two different
versions of |
Q: |
Why do I get the error |
A: |
Most likely your distribution has crippled GCC by
switching on options that improve security but are not
C compliant. Try adding
|
Q: | What is the performance penalty? | ||||||||||||
A: | That depends on what you're doing with the library. If you only use filter-sets that intercept a few functions (like showstats), then all other functions suffer only a small penalty. Using filter-sets that check for error after every function (including showerror and the debugger) adds a much bigger penalty.
To give you an example, here are some rough numbers for Quake3 1.32c on
demo
Tracing is particularly slow because it does file I/O, as well as a lot of text formatting. The overhead will also depend on the CPU/GPU balance. GPU-bound programs will be less affected by overheads. | ||||||||||||
Q: |
I wrote
| ||||||||||||
A: |
You either need to specify a full path to
| ||||||||||||
Q: | How do I get a stack trace when my program crashes inside the OpenGL driver? | ||||||||||||
A: | Use the bugle-unwindstack(7) filter-set. See the manual page for more information. | ||||||||||||
A: |
Use the bugle-log(7) filter-set, and turn
on the | ||||||||||||
Q: |
Do I need to always set | ||||||||||||
A: | No, the first chain in the configuration file is the default. | ||||||||||||
Q: |
Can I avoid using | ||||||||||||
A: |
Yes, you can specify | ||||||||||||
Q: | How do you get SDL-based apps to use BuGLe? | ||||||||||||
A: | On GNU systems, they should work as is. On some systems, it may be necessary to run them as
| ||||||||||||
Q: | How do you get Quake3 or Doom3 to use BuGLe? | ||||||||||||
A: | On GNU systems, they should work as is. On some systems, run it as
Note that Quake3 and Doom3 are 32-bit binaries, so if you have an AMD64 system you will need to compile a 32-bit bugle. | ||||||||||||
Q: | How do you get QT-based apps to use BuGLe? | ||||||||||||
A: |
On GNU systems, they should work as is. There is
currently no known workaround for systems that don't
support | ||||||||||||
Q: | I am using GL_EXT_framebuffer_object to render to texture, but the results do not appear in the texture viewer of gldb-gui. | ||||||||||||
A: | This is a known bug in NVIDIA's 76.76 driver. It is fixed in the 80 series drivers. The results should appear in the framebuffer viewer. | ||||||||||||
Q: |
I'm running 64-bit bugle on a 64-bit OS with a
64-bit application, but when I try to run it, it
tries to open the 32-bit version of | ||||||||||||
A: |
I haven't heard if this actually works, but try
setting | ||||||||||||
A: |
Another potential workaround is to replace
| ||||||||||||
Q: |
I am using ATI drivers and when I run configure, it
does not find | ||||||||||||
A: |
I have had this reported by one Debian user, but
didn't get further details on hardware or driver
version. It appears that this version depended on but
did not link to libpthread. While it is possible to
hack this in |
Table of Contents
bugle — An OpenGL debugging library
[BUGLE_CHAIN
=chain
LD_PRELOAD
=libbugle.so
program
argument
...]
bugle is a library that intercepts calls to OpenGL functions, in much the same way that many memory debuggers do. Calls are run through a number of user-specified filter-sets, including one that invokes the original call.
In addition, gldb-gui(1) allows an OpenGL application to be debugged by detecting OpenGL errors and showing OpenGL state. For common usage this may be the most convenient way to use bugle.
The BUGLE_CHAIN
environment variable specifies a
filter-set chain, which is simply a
collection of filter-sets with options. Chains are
defined in the configuration file,
$HOME/.bugle/filters
(see the section called “Configuration”).
You can create filter-set chains in the file
$HOME/.bugle/filters
. It is possible to use
bugle without creating this file, but
it will simply pass all calls straight through to the real OpenGL
library. This is not particularly useful unless you are using
gldb-gui(1). A sample file is available in
doc/examples/filters
in the source
distribution.
The file is text-based. Comments begin with a #
and continue to the end of the line. Strings should be quoted with
double-quotes, and backslash acts as an escape character in the
usual way (including escaping of newlines). Other white-space is
ignored.
Each chain is specified as
chainchain
{filter-set
filter-set
filter-set
... }
Filter-sets are specified as
filtersetfilterset
[key
[inactive]] {option
“value
”option
“value
”option
“value
” ... }
The key
may be used to toggle the
filter-set at run-time (not all filter-sets support this yet, and
those that do will not always work). Key names are based on X
KeySyms (see <X11/keysymdefs.h>
for a
list). They may also be prefixed with C-
,
A-
or S-
to indicate that
the key must be combined with Ctrl,
Alt or Shift respectively. Some
filter-sets have options which are keys; these take the same
format.
If you don't need to specify any options, it is also legal to omit
the braces. Boolean options may be specified as
yes
/no
, as
true
/false
or as
1
/0
.
Each filter-set is documented in its own manual page e.g., the trace filter-set is documented in bugle-trace(7). You can get a brief list of available filter-sets and their options by specifying an undefined chain e.g.,
$
BUGLE_CHAIN
=helpLD_PRELOAD
=libbugle.so
glxgears
BUGLE_CHAIN
Specifies the filter-set chain to use. If absent, the first chain in the configuration file is used.
BUGLE_FILTERS
If set, specifies an alternative configuration file to
use instead of
$HOME/.bugle/filters
.
BUGLE_FILTER_DIR
If set, specifies an alternative directory in which to find modules. This option is currently used by the test suite, and is not intended for general use.
LD_PRELOAD
Tells the linker to load bugle.
BUGLE_DEBUGGER
, BUGLE_DEBUGGER_HOST
, BUGLE_DEBUGGER_PORT
Configuration for remote TCP/IP debugging. Refer to gldb-gui(1) for details.
$HOME/.bugle/filters
Lists the possible filter-set chains. See the section called “Configuration” for a description of the format.
$HOME/.bugle/statistics
Definitions of statistics; see bugle-statistics(5) for more information.
OpenGL color-index mode is not well supported.
Multi-threaded applications that call the GL from more than one thread will break in various ways. The debugger filter-set is particularly fragile.
Display lists may cause things to go wrong, depending on how they are created and what calls go into them.
See the pages for individual filter-sets for specific bugs affecting each.
bugle-statistics — specify formulae and metadata for bugle statistics
"name
" =expression
{ precision1
label "label
" max100
}
By default, bugle(3) gets statistics from
~/.bugle/statistics
, although an alternative
location may be specified in the BUGLE_STATISTICS
environment variable. Most users will just copy the sample file
doc/examples/statistics
from the source
distribution. This manual page describes the format in more detail
for those who want to set up custom statistics.
In order to understand bugle's statistics system, one must first understand how it uses signals and statistics.
A signal is a raw count of something, like number of frames, memory use, or load. For events, these are usually the total number of that event (like frame changes), rather than a rate. Signals are produced by generator filter-sets like bugle-stats_basic(7) or bugle-stats_primitives(7).
Statistics are high-level information computed from signals. For example, frame rate is computed from the number of frames signal and the time signal. Statistics also contain some metadata, such as the label to display with the statistic, and the number of significant digits to print. Logging filter-sets (bugle-logstats(7) and bugle-showstats(7)) use this information to display the statistics.
The statistics file contains the formulae used to compute statistics from signals, as well as the metadata mentioned above.
Blank lines and lines beginning with a #
are
ignored. Statistics have the basic format shown in the synopsis.
The expression consists of standard arithmetic operations
(including parentheses), numbers, and signal expressions. When a
signal expression is evaluated, it is done so over some interval
of time (usually one frame), but key_accumulate
in bugle-showstats(7) allows for longer intervals). Several types of
signal expressions are available to determine how the signal is
measured over that time:
d("signal
")
measures the change in the signal over the interval
a("signal
")
measures the average value of the signal during the interval
s("signal
")
measures the value at the start of the interval
e("signal
")
measures the value at the end of the interval
For measuring rates, use the ratio of two d
expressions. For example, the default configuration defines the
frame rate as
"frames per second" = d("frames") / d("seconds") { precision 1 label "fps" }
For statistics not defined by rates (such as memory consumption),
an a
expression is generally sufficient.
Expressions are evaluated using floating-point arithmetic,
applying the usual rules of operator precedence. If an
expression evaluates to a non-finite value (infinity or
NaN) it will not be shown at all. A non-obvious
application this is that given two expressions
E
and F
, the
compound expression
means
“E
/
E
*
F
F
unless
E
is zero”.
The lines between the {
and
}
contain metadata. The metadata keywords are:
precision
digits
the number of digits to show after the decimal point
label
"text
"the text to show with the statistic when logging
max
number
a maximum value for the statistic, used to scale graphs to the correct height
substitute
number
"label
"
causes label
to be used as
the value if the numerical value was
number
A *
may be used in the name of a signal. If
the expression for a statistic contains any wildcards, it is a
wildcard statistic. When a wildcard
statistic is selected for logging, it is instantiated zero or
more times, with every possible replacement for the wildcard
which yields a valid expression (in the sense that all the
resulting signals must exist). If *
appears
several times in the expression, all occurrences are replaced
with the same value in each instance.
In order to differentiate the instanced statistics, a
*
may also appear in the
label
. This is again replaced with the same
string used to replace the wildcards in the expressions.
For an example of a wildcard statistic in practise, see the
calls per frame
statistic in the
sample statistics file.
gldb-gui — graphical OpenGL debugger
gldb-gui
your-program
[argument
...]
The command above will start gldb-gui, but will not start your program. To do that, use → . Your program will automatically stop if it generates an OpenGL error. You can also stop it manually by selecting → (Ctrl+Break). See the section called “Setting breakpoints” for information on stopping your program when it calls particular OpenGL functions. You can continue your program with → (Ctrl+F9), continue until the next OpenGL function call with → (F8), or kill it with → (Ctrl+F2).
Your program can only be stopped or killed when it calls an OpenGL function. If your program updates its display only when necessary, it may not stop immediately. You can often force it an update by placing another window over your program and then removing it again.
The interface is separated into a number of tabs. You can browse
them at any time, but the information will only be up-to-date when
your program is stopped. When your program is running, the status
bar will contain the text
Running
.
The initial tab is the State tab. It shows all OpenGL state that is textual rather than an image. The state is organised roughly more or less according to the state tables in the OpenGL specification. OpenGL has an overwhelming amount of state, so some tools are provided to make it easier to find answers:
To find a specific state, press Ctrl+F. This opens a text entry box where you can type in the name of the state.
To show only the states that changed since the last time the program was stopped, check the Show only modified checkbox. These states are also shown in bold.
To track only a small set of states, check the checkboxes next to those states, then check the Show only selected checkbox.
To save all the states to an XML file, click the
button.The Buffers tab shows OpenGL buffers (vertex buffer objects). The Buffer combobox allows a buffer to be selected. By default, the buffer is decoded as a sequence of unsigned bytes, but a format specification can be filled in below the combobox to control the decoding. It works best when the entire buffer contains repetitions of repetitions of a single structure format.
Suppose that the buffer contains a sequence of vertices, each
consisting of a 3 GLfloats for the position, 3 unsigned bytes
for a colour, and a byte of padding to make the stride 16
bytes. Then fill in the format field with
fffbbb_
or more compactly,
3f3b_
. A description of the available
letters for specifying types appears below the entry box.
The Textures tab shows OpenGL textures. The Texture combobox allows a texture to be selected, with the currently bound texture of each type shown in bold. For cubemap textures, the Face combobox allows one of the sides to be examined in detail; the default is to show two views of the cube itself. For 3D textures, a slice may be selected with the Z combobox.
The apparent size of the texture is controlled through the
Zoom combobox. Fit
makes the texture as large as possible while still fitting the
window. The other settings set a ratio between texels and
screen pixels. The toolbar also has buttons to
zoom in,
zoom out, set a
1:1 ratio, or
fit to the window size.
The appearance of the texture may be controlled with the Mag filter and Min filter comboboxes. These settings correspond to the GL_TEXTURE_MAG_FILTER and GL_TEXTURE_MIN_FILTER in OpenGL. However, these settings are only used for displaying the texture, and do not affect your program. The Level combobox makes it possible to examine specific texture levels. The default (Auto) uses mipmapping as defined by Min filter.
In some cases, there may not be enough contrast in the
texture to see any details (this is particularly true of
textures that encode non-graphical information, such as lookup
tables). Checking Remap range will scale
the colour range up (or down) to cover the whole [0, 1] range.
To perform more detailed image analysis, use the
button to
copy the texture to the clipboard, and paste it into an
external application such as the GIMP.
The copy feature is only available when compiled with GTK+ 2.6 or later.
Framebuffers may be viewed in much the same way as textures
(see the section called “Examining textures”). The
Framebuffer may be set to either the
current window-system framebuffer, or to a framebuffer
created with glCreateFramebufferEXT
.
Pbuffers that are no the current drawable are not supported.
Within a framebuffer, Buffer may be set to the front buffer, back buffer, depth buffer, stencil buffer or an auxiliary buffer, depending on which buffers actually exist.
The Breakpoints allows breakpoints to be set on specific OpenGL functions. Immediately before calling the function, your program will be stopped and the status bar will indicate which function caused the breakpoint.
Click Enabled checkbox for the function, and select it again later.
to set a new breakpoint, and enter the name of the function into the dialog box that appears. To remove a function from the list, click . If you are likely to want to break on that function later, it is easier to deselect theKeep in mind that a function may have multiple aliases (for
example, glBeginQuery
and
glBeginQueryARB
), and you need to select
the right one.
By default, gldb-gui will stop when a function generates an OpenGL error. This can be disabled by deselecting Break on errors. Note that function breakpoints occur before the function is called, but errors occur afterwards, so gldb-gui may stop twice for the same function.
When your program is stopped, the Backtrace
tab shows the current call stack of your program, as
gdb would. The first few frames (usually those
up to run_filters
) will be internal to
bugle.
To further examine the state of your program, select
xterm and
gdb installed, this will open a terminal window
running gdb, already attached to your program.
Once you have finished, you may either quit gdb
and detach it from your program, or keep it open and
continue
in gdb.
Your program needs to be running from the point of view of gdb for gldb-gui to function correctly.
Debugging on a single machine is not always practical, because the target application may run full-screen, or take over the keyboard or mouse.
Several options exist to use gldb-gui on a separate machine to the target application. However, all of them require trust between the two machines involved as the debugging protocol is not error-checked and so it would be easy for either a rogue target to attack gldb-gui or vice versa.
Regardless of the method used, the GL implementation running the debugger must in some respects be at least as capable as the display running the target application. Specifically, any texture that you view is loaded into an equivalent texture in the debugger, and so the texture target and dimensions must be supported there. Note that even if bugle was built for OpenGL ES, the debugger will use OpenGL.
The easiest and most robust option is to rely on the networking
in the X Windowing System. From the machine containing the
target, start gldb-gui with a suitable
DISPLAY
to place the GUI on a remote machine.
Then go to
→ and set the display to the local machine
(usually :0.0).
Although X11 can directly connect to a remote display over the
network, this is not an encrypted connection and may not be
secure. SSH has an X-forwarding option (-x
),
but with the default setting it does not forward GLX and so it
will not work if you have compiled gldb-gui with OpenGL
support. However, the -Y
forwards the
connection as trusted, and in this mode
GLX is supported. Please see security(7) to understand the
security implications of this before you proceed.
The same setup as above may be used in reverse: the target runs on a remote display, while gldb-gui runs on the local display. The disadvantage of this is that the application is now using indirect rendering, which may affect its performance as well as its behaviour.
This scenario is experimental and fragile. The debugger and target execute on separate machines, and communicate over SSH rather than through a local pipe. Because the debugger protocol was not designed for networking, this currently places severe restrictions on the machines used:
They must use the same byte representations for types. In particular, they must have the same endianness, and it may be necessary for them to have the same word size.
Any types used on the target must also be known
to the debugger. Ideally, one should use the same
version of bugle, compiled with the same compiler and
the same OpenGL headers. In some cases it may be
sufficient to copy src/data/gl.tu
from one build to another and re-build (but do
not run make
clean, as this will cause the copied
file to be regenerated).
The Backtrace tab and the action will not work.
To use this mode, go to Remote via SSH. In the remote host, put the hostname as it will be passed to ssh(1) (it can also contain a username). You must also configure ssh to log into the machine without prompting for a password.
→ and change the mode toThis is similar to the SSH option, but does not require SSH to be available, making it suitable for embedded systems with OpenGL ES. First, start the application on the target, with the following environment variables:
LD_PRELOAD
=libbugle.so
BUGLE_DEBUGGER
=tcp
BUGLE_DEBUGGER_PORT
=port
(optional)BUGLE_DEBUGGER_HOST
=host
This will open a listener on port
.
By default, it will listen on all interfaces, but can be made
to bind to a specific interface by setting
BUGLE_DEBUGGER_HOST
.
Once the target has been started, go to Remote via TCP/IP. You will then be able to fill in the host and port of the target. Once this setup is done, select → to start the debugging session.
→ and change the mode toThis mode does not use any kind of authentication or encryption, so should only be used on a trusted network.
gldb — console-based OpenGL debugger
gldb
your-program
[argument
...]
gldb(1) has been almost entirely superseded by gldb-gui(1), and is not actively maintained. You should try gldb-gui(1) first and only use gldb(1) if gldb-gui(1) does not work.
gldb is a front-end debugger to bugle(3), modelled on gdb(1). It can set breakpoints on OpenGL functions, and by default will stop whenever the program causes a GL error. Pressing Ctrl+C will also cause the running program to stop.
name
Specifies the name of the filter-set chain to use from
the configuration file
~/.bugle/filters
. If
name
is
none
then the default (no filters)
is used.
Shows the list of commands, with brief descriptions.
Starts the program.
Continues running the program.
Runs the program until the next OpenGL call.
Kills the running program.
function
Sets a breakpoint on the OpenGL function
function
.
Breaks on OpenGL errors. This is the default behaviour.
function
Clears a breakpoint on
function
.
Prevents breaking on OpenGL errors.
Exits gldb.
Prints a stack trace using gdb(1)
Starts gdb(1) and attaches it to the program.
The program will be waiting for commands from gldb, so continuing the program will have no effect.
state
Queries the OpenGL state
state
.
If state
is omitted, all
state for the current context is shown. Try first
running the command without argument to see how the
states are arranged, as some state is nested. For
example, the width of the default 2D texture is
referenced as
GL_TEXTURE_2D.0.0.GL_TEXTURE_WIDTH.
Tab completion is also supported.
filename
.ppm
Captures a screenshot from the back buffer, and saves
it to
in ppm(5) format. Since the back buffer is used, you
are not guaranteed a complete picture. For a complete
picture, put a breakpoint on
filename
.ppmglXSwapBuffers
and call this command from there.
filter-set
, disable filter-set
Enables or disables a filter-set on the fly. This is still experimental, and won't work for most filter-sets (because they expect to perform initialisation when the context is created). Dependent filter-sets will automatically be enabled, but will not be automatically disabled.
BUGLE_CHAIN
, BUGLE_DEBUGGER
, BUGLE_DEBUGGER_FD_IN
, BUGLE_DEBUGGER_FD_OUT
Internal environment variables used to communicate between the debugger and the library.
LD_PRELOAD
Used internally to force loading of the library.
bugle-camera — allow the camera to be manipulated
filterset camera [key
inactive] {speed
"1.0
"mouse_dga
"no
" }
This filter-set allows you to take over the camera in an OpenGL application and move it about. This is particularly useful for testing visibility culling and level-of-detail (LOD), as these will not change as the camera is moved.
To use it, make sure it is activated, then move to the mouse to control the camera angle and the Up, Down, Left and Right keys to move the viewpoint. The camera model is a free camera, so it will not maintain a defined up direction. There are a few other useful keys, described in the section called “Options”.
This filter-set supports activation and deactivation; the recommended use is to have it initially inactive and use a key to take over control when desired (see bugle(3)).
Since this filter-set is based on modifying OpenGL state without telling the application, there are significant limitations:
The projection matrix, and in particular, the near and far clip planes, are not altered. Thus, trying to move in too close or out too far could cause objects to be clipped away.
Various fancy rendering techniques involve rendering a quad that is carefully aligned to the screen; altering the camera will break such techniques. There is ultimately no general fix as it is impossible to know when an application is dealing with the real world. If you are writing such an application and wish it to work with this filter-set, you should use a vertex program that ignores the model-view matrix in situations where you do not want this filter-set to interfere.
Applications that rely on the feedback buffer are likely to break.
mouse_dga
This is a boolean option which should be enabled when debugging an application that uses XDGA(3) to get relative motion data from the mouse. If the camera goes all over the place as soon as you move the mouse, try enabling this option (SDL-based applications are the main culprits).
speed
This sets the speed at which the camera moves. Since each application has a different scale, you will need to adjust the value for each application (but dynamic control is also possible; see below).
key_forward
, key_back
, key_left
, key_right
These are the keys for moving the camera. They default to the arrow keys.
key_faster
, key_slower
These keys control the speed of the camera, doubling or halving it respectively. They default to PageUp and PageDown.
key_reset
This key cancels any alterations made, restoring the camera to where the application thinks it is. There is no default.
key_toggle
This key alternately releases and recaptures the mouse. It can be useful if you need to use the mouse in another window without completely disabling the filter-set (which would also restore the camera position). There is no default.
This toggles display of the original view frustum. If this driver supports GL_NV_depth_clamp, depth clamping is used to prevent the frustum from being clipped to the near and far clip planes. There is no default.
bugle-checks — check for errors that OpenGL defines as undefined behaviour
filterset checks
While OpenGL checks for many error conditions, there are some for which the specification does not define behaviour. These instances are usually in performance-critical paths where error-checking would impact on performance. This filter-set checks for some of these conditions. Because of the high cost of the checks, it is only intended for debugging.
The checks that are made are for:
Sourcing vertex or index data from unreadable client memory.
Sourcing vertex or index data from outside the valid range of a vertex buffer object.
Calling glVertex
from outside
glBegin
/glEnd
.
Setting client state from inside
glBegin
/glEnd
.
Specifying indices to
glDrawRangeElements
that are outside
the specified range.
When an error is detected, a warning is written to standard error and the call is ignored. There is currently no convenient way to trap the errors in a debugger (you can, however, find the message in the bugle source and set a breakpoint on the appropriate line).
bugle-eps — captures vector graphics representatios of scenes
filterset eps { filename "" key_eps "
screenshot.eps
key
" title "My screenshot
" bsp "no
" buffer "10000000
" }
This screenshot is similar to bugle-screenshot(7), but instead of a raster image, it produces a vector graphic suitable for printing. This is achieved through gl2ps, which is incorporated into bugle. The supported formats are Postscript, Encapsulated Postscript (EPS), Portable Document Format (PDF) and Scalable Vector Graphic SVG).
The capturing process utilises the OpenGL feedback buffer (see glFeedbackBuffer(3)), which creates some inherent limitations. No per-fragment effects (such as texturing or bitmap rendering) are captured, not will vertex programs work correctly. Essentially, the colour of each vertex must be either directly specified or determined by the OpenGL lighting model.
filename
The file to which the screenshot will be written. The
extension is used to determine the file format. Valid
extensions are
.ps
,
.eps
,
.pdf
and
.svg
.
key_eps
The key-press which triggers the snapshot.
title
The title that is embedded in Postscript and EPS files.
bsp
If this boolean is enabled, the depth sorting is done with a BSP tree to give accurate results. This may be necessary to get correct results in scenes with complex occlusion, but it is much slower.
buffer
The number of entries to allocate for the feedback buffer. If this is too low, the feedback buffer will overflow and the screenshot will fail. The default should be enough for most simple scenes, but for highly complex scenes it may be necessary to create a larger buffer.
bugle-error — detect errors in OpenGL calls
filterset error
This filter-set does not take any visible action on its own, but provides a service to other filter-sets. It calls glGetError(3) after every OpenGL call to detect OpenGL errors (it does not detect X errors).
Usually you will not need to explicitly load this filter-set; if
you want to be informed of OpenGL errors, either use the
showerror
filterset, or
gldb-gui(1). However, you may
occasionally see the message
An OpenGL error was detected but will be lost to the application.
This means that bugle's internal
error-checking code accidentally collected an error caused by one
of your calls, and thus if your application later called
glGetError(3)
it would not be informed of the error. However, if you add the
error
filter-set, it will catch the error
first and your application will be correctly informed of the
error.
Because the error reporting semantics of OpenGL are not completely defined (in particular, an implementation may choose how many error flags it has), it is impossible to guarantee that this filter-set is completely transparent to the application. However, the first call to glGetError(3) always return an error, and in practice this is all that is necessary.
bugle-exe — record a compilable log of OpenGL calls made
filterset exe
{
filename "exetrace.c
"
}
This filter-set provides a log of the OpenGL calls made. Unlike the bugle-trace(7) filter-set, the log is output as C code that can be compiled to reproduce the function calls.
This filter-set is still experimental and incomplete. For details, see below.
Currently, only OpenGL function calls are recorded, not calls to
WGL/GLX/EGL or the native windowing system. Handles returned by
functions such as glGenTextures
and
glCreateShader
are not remapped, so
re-running a compiled trace will only work if handles are
generated deterministically by the OpenGL implementation.
Client-side vertex arrays are also not yet supported.
The generated code merely consists of a function per frame, and a lookup table of those function. It is up to you to provide a harness in which to run this code.
See the limitations above. This filter-set is also vulnerable to any errors or omissions in the tables that tell bugle how many values are stored in an array passed to OpenGL.
Because the filter-set examines arguments and follows pointers, it is possible to crash it by passing invalid values, particularly invalid pointers.
bugle-extoverride — hide OpenGL extensions from an application
filterset extoverride { version "1.5" disable "all" disable "extension
" enable "extension
" }
The extoverride
filter-set modifies the
version and extension strings to hide driver capabilities from the
application. The primary use is to test an application to ensure
that it works correctly on drivers that do not offer these
capabilities.
Apart from modifying these strings, a warning is printed to the log if any function from one of these extensions is called.
version
Sets a new value for GL_VERSION. However, if the true value is lexicographically smaller than this value, the true value is used.
disable
"all
"By default, extensions are exposed unless explicitly disabled. This option reverses the behaviour to hide all extensions that are not explicitly enabled.
disable
"extension
"Hides the named extension from the application. A warning is printed if the extension was not known at the time bugle was compiled; in this case it will still be hidden, but there will not be any warning if it is used anyway.
enable
"extension
"
Like the disable
option, but
enables an extension when the default is disabled.
Warnings are only printed if functions from the disabled extensions are called. At present, no warning will be printed if tokens from those extensions are passed (which is difficult to determine, since multiple tokens may share the same numeric value). Furthermore, some extensions alter semantics without explicit functions or tokens, such as GL_ARB_texture_non_power_of_two; no warnings are issued if these extensions are used.
Also note that extension loader libraries may interfere with the warning mechanism. For example, GLee uses wrappers that cause illegal function calls to be silently ignored.
bugle-frontbuffer — force rendering to the front buffer
filterset frontbuffer
The frontbuffer
filter-set overrides the
draw buffer, setting it to GL_FRONT. This is most
useful when used within gldb-gui(1) in order to see how a scene
is built up batch by batch.
bugle-log — configure logging output from other filter-sets
filterset log { filename "bugle.log
" file_level "4
" stderr_level "3
" flush "no
" format "[%l] %f.%e: %m
" }
The log filter-set does not do any logging itself; instead, it provides logging services to other filter-sets. It is always loaded, but it may be explicitly listed in the configuration file to set options. The log is always written to standard error, but it can be written to file as well. It is also possible to control the log level.
filename
This sets the file for logging. Logging is still done to standard error. Note that with the default settings, the file log is more verbose than the standard error log.
file_level
The log level for the log file, where a higher number means more verbose logging. The levels are:
No logging at all
Errors, usually leading to immediate termination
Warnings, usually affecting bugle's functionality
Notices, usually OpenGL errors or undefined behaviour
Info from filtersets that generate logs, such as bugle-trace(7)
Debugging messages
stderr_level
Similar to file_level
, but for
logging to standard error. The default is 4 for a file
and 3 for standard error.
format
Overrides the default log format. The following printf-style escapes are recognised:
%l
log level
%f
filter-set
%e
event
%m
the log message itself
%p
process ID
%t
thread ID
%%
a literal %
bugle-logstats — log statistics to file
filterset logstats { show "statistic1
" show "statistic2
" }
The logstats
filter-set writes statistics
to the bugle log (see bugle-log(7)). The statistics are gathered from
other filter-sets.
Use the show
option for each statistic that
should be logged to file. The option values must match names
defined in ~/.bugle/statistics
.
bugle-screenshot — takes screenshots and captures video
filterset screenshot { filename "screenshot.ppm
" key_screenshot "C-A-S-S
" }
filterset screenshotC-V
inactive { video "yes" filename "video.avi
" codec "mpeg4
" bitrate "1000000
" allframes "no
" }
The screenshot
filter-set can be used
in one of two modes, corresponding to the two examples above. In
the first, a particular key-press causes a screenshot to be taken,
which is written to file in ppm(5)
format. In the second, a video stream is captured and encoded to
one of a range of formats with ffmpeg(1).
video
This option controls the mode: either screenshots on request or a video stream. This filter-set supports activation and deactivation, so it is possible to record video only on demand.
filename
The file to which the image/video is written. In the
case of an image, if the filename contains a
%
it is
used as a format string for
sprintf(3) with the frame number passed as the
parameter.
key_screenshot
The key combination used to capture a screenshot.
codec
The codec to use when capturing a video. Refer to the
documentation for ffmpeg(1)
for a list of valid codecs. Some codecs require
special setup and may not work, but common codecs such
as mpeg4
and
huffyuv
should work.
bitrate
The approximate number of bits per second to use for video encoding.
allframes
By default, a frame is captured 30 times per second. If this option is set, every frame is captured. Note that the video file will still play at 30fps, so the speed will vary unless the application has been written to use a fixed time-step between frames for its internal animation (this is a useful way to produce smooth video if the capturing overhead is otherwise too high).
lag
Sets the latency between frame capture and encoding. If GL_EXT_pixel_buffer_object is available, setting this option to a value greater than 1 can help mask readback latency, at the expense of video memory.
bugle-showerror — reports errors in OpenGL calls
filterset showerror
This filter-set is a light-weight method of detecting OpenGL errors in applications, where gldb-gui(1) is not useable for some reason (for example, when debugging a full-screen application). It writes OpenGL errors to the log (see bugle-log(7) for details of the log). With the default log settings, the error will be reported to standard error.
bugle-showextensions — show which extensions are used by an OpenGL application
filterset showextensions
The showextensions
filter-set can be used
to determine what version of OpenGL and which extensions are used
by a particular application. It can be used to check that an
application does not accidentally depend on an OpenGL version that
is not targetted. The most common error is calling a core OpenGL
function (for a recent version of OpenGL) when one intended to use
an older and more widely supported extension.
Note that it can only report what is used, not what is required, which may be different if the application uses certain features only after detecting them (but see bugle-extoverride(7) for a way to handle this). It also only tests the run-time usage; the compile-time usage may be different.
Two methods are used for detection: the functions called and the enumerants passed to functions. The former is quite reliable, since different entry points are used for the core and extension versions of the same function. The latter is necessary to detect extensions such as GL_SGIS_generate_mipmap which do not introduce new function calls, but it is less reliable as many enumerants share values. Some extensions are not detected at all: GL_ARB_texture_non_power_of_two does not introduce any tokens or functions, and some promoted extensions (such as GL_ARB_pixel_buffer_object) have additional semantics to their predecessors but again introduce no new tokens or functions.
A typical output is the following:
Min GL version: GL_VERSION_1_5
Min GLX version: GLX_VERSION_1_2
Used extensions: GL_ARB_shader_objects GL_ARB_vertex_shader
This indicates that the application used OpenGL 1.5 and GLX 1.2 (and possibly some extensions that are incorporated into OpenGL 1.5), as well as the extensions listed.
bugle-showstats — render statistics over the display
filterset showstats { show "statistic1
" show "statistic2
" graph "statistic3
" }
The showstats
filter-set
display statistics gathered by other filter-sets over the rendered
display. Statistics can be displayed either as text or as graphs.
show
Specifies a statistic to display as text. The name
must match an entry in
~/.bugle/statistics
.
graph
This is like the show
option above,
but displays a graph rather than text.
time
The interval (in seconds) between updating the statistics. The default is one second.
key_accumulate
By default, statistics are averaged over the time interval specified above, making them approximately instantaneous rates. Pressing this key will cause the display to instead show the average from the time the key was pressed until the current moment.
key_unaccumulate
This key cancels the effect of
key_accumulate
.
bugle-stats_basic — gather frame rate statistics
filterset stats_basic
bugle-stats_calls — gather call frequency count
filterset stats_calls
This filter-set generates a count of the number of times each
OpenGL function is called. The signal associated with
glSomeFunction
is called
calls:
.
glSomeFunction
The expected use is with the calls per
frame
statistic defined in the sample statistics
file, which shows the counts for all functions called at least
once during the frame.
bugle-stats_calltime — gather call timing
filterset stats_calltimes
This filter-set measures how long is spent in each OpenGL call.
The signal associated with
glSomeFunction
is called
calltimes:
.
glSomeFunction
In addition, there is a signal called
calltimes:total
, which measures the total time
spent in all GL calls.
The expected use is with the average time per
call
statistic defined in the sample statistics
file, which shows the average time spent in each call.
Note that these times include some overhead from bugle itself,
so it will be most useful for calls that involve significant work
(such as shader compilation/linking) or which may stall the CPU
(such as glReadPixels
).
bugle-stats_fragments — gather fragment counts
filterset stats_fragments
The stats_fragments
filter-set provides
signals for the number of fragments to other filter-sets. It must
be listed in a chain that uses any statistics related to fragment
counts.
It is simply a wrapper around GL_ARB_occlusion_query, so a fragment is defined exactly as in that extension (and OpenGL 1.5), and will not work unless that extension is supported.
bugle-stats_nv — gather performance data from NVPerfSDK
filterset stats_nv
{
flush "yes
"
}
The stats_nv
filter-set extracts data
from certain NVIDIA GPUs using NVPerfSDK. This filter-set is only
built if the appropriate header file is present at compile time,
and also requires a suitably configured driver and GPU (refer to
the NVPerfSDK documentation).
The possible statistics can be seen in the example
statistics file (doc/examples/statistics
in
the bugle source distribution). It is important to read the
NVPerfSDK documentation to understand what the different types of
statistics are, what they mean, and the limitations of the
hardware interface.
flush
If set, a glFinish(3) will be issued immediately prior to sampling the counters. This guarantees that events will be accounted to the correct frame, but will cause pipeline stalls.
Because NVPerfSDK operates across OpenGL contexts, it will count events from outside the debugged application. In particular, using bugle-showstats(7) to view the results will alter the statistics.
bugle-stats_primitives — gather triangle and batch counts
filterset stats_primitives
The stats_primitives
filter-set provides
signals for the number of triangles and batches to other
filter-sets. It must be listed in a chain that uses any statistics
related to triangle or batch counts.
bugle-trace — record a log of OpenGL calls made
filterset trace
filterset log
{
filename "trace.txt
"
}
This filter-set provides a log of the OpenGL calls made. For each call, the function name, the parameters and the return value (if any) are recorded. Where appropriate, symbolic names are shown for GLenum parameters, and pointers are followed to show the correct number of elements.
There are no options to control this filter-set. All logging is done through bugle's logging system (see bugle-log(7)), and options such as filename and log format can be modified there.
Here is a sample log output
[INFO] trace.call: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
[INFO] trace.call: glLoadMatrixd(0xbfffe610 -> { { 0, -0.29661, 1.22295, 0 }, { 1.22295, 0, 0, 0 }, { 0, 1.18644, 0.305739, 0 }, { 0.037888, 1.61781, -1.52576, 1 } })
[INFO] trace.call: glActiveTextureARB(GL_TEXTURE0)
[INFO] trace.call: glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, 0xbfffe5d0 -> { 0.778524, 0.778524, 0.569631, 0 })
Some enumerants share values, so you may see a different symbolic name in the log than in your source code. It is believed that this should be limited to cases where extensions share a value for semanticly equivalent symbols; if you find a case where this is not true, please inform the author.
Because the filter-set examines arguments and follows pointers, it is possible to crash it by passing invalid values, particularly invalid pointers.
In previous versions, the trace
filter-set
also reported OpenGL errors to the log. This is now handled by the
showerror
filter-set (see bugle-showerror(7)).
bugle-unwindstack — recover a stack trace after a segmentation fault
filterset unwindstack
Some OpenGL drivers (particularly proprietry drivers) are compiled without frame pointer information. The result is that if you pass a bad pointer to the driver, causing it to segfault, gdb(1) is unable to produce a stack trace showing that location of the fault. This filter-set uses some ugly hacks to try to correct this.
When using this filter-set and debugging your application in gdb(1), the segmentation fault will still leave you without a stack trace. However, if you continue running, you will get a second segmentation fault, at which point a stack trace is available.
Note that the call that causes the segmentation fault may not be
the direct cause; for example, a bad pointer passed to
glVertexPointer
might only cause a
segmentation fault in glDrawArrays
. See also
the bugle-checks(7) filter-set, which does
some aggressive error-checking and can detect some of these
conditions.
bugle-wireframe — force rendering in wireframe mode
filterset wireframe
The wireframe
filter-set overrides the
polygon mode, setting it to GL_LINES. This is
useful for visualising the triangulation of models.
Run-time activation and deactivation are not fully supported.
Display lists that alter the polygon mode will cause problems.
As with any filter-set that modifies OpenGL state, it will break complex rendering techniques like render-to-vertex-buffer.
Texturing is generally disabled to make the lines more visible, but fragment programs will nevertheless continue to apply textures.
0.0.20091026
------------
This release just fixes a compilation problem with newer versions of glext.h.
If you have successfully installed the previous version, there is no need to
upgrade.
0.0.20090801
------------
This release just fixes a compilation problem with GCC 4.4. If you have
successfully installed the previous version, there is no need to upgrade.
0.0.20090706
------------
This release just fixes compilation problems with the newest glext.h. If you
have successfully installed the previous version, there is no need to upgrade.
0.0.20090411
------------
This release fixes several bugs, and has improved tracing of EGL and GLX.
0.0.20090311
------------
This release is packed with new debugger features:
- Buffer viewer
- Info log view
- Stop on shader compile/link failure
It also generally improves portability and cross-compilation support, adds
a target for OpenGL ES 1.1 on Windows, and has a lot of bugfixes as well.
0.0.20090221
------------
This release features a whole host of new features and bugfixes. Most notable
are experimental support for TCP/IP-based remote debugging and OpenGL ES 1.1.
0.0.20080824
------------
The texture view was broken in the previous release - this release fixes it.
There are no other changes.
0.0.20080803
------------
This release fixes a number of small bugs. Refer to the ChangeLog for details.
0.0.20080728
------------
This release fixes some problems with OpenGL ES support, and with building
the debugger on Windows. Desktop UNIX users do not need to upgrade.
0.0.20080716
------------
This is a major new release that adds experimental support for Windows and for
OpenGL ES 2.0. These ports are still in the early stages of development, and
many features don't yet work. Nevertheless, you're encouraged to try them out.
Note that you must delete the old contents of $PREFIX/lib/bugle/*.so when
upgrading, as otherwise stale modules will be loaded into bugle.
0.0.20080303
------------
Apart from a few bug-fixes, this release adds checks for incomplete textures to
the 'checks' filter-set. It now also requires GLEW for the image viewers in
gldb-gui - if you find those tabs have vanished then you should install
it from glew.sf.net and reconfigure bugle.
0.0.20080215
------------
This release just fixes a few minor bugs.
0.0.20080123
------------
This is mostly a bugfix release, fixing compilation under old versions of
GTK+ and with some NVIDIA header files. There is also some new reflection
functionality for plugin authors.
0.0.20080103
------------
There are a number of minor bug-fixes (see the ChangeLog), but the major
change in this release is that the filter-set API has been stabilised and made
available to users through installed header files. If you are interested in
writing your own filter-sets, refer to doc/html/extending.html.
0.0.20071206
------------
This release has a lot of changes, but it's mostly under the hood to
start bringing bugle to a point where 3rd parties can easily write and
ship filter-sets. The most obvious change for users is that remote
(network) debugging is now easier to do. See gldb-gui(1) for details
(seriously, read it, as it's still very experimental and the best way
isn't what the GUI might suggest).
NB: if you are upgrading, you MUST delete
/usr/local/lib/bugle/stats.so, otherwise you will get an error about
cyclic dependencies on startup.
0.0.20071108
------------
This release just fixes the generation and installation of the
documentation.
0.0.20071107
------------
This release fixes a number of compilation failures, crashes, and
performance bugs. The manual pages have all been converted to DocBook,
giving much higher quality HTML versions. Some improvements were made
to the documentation at the same time.
Some internals were redesigned, and so some new bugs may have been
introduced. If you find any new bugs, please email me
(bmerry@users.sourceforge.net).
0.0.20071009
------------
Interception of functions that are not filtered is now significantly
faster (showfps will have far less overhead, for example, since it only
acts on glXSwapBuffers).
This release also changes the way startup is handled to better
facilitate libraries like QT and SDL that dynamically load libGL.so.
You no longer need to set an environment variable for SDL applications.
Please let me know of any regressions, particularly on non-GNU
systems.
0.0.20070718
------------
It is now possible to view high-level geometry shaders in the shader
viewer. There is also a minor bug-fix for the framebuffer viewer when
using FBOs.
0.0.20070528
------------
The logging system has been heavily reworked. If you are upgrading,
please read the manpage for bugle-log(7) and bugle-trace(7) and update
your ~/.bugle/filters as appropriate.
There is also a new filter-set for hiding extensions (extoverride) and
miscellaneous bugfixes.
0.0.20070325
------------
I've added support for several of the new extensions exposed by the G80
(aka GeForce 8800); see the ChangeLog for details. These are not fully
tested, especially where NVIDIA haven't released support in the
drivers, so let me know if anything breaks.
The state viewer will also look a little different: some missing
extension suffices have been added (e.g., GL_TEXTURE_RECTANGLE_ARB was
missing the _ARB) and the ordering has been changed to better mirror
the order in the OpenGL 2.1 state tables.
0.0.20070217
------------
This release fixed a number of bugs and makes some internal redesigns.
The most visible new feature is that strings in the gldb-gui state
viewer are now displayed unescaped, making it easier to read multi-line
strings such as shader info logs.
0.0.20070107
------------
There are several bug-fixes related to using gldb-gui with pbuffers and
framebuffer objects. In addition, it is possible to save the current
state to an XML file, and the camera filter-set has the option to
drawing the original view frustum.
0.0.20061227
------------
There is now an option in the texture and framebuffer viewers to remap the
range. This is useful for viewing textures with data outside the [0, 1]
range as well as images with low dynamic range. There are also many bugfixes;
in particular, BuGLe should now work much better on ATI cards.
0.0.20061110
------------
This is a quick-fix release for ccache. If you have successfully
installed 0.0.20061109 there is no need to upgrade.
0.0.20061109
------------
A number of bugs are fixed in this release. The most important is that
screenshots and video capture are working again, having been broken in
the previous release.
0.0.20061022
------------
The statistics system has been completely rewritten and is now a lot
more powerful, supporting customisable statistics, graphs, batch
counts, NVPerfSDK and lower overhead.
You will need to update your ~/.bugle/filters file to use any
statistics (see the examples in doc/examples/filters), and you will
also need to copy doc/examples/statistics to ~/.bugle/statistics.
0.0.20060913
------------
While there is no one feature that makes this release special, it has a
huge number of minor bug-fixes and improvements, mostly to the GUI
debugger. See the ChangeLog for details.
The GUI debugger has almost achieved feature-parity with the text debugger
(run-time enabling and disabling of filter-sets being one missing feature).
I haven't really been maintaining the text debugger, and I'm thinking of
discontinuing it. If there are reasons why you still prefer the text
debugger, let me know soon so that I can reconsider.
0.0.20060828
------------
This release fixes a serious bug in the framebuffer viewer that would
cause it to crash on applications doing render-to-texture. If your
application does not use render-to-texture via
GL_EXT_framebuffer_object you do not need to upgrade.
0.0.20060827
------------
gldb-gui now has a framebuffer viewer! You can view the front and back
buffers, plus depth, stencil and auxiliary buffers as well as
framebuffer objects. There is also better support for 3D textures in
the texture viewer, and assorted bug-fixes.
0.0.20060813
------------
This release makes some improvements to the texture viewer - in
particular, shadow textures will be displayed in grey-scale rather than
crashing, and luminance textures will appear in grey-scale rather than
red-scale. Refer to the ChangeLog for miscellaneous other bug-fixes and
improvements.
0.0.20060528
------------
This release fixes several important bugs (see the ChangeLog for
details). It also introduces some flexibility into the logging format
and allows gldb and gldb-gui to step to the next GL call. The
filter-sets are now documented in individual manual pages.
0.0.20060429
------------
This release fixes a nasty bug (introduced in 0.0.20060416) that causes
the trace filterset to crash on certain calls, and may cause other
spurious behaviour. All users of 0.0.20060416 should upgrade.
0.0.20060416
------------
This release adds a camera filterset, which allows the user to take
over the camera. It won't work with advanced rendering techniques (such
as any kind of post-processing), but is a handy way to test LOD and
visibility culling.
0.0.20060306
------------
This is a minor update that fixes some build problems on Debian
testing. Users who successfully built and installed 0.0.20060224 do not
need to upgrade.
0.0.20060224
------------
This release adds code to intercept keypresses from the application.
Screenshots are now taken by keypress rather than on every frame, and
it is possible to manually start and stop filter-sets such as video
recording (particularly useful if the framebuffer is resized before
starting, as a resize normally terminates encoding) and wireframe. See
the manual page for details.
gl2ps, a library to create Postscript and similar files from the
feedback buffer, has been incorporated, allowing one to create vector
graphic screenshots. This is handled by the 'eps' filterset, although it
actually supports PS, PDF and even SVG). Of course, this has the usual
limitations of the feedback buffer (no per-pixel effects), so don't
expect to capture Doom 3, but it works beautifully for glxgears.
There are also some bugfixes, and in particular GTK+ 2.8 and pre-release
versions of ffmpeg should now be better supported.
WARNING: the options to the screenshot filter-set have changed, and the
epswire filter-set has been replaced by the eps filter-set. You will
need to update your ~/.bugle/filters file. Refer to the example in
doc/examples/filters for a sample. I've removed the option to set a
start frame for video capture (since you can now press a key to start).
If you need the old behaviour let me know and I can restore it.
0.0.20060101
------------
This release greatly improves the texture viewer in gldb-gui, as well as
fixing a number of bugs. It also fixes a dubious shortcut (read: bug)
that caused all kinds of havoc with ATI drivers. If previous releases
have caused weird problems when using an ATI card (whether with gldb,
gldb-gui or a filter), give this release a try.
I have had intermittent problems with gldb-gui crashing due to "an X
Window System error". If you can reproduce this, let me know so that I
can try to fix it.
0.0.20051112
------------
There is now a graphical debugger, gldb-gui. The GUI is still in very
early development, and anything complicated will break it (in
particular, 1D, 3D and cube-map textures are not supported in the
texture viewer).
There is also support for several new extensions in gldb's state viewer,
including GL_ARB_vertex_program, GL_ARB_fragment_program,
GL_ARB_texture_rectangle, GL_EXT_texture_filter_anisotropic, and
GL_EXT_framebuffer_object.
0.0.20050221
------------
This version is a major update. The code generator, state manager and
object tracker have all been rewritten and work a lot better, and
substantial changes have been made to the call dispatcher to reduce
overhead. Almost all of OpenGL 2.0 is now supported. It should also be
slightly more portable, due to the use of ltdl to load modules.
As a result, there are probably lots of new bugs. Please send them to
me at bmerry@users.sourceforge.net.
This version also adds the 'checks' filter-set. See the man page for
details.
0.0.20041123
------------
The major news is the news stats and showstats filter-sets, which can
display frame rate, triangle count and fragment count - as an overlay
on the rendered frame! There has also been some work to reduce overhead,
so that the fps counter will be reasonably accurate.
0.0.20041108
------------
Some bugfixes and minor improvements, including a filter-set to tell
you what extensions are being used. See the ChangeLog.
0.0.20041025
------------
Minor update, the most important fix being that extension functions
will now be properly intercepted. If the previous version worked for
you, and you are not using extensions, then you shouldn't need to
update.
0.0.20041011
------------
This is a fairly major update to the internals, although not much of it
is visible to the user. The biggest changes are the ability to pass
options to the program that gldb will run, and a 'screenshot' command
within gldb to take screenshots on request.
WARNING: see the README for upgrade instructions. Simply installing
over an older version will break things. You will also need to add the
'trace' filter-set to your existing configuration files if you want the
tracing functionality originally provided by the 'log' filter-set.
0.0.20040903
------------
This release adds a few minor improvements to the video capture facility.
See the ChangeLog.
0.0.20040719
------------
The big changes are improvements to the debugging facility, gldb. Pressing
Ctrl-C will now stop the program (ala gdb), and it is possible to query
OpenGL state. Refer to the gldb(1) manual page for details.
This release also offers much better thread safety, and it should now
be mostly possible to use bugle even with programs that render
simultaneously from multiple threads. However, the debugger will not
work on a multi-threaded program, and there are still a few known race
conditions.
Finally, there is also a preliminary video capture mode. It is still
somewhat slow and experimental.
0.0.20040614
------------
This release adds the gldb debugging tool. This replaces the rather
primitive debugging mode of earlier releases, where you specified
breakpoints in the config file. See the man page for instructions on
using gldb.
You will probably need to modify your configuration file, to take
account of the following changes (or you can just copy the one in
doc/examples/filters.
- The invoke filter-set is automatically loaded. You may still specify
it, but omitting it makes no difference.
- The debugger filter-set should no longer be specified. It is
automatically loaded by the debugger, and attempting to use it
without the debugger will lead to errors.
- The "error" filter-set has been renamed to "showerror".
An "error" filter-set still exists, but only detects errors for the
benefit of other filter-sets. For example, the "log" filter-set will
log errors if the "error" filter-set is used.
0.0.20040609
------------
Minor bugfixes only.
0.0.20040606
------------
This is the first public release of BuGLe. Please read the README file
first, as the software it still pretty rough.
0.0.20091026
------------
* Better detection of anonymous types in budgie
* Fix bogus aliasing of glGetObjectParameter*APPLE in newer glext.h
0.0.20090801
------------
* Make compilation work with GCC 4.4
0.0.20090706
------------
* Make compilation work with latest glext.h
0.0.20090411
------------
* Fix display of uniform arrays to show all elements, not just one (closes: #53)
* Fix input system to not call X functions inside an event predicate (closes: #55)
* Improved symbolic display of enums for EGL and GLX
* Added block parameter to bugle_api_enum_name and bugle_api_enum_extensions
* Removed bugle_count_glx_attributes in favour of generic bugle_count_glwin_attributes
* Removed bugle_dump_glx_attributes in favour of generic bugle_dump_glwin_attributes
* Added .bc entries for dumping of attribute lists, particularly in EGL
* Add include dir to bugle.pc to make compilation of third-party plugins work better
* Fix crashes when using repeat counts in buffer viewer
* Fix segfault on starting command-line gldb
* Add stats_calltimes filterset
* Made specifying a command on the command-line optional
0.0.20090311
------------
* Give budgie a separate configure.ac and Makefile.am, to make cross-compilation easier
* Reverted to old version of gnulib without GPLv3 code
* Fix missing symbol globjects_delete_single in ES2.0 port
* Fix compilation errors due to ssize_t not being defined
* Fix extraction of uniforms
* Tweaks to the debug protocol and fixes to the related code
* Updated protocol documentation as part of the user manual
* Support stopping on shader compilation or link failure
* Display of info log
* Fix Windows build of the debugger filter-set
* Fix compilation error in stats_nv filter-set
* Fix display of 3D textures in the debugger
* Buffer object viewer
* Support for OpenGL ES-CM 1.1 on Windows
* Fix a build problem when using Cygwin Perl in a MinGW shell
* Fix installation instructions to require building GLEW from source
* Fix an array overrun during startup in the camera filter-set
0.0.20090221
------------
* Fix tracing support for GL_ARB_transpose_matrix
* Fix several bugs in exe filterset that made it almost unusable
* OpenGL ES-CM 1.1 support (incomplete)
* Improved dumping of glCompressedTex*Image* and glBuffer*Data
* Dump NULL pointers as "NULL" instead of whatever the printf implementation picks
* Rename 'xevent' system to 'input'
* Make --disable-input remove all compile-time dependence on X
* Fix EGL support on POSIX to include the symbols
* Change debug protocol to pass types as mangled strings, to make the protocol
usable between clients and filters that weren't built identically
* Makefile fix for parallel make
* TCP/IP remote debugging (still in progress)
* Fix for newer versions of Mesa's GLgl.h
0.0.20080824
------------
* Fix texture viewer
0.0.20080803
------------
* Fix display of program objects
* Make shader/program string querying more robust
* Allow gldb-gui to accept command arguments in Windows
* Fix tracing of OpenGL ES using ubyte or ushort arrays
* Fix display of internalformat parameter in OpenGL ES
* Fix memory corruption in object tracking if objects are deleted
* Update documentation on setting up for Windows and for OpenGL ES
* Prevent porting.h from being included in tarballs
0.0.20080728
------------
* Fix Makefile rules to correctly build gldb-gui on Windows
* Fix generated egl-win.def (builds on Windows may have been broken)
* Implement framebuffer viewing on OpenGL ES
0.0.20080716
------------
* Port to Windows (experimental, don't expect it all to work)
* Port to OpenGL ES 2.0 (VERY experimental, don't expect any of it to work)
* Add alpha filter-set to produce compilable C traces
* Embed a font in the source instead of trying to query it
* Fix some extension tests
* Change CALL to search around aliases until it finds a pointer
* Remove compile-time tests for pre-GL2 extensions
* Fix count for glGetAttachedShaders
* Fix X11 event interception for 32-bit bugle on 64-bit OS (on my box at least)
* Finer-grained modules
* Remove support for older ffmpeg's, and add support for newer ones
* Rename assorted files and symbols
* Other miscellaneous bug-fixes
0.0.20080303
------------
* Fix several bugs in object tracking, which could lead to crashes in
gldb-gui
* Checking for texture completeness in validate filterset
* Change ifdef tests for GL_EXT_texture_cube_map to GL_ARB_texture_cube_map,
since the former isn't defined by glext.h
* Force correct version info on glXGetCurrentDisplay
* Convert from inlined GLEE to library GLEW
0.0.20080215
------------
* Fix BUGLE_GL_HAS_EXTENSION_GROUP
* Make PBO test run with a larger choice of extensions
* Fix crash when tracing glXChooseVisual
0.0.20080123
------------
* Fix trace of GL_AMBIENT_AND_DIFFUSE
* Add extra reflection API for querying info about or dumping function
parameters
* Fix inappropriate aliasing of some extension functions when using NVIDIA
headers (thanks to Paul Melis for a patch).
* Fix compilation under GTK+ < 2.8
0.0.20080103
------------
* Replace a lot of custom functionality with gnulib
* Change bugle_list_init, bugle_hash_init, bugle_hashptr_init to take a
destructor function instead of a boolean
* Rename safemem.h to misc.h, since all the safemem functionality got
subsumed by gnulib
* Eliminated radix tree code in favour of hashptr_table
* Added more documentation on writing filter-sets
* Fixed crash when examining uniforms on ATI
* Fixed display of stats graphs
* Fixed bogus warning about failing to create aux context when GLX < 1.3
* Fixed access to freed memory in stats core code
* Avoid querying state for attributes and uniforms on programs that have
not been successfully linked
* Move public includes into include/ directory
* Refactor and abstract all the generated tables
* Eliminate ABI dependence on the generated code from the filter API
* Fix potential race conditions with initialisation order
* Some more renaming
* Change CALL_glFoo to CALL(glFoo)
* Rewrite the reflection API for GL extensions
* Merge genexts, genfunctions and gentokens into genpl.perl, with one
header and one C file.
* Fix several bugs where checking for GL_EXT_foo instead of BUGLE_GL_EXT_foo
* Fix video encoding when width is not a multiple of 4
* Update libswscale when available for video encoding, instead of
img_convert (which is deprecated)
0.0.20071206
------------
* Fix an int vs. long mismatch
* Update documentation on writing new filter-sets
* Removed old kludge for filter-sets to register space in each call (which
was non-threadsafe and had potential alignment issues) in favour of
a per-call object.
* Renamed a lot of types and functions to try to bring a more uniform
naming to the API.
* Eliminate initialise_hashing in favour of the constructor macros
* Replace some raise()s with bugle_thread_raise()
* Move stats support code into the core and split out modules
* Change the way statslex.l and statsparse.y avoid namespace collisions
(now more dependent on flex and bison)
* Added About dialog to the debugger
* Use ntohl and htonl in debugger protocol
* Target option in gldb-gui
0.0.20071108
------------
* Fix chunk granularity in generated documentation
0.0.20071107
------------
* Fix segfault if dlopen is called with NULL filename (thanks Ilan Aelion)
* Avoid activating xevent when registering for NoSymbol
* Converted all manual pages and some other documentation to DocBook
* Add DocBook documentation on gldb-gui
* Add support for wildcards in statistics
* Add "calls per frame" statistics
* Add partial support for GCC 4.2
* Fix check for pthread_kill
* Fix bugs in dlopen and interposition regression tests
* Fix shutdown crash if stats_nv is loaded without the NVPerfSDK DLL
* Support non-load ordering dependencies between filter-sets, and use it
to allow stats_* to be listed after showstats/logstats
0.0.20071009
------------
* Do a fast bypass on functions that are never intercepted
* Updated the benchmarks in the README
* Use a constructor attribute to call initialise_all
* Overload dlopen to better handle engines that dlopen("libGL.so")
0.0.20070718
------------
* Add geometry shader support to the shader viewer
* Fix display of window system framebuffer when an FBO is bound
0.0.20070528
------------
* extoverride filterset
* Rework of the logging system
- most references to stderr have been replaced by logging
- option to control the log level
- new bugle_log_printf helper function and more efficient bugle_log
* trace filterset no longer reports errors (use showerror)
* default filenames are now current directory rather than /tmp, for
security
* fix gldb crash on systems without transform feedback
* add F8 key for Step in gldb-gui
* update misc bits of documentation
* work around some Mesa bugs
0.0.20070325
------------
* Add incorrectly omitted vendor suffices from extension state
* Add state for GL_EXT_texture_buffer_object
* Add partial state for GL_EXT_bindable_uniform
* Support for GL_EXT_draw_buffers2
* Support for GL_EXT_packed_float
* Support for GL_EXT_draw_instanced
* Support for GL_EXT_texture_shared_exponent
* Support for GL_EXT_framebuffer_sRGB
* Support for GL_EXT_geometry_shader4 (untested)
* Support for GL_EXT_texture_array
* Support for GL_NV_transform_feedback
* Refactor glstate.c to allow callbacks in the middle of a table
* Reorder top-level state to match order in 2.1 spec
* Fix crash-on-exit when using an SDL app and aux contexts
* Fix crash when examining non-square uniform matrices in the debugger
0.0.20070217
------------
* Fix display of ARB program local parameters
* Fix reporting of VBO overrun vs invalid memory
* Fix handling of function aliases in GLX (fixes encapsulation when
glXGetProcAddress and not glXGetProcAddressARB is used).
* Split type-related functions out of libbugle into libbugleutils
* Communicate state to gldb in raw, not string form
* Display strings in gldb without escaping
* Add extra extensions to genexts.pl
* Add missing CALL_ prefix to multiple calls
* Reduce symbol pollution
* Fix case of programs that define symbols that conflict with OpenGL
* Fix wrapping of GLSL when OpenGL 2.0 headers are not available
0.0.20070107
------------
* Fix display of FBOs on drivers supporting GL_EXT_framebuffer_blit
* Fix crash when using a floating-point PBuffer
* Fix display of per-framebuffer state
* Add an option to show the original frustum in the camera filterset
* Add option to export the current state to XML
0.0.20061227
------------
* Misc tweaks to configure.ac and Makefile.am
* Add missing state GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
* More verbose reporting from the 'checks' filterset
* Fix sort of columns in the state viewer
* Fix display of GL_INTENSITY textures
* Fix GL_PROGRAM_BINDING_ARB state
* Fix level selection changing to 'Separator' on texture change
* Fix a crash if state cannot be updated
* Deprecated the old screenshot interface to the debugger filterset in
favour of the more flexible and robust data_framebuffer interface
* Better robustness to pre-GLX 1.3 systems (fixes framebuffer viewer on ATI)
* Added 'remap range' option to image viewers
* Highlight currently bound shaders, textures and framebuffers
0.0.20061110
------------
* Fix the ccache workaround properly
0.0.20061109
------------
* Fix incorrect count for generic attributes in checks filterset
* Work around Mesa bug (#8883) in checks filterset
* Make things work when ccache is in use (thanks to Wolfgang Frisch)
* Fix video capture and screenshot (broken in previous release)
* Fix redefinition of NAN
0.0.20061022
------------
* Rewrite of the statistics engine
- Configuration file for statistics
- Statistics from NVPerfSDK
* Rewrite of showstats filterset
- Opaque background (now readable over a white scene)
- Faster text rendering via textured quads
- Aligned layout
- Graphing
* Reduce GL namespace pollution from internal objects
* Fix some shutdown code including shutdown ordering
* Remove unnecessary include of getopt.h
* Minor improvements in OpenGL 2.1 support
0.0.20060913
------------
* Fix display of various aliased tokens
* Use pkg-config to get libavcodec configuration
* Fix reported names for GL_POINTS and GL_LINES
* Fix some duplicated GL_ARB_imaging state
* Fix spurious errors due to mis-ordering of error and trackbeginend
* Prevent crash when querying state in glBegin/glEnd
* Fix tracing of glReadPixels
* gldb-gui:
* Work around a bug that caused texture and framebuffer repaints to fail
* Highlight state changes
* Options to filter state
* Option to attach GDB
* Internal redesign
* Fix support for GTK+ 2.4 (hopefully)
* Move breakpoints into a tab
* Make it possible to disable breakpoints without deleting them
* Show an appropriate cursor while doing slow updates
0.0.20060828
------------
* Fix framebuffer viewer for texture attachments
* Fix count for glGenQueries/glDeleteQueries
0.0.20060827
------------
* Framebuffer viewer
* Improvements to the texture viewer
* Eliminate double fetch of texture in gldb-gui
* Restore texture binding when not using aux context for texture fetch
* Fix numerous memory leaks in gldb-gui
* Fix some reporting in trace filter-set
* Fix GL_NONE displaying as GL_FALSE in some places
* Added some missing state to the state display
0.0.20060813
------------
* Fix positioning of stats display when resizing the viewport
* Move line numbering out of the text buffer
* Add accumulate/noaccumulate options to showstats
* Improve PBO support e.g. in dumping glTexImage2D
* Show RGBA and UV values in texture viewer
* Support depth and luminance textures in texture viewer
* Misc OpenGL 2.1 stuff e.g. non-square uniform matrices, GL_CURRENT_RASTER_SECONDARY_COLOR
* Update gl2ps to version 1.3.1
0.0.20060528
------------
* Fix break-on-error
* Add flexible log format
* Add support for GL_MAX_RENDERBUFFER_SIZE_EXT.
* Fix false warnings when glMultiTexCoord* is called from inside
begin/end.
* Add support for the "step" operation to gldb and gldb-gui.
* Fix numerous shutdown bugs
* Fix bug in the showextensions filterset revealed by the fix above
* Create a separate manual page for each filter-set.
0.0.20060429
------------
* Fix a nasty bug in generator that corrupted the type tables, leading to
a crash when logging glMultMatrixf
0.0.20060416
------------
* Add 'camera' filterset
* Add --disable-xevent option to configure to handle the case where
ltdl fails to get symbols from libX11
0.0.20060306
------------
* Fix compilation problem with newer versions of flex
* Fix some Debian testing build problems (thanks to James Lyon for a patch)
0.0.20060224
------------
* Fix numerous C89 warnings. Unfortunately GLee is not valid C89 code.
* Fix dumping of return from glGetProgramStringARB
* Change the way pages were refreshed to be cleaner and to work on GTK+ 2.8.
* Fix bogus warnings about glVertexAttrib*ARB being called from outside
glBegin/glEnd with indices other than 0
* Pass textures to gldb-gui in GL_FLOAT, in preparation for eventual
tone mapping
* Heavy modification of the filter load/unload/activate/deactivate code.
Filtersets are now loaded on startup and never unloaded, but can
be activated or deactivated on the fly by the debugger or by keyboard
shortcut.
* Keyboard interception
* Make video capture work with pre-release versions of libavformat
* Make wireframe and frontbuffer work with activation and deactivation
* Integrate gl2ps to replace epswire
* Change license to GPLv2 only
0.0.20060101
------------
* gldb-gui improvements
- Fix programs hanging around and spinning after gldb-gui quits
- Convert values to UTF8 (TODO: names as well)
* Texture viewer improvements
- copy button (can paste into GIMP)
- display of 1D, 2D, RECT and cubemap textures
- control over mag and min filters
- fit to window or choice of zoom levels
- work around for ATI driver bug
* Rewrite of the GLSL state tracking
* Add bugle_hash_count and bugle_hashptr_count to simplify hash table class
* Allow aux contexts to be created in absence of GLX 1.3
* Make GL_EXT_texture_rectangle support work even if neither
GL_NV_texture_rectangle nor GL_ARB_texture_rectangle is advertised
* Use glXGetProcAddress to get function pointers rather than libtool
(ATI driver works much better now)
* test suite:
- Use GLee rather than relying on GL_GLEXT_PROTOTYPES
- Fix some failures in caused by driver weirdness not bugle bugs
- Rewrite the log comparison tool to give more useful feedback
- Added a test that just creates textures, to test the texture viewer
0.0.20051112
------------
* Fix find_header.pl to look in . and in $srcdir
* Fix Perl warning in glexts.perl
* Have genfunctions.perl spit out #warnings in the C++ code when
the function lists mismatch, rather than breaking everything
* Fix a check for the incorrect symbol in glstate.c (broke with
older glext.h)
* Add support for several extensions in the state manager:
- GL_ATI_draw_buffers
- GL_ARB_vertex_program
- GL_ARB_fragment_program
- GL_EXT_texture_filter_anisotropic
- GL_EXT_depth_bounds_test
- GL_NV_texture_rectangle/GL_EXT_texture_rectangle/GL_ARB_texture_rectangle
- GL_NV_light_max_exponent
- GL_NV_depth_clamp
- GL_NV_multisample_filter_hint
- GL_NV_texture_expand_normal
- GL_IBM_rasterpos_clip
- GL_EXT_framebuffer_object (incomplete)
* Add support for textures beyond GL_MAX_TEXTURE_UNITS
i.e. GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS and GL_MAX_TEXTURE_COORDS
* Add GL_COMPRESSED_TEXTURE_FORMATS to the state
* Extend the extension generator to handle extension groups
* Add some extra checks to the 'checks' filterset
* Add documentation on extension handling
* gldb no longer hangs when asked for non-existent substate
* gldb gives all lines of backtrace, not just first line
* split gldb-common.c out from gldb.c to facilitate gldb-gui
* early work on gldb-gui
* fix gldb segfault on program exit
0.0.20050221
------------
* Added checks filterset
* Vastly improved support for systems short on extensions
* Changed the way tests are done (using regexes) to make them more
robust and less likely to fail when moving to a different system.
* Redesign of the filter management code to reduce overhead.
* Redesign of the filter-set variable code to use tables rather than
banks of if's.
* Rewrite some of the documentation.
* Rewrite of the code generator; now generates GROUP_ tokens and
generally separates groups from functions.
* Rewrite of the state manager (incomplete).
* Support for GLSL.
* Rewritten object tracker, using radix trees.
* Linked lists and hash tables are now told at creation time whether
they own their memory.
* Make opaque bugle_object and bugle_object_view typedefs.
* Redo the internals of object layer storage to avoid possible
alignment problems.
* Added a threading abstraction layer.
* Removed canon.c/canon.h, since they are no longer needed.
* State now assembled by gldb, allowing tab completion for state
* Switch to ltdl for module and library loading
0.0.20041123
------------
* Added stats and showstats filtersets
* Speeded up the case where functions are not intercepted at all
0.0.20041108
------------
* Fix crash in video capture (not sure how it ever worked)
* Fix dumping bug (wrong field was being type overridden)
* (gldb) Make a blank line rerun previous command
* Fix various compiler warnings
* Added --without-lavc configure option
* Add the showextensions filter-set.
0.0.20041025
------------
* Redo libreadline detection to fall back gracefully if the library
doesn't link properly, and to explicitly link against libncurses if
present (needed for Slackware with readline 5, apparently)
* Better support for older versions of glext.h, as well as better support
for possible future versions where extensions get promoted to core.
* Better dumping of GLSLang functions (GetUniformARB needs works still).
* Fix interception of glXGetProcAddressARB (was not loading the filter)
0.0.20041011
------------
* (gldb) Allow options to be passed to the program
* (gldb) screenshot command
* (gldb) Enable and disable filters on the fly
* (capture) By default, skip or duplicate frames for videos
* Fold old types.c and types.h into utils.c and utils.h
* Introduce names.c and names.h, to hold just the names of the functions
* Rewrite the token capture system, which now captures extension info
* New system to capture which functions belong to which extensions
* Support for per-context, per-filter state
* Move tracker library into the core source
* Move logging into the core source, and split the tracing functionality
out into a 'trace' module
* Make gldb and libbugleutils independent of GL and X
* Hex output of GLXDrawable (looks nicer, plus removes spurious regression
errors)
0.0.20040903
------------
* Improvements to video capture: get libavcodec to do the mirroring,
and use GL_EXT_pixel_buffer_object for possibly faster capture.
0.0.20040719
------------
* Added ability to stop running program with Ctrl-C.
* Improved thread safety.
* Rewrite of the state code
* Added basic state dump support to gldb
* Dump overrides are now boolean expressions, not functions
* Improved test suite, with some log regression tests
* Support for aux contexts
* Added movie mode to screenshot filterset
0.0.20040614
------------
* Added the gldb debugger
* Added some sanity checks to make sure that internal code does not generate
GL errors.
* Remove the "trap" option of the "error" module.
* Autoload the invoke filterset, and load the debugger filterset if the
environment variables are set.
* Wrote manual pages.
0.0.20040609
------------
* Made lexer.ll more robust to headers containing function bodies and
inline assembler.
0.0.20040608
------------
* First public release