
A high-performance, production-ready framebuffer graphics library for Linux systems. FBGL delivers direct hardware-level rendering capabilities through a clean, well-documented API, optimized for embedded systems, industrial applications, and performance-critical graphics workloads.
Table of Contents
- Overview
- Technical Specifications
- Installation
- API Documentation
- Implementation Examples
- Performance Characteristics
- Development & Testing
- Architecture
- Contributing
- License
Overview
FBGL (Framebuffer Graphics Library) is a single-header C library providing comprehensive 2D graphics primitives with direct Linux framebuffer device access. Designed for scenarios requiring minimal system overhead and deterministic rendering performance, FBGL eliminates dependencies on complex graphics stacks while maintaining a robust feature set.
Primary Use Cases
- Embedded Systems: Resource-constrained environments requiring efficient graphics rendering
- Industrial Control Panels: Real-time display systems with strict performance requirements
- Digital Signage: Kiosk and information display systems
- Boot Graphics: Pre-desktop environment visual feedback
- Prototyping: Rapid development of graphics concepts without framework overhead
- Educational: Low-level graphics programming instruction
Design Principles
- Minimal Footprint: Header-only architecture with zero external dependencies
- Predictable Performance: Direct memory access with deterministic execution paths
- API Clarity: Intuitive function signatures following industry conventions
- Production Ready: Comprehensive error handling and boundary validation
- Standards Compliance: POSIX-compliant implementation using standard Linux interfaces
Technical Specifications
Core Features
Rendering Capabilities
- Pixel-level manipulation with bounds checking
- Anti-aliased line rendering using Bresenham's algorithm
- Geometric primitives: rectangles, circles (filled and outlined variants)
- Texture mapping with alpha channel compositing
- Bitmap font rendering with PSF1 format support
System Integration
- Direct memory-mapped framebuffer I/O
- Non-blocking keyboard input with escape sequence handling
- Frame timing utilities for animation synchronization
- Configurable validation levels for development vs. production builds
Supported Formats
- Textures: TGA (24-bit RGB, 32-bit RGBA with transparency)
- Fonts: PSF1 (PC Screen Font version 1)
- Color Space: 32-bit ARGB with byte-aligned channels
Platform Requirements
- Operating System: Linux kernel 2.6+ with framebuffer support
- Compiler: C99-compliant compiler (GCC 4.8+, Clang 3.4+)
- Runtime: Standard C library, POSIX threads support
- Permissions: Read/write access to framebuffer device (
/dev/fb0 or equivalent)
- Architecture: Platform-independent (tested on x86_64, ARM, ARM64)
Installation
FBGL implements a header-only architecture requiring no pre-compilation or linking. Integration into existing projects follows standard C header inclusion patterns.
Integration Steps
- Acquire Source: Clone repository or download
fbgl.h git clone https://github.com/lvntky/fbgl.git
- Include Header: Add to project with implementation macro in exactly one translation unit
#define FBGL_IMPLEMENTATION
#include "fbgl.h"
- Compile: Link against math library
gcc -std=c99 -O2 -o application main.c -lm
Build Configuration
Optional Preprocessor Directives:
FBGL_VALIDATE_PUT_PIXEL: Enable runtime bounds checking for pixel operations (development builds)
DEBUG: Enable verbose error reporting and diagnostic output
Example Makefile:
CC = gcc
CFLAGS = -std=c99 -O2 -Wall -Wextra
LDFLAGS = -lm
TARGET = application
SOURCES = main.c
$(TARGET): $(SOURCES)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
clean:
rm -f $(TARGET)
API Documentation
Initialization & Lifecycle Management
int fbgl_init(
const char *device,
fbgl_t *fb);
Description: Initialize framebuffer context with specified device.
Parameters:
device: Path to framebuffer device (use NULL for default /dev/fb0)
fb: Pointer to framebuffer context structure
Returns: 0 on success, -1 on failure with errno set appropriately
Thread Safety: Not thread-safe; call from single thread during initialization
void fbgl_destroy(
fbgl_t *fb);
Description: Release framebuffer resources and unmap memory.
Parameters:
fb: Pointer to initialized framebuffer context
Thread Safety: Not thread-safe; ensure all rendering operations complete before calling
Rendering Primitives
void fbgl_put_pixel(
int x,
int y, uint32_t color,
fbgl_t *fb);
Description: Write single pixel at specified coordinates.
Parameters:
x, y: Pixel coordinates in screen space
color: 32-bit ARGB color value
fb: Framebuffer context
Performance: O(1) operation, suitable for high-frequency calls
Notes: Bounds checking only active when FBGL_VALIDATE_PUT_PIXEL defined
Description: Render line segment using Bresenham's algorithm.
Parameters:
start: Starting point coordinates
end: Ending point coordinates
color: Line color
fb: Framebuffer context
Complexity: O(max(dx, dy)) where dx, dy are coordinate deltas
Description: Render filled axis-aligned rectangle.
Parameters:
top_left: Upper-left corner coordinates
bottom_right: Lower-right corner coordinates
color: Fill color
fb: Framebuffer context
Complexity: O(width × height)
void fbgl_draw_circle_filled(int x, int y, int radius,
Description: Render filled circle using optimized scanline algorithm.
Parameters:
x, y: Center point coordinates
radius: Circle radius in pixels
color: Fill color
fb: Framebuffer context
Complexity: O(radius²)
Texture Operations
Description: Load TGA texture from filesystem with automatic format detection.
Parameters:
path: Filesystem path to TGA file
Returns: Texture handle on success, NULL on failure
Supported Formats: 24-bit RGB, 32-bit RGBA (uncompressed)
Memory Management: Caller responsible for deallocation via fbgl_destroy_texture()
Description: Blit texture to framebuffer with alpha blending support.
Parameters:
fb: Framebuffer context
texture: Source texture handle
x, y: Destination coordinates (top-left corner)
Complexity: O(texture_width × texture_height)
Notes: Automatically clips to viewport boundaries
Description: Release texture resources.
Parameters:
texture: Texture handle to deallocate
Thread Safety: Not thread-safe with concurrent texture operations
Typography
Description: Load PSF1 bitmap font from file.
Parameters:
path: Filesystem path to PSF1 font file
Returns: Font handle on success, NULL on failure
Font Properties: 8-pixel fixed width, variable height, 256 or 512 glyphs
const char *text, int x, int y,
uint32_t color);
Description: Render text string using bitmap font.
Parameters:
fb: Framebuffer context
font: Font handle
text: NULL-terminated string
x, y: Text baseline coordinates
color: Text color
Complexity: O(string_length × glyph_height × glyph_width)
Input Handling
int fbgl_keyboard_init(void);
Description: Initialize non-blocking keyboard input system.
Returns: 0 on success, -1 on failure
Side Effects: Modifies terminal attributes; automatically restored on exit
fbgl_key_t fbgl_get_key(void);
Description: Poll for keyboard input without blocking.
Returns: Key code constant or FBGL_KEY_NONE if no input available
Supported Keys: Arrow keys, WASD, Enter, Space, Escape
bool fbgl_is_key_pressed(fbgl_key_t key);
Description: Check if specific key is currently pressed.
Parameters:
key: Key code to check
Returns: true if key pressed, false otherwise
void fbgl_destroy_keyboard(void);
Description: Restore terminal attributes and cleanup input system.
Utility Functions
float fbgl_get_fps(void);
Description: Calculate instantaneous frame rate based on frame timing.
Returns: Frames per second as floating-point value
Usage: Call once per frame after rendering operations
uint32_t fb_get_width(
const fbgl_t *fb);
uint32_t fb_get_height(
const fbgl_t *fb);
uint32_t *fb_get_data(
const fbgl_t *fb);
Description: Query framebuffer properties.
Returns: Dimensions in pixels or direct pointer to pixel buffer
Color Macros
FBGL_RGB(r, g, b)
FBGL_RGBA(r, g, b, a)
FBGL_F32RGB_TO_U32(r, g, b)
Color Format: ARGB with byte layout [A][R][G][B] on little-endian systems
Implementation Examples
Basic Framebuffer Initialization
#define FBGL_IMPLEMENTATION
#include "fbgl.h"
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
if (fbgl_init(NULL, &fb) != 0) {
fprintf(stderr, "Error: Failed to initialize framebuffer: %m\n");
return EXIT_FAILURE;
}
printf("Framebuffer initialized: %dx%d\n",
fb_get_width(&fb), fb_get_height(&fb));
fbgl_set_bg(&fb, FBGL_RGB(20, 20, 40));
fbgl_destroy(&fb);
return EXIT_SUCCESS;
}
Rendering Pipeline Example
#define FBGL_IMPLEMENTATION
#include "fbgl.h"
#include <signal.h>
#include <stdbool.h>
static volatile bool running = true;
static void signal_handler(int signum)
{
if (signum == SIGINT || signum == SIGTERM) {
running = false;
}
}
int main(void)
{
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
if (fbgl_init(NULL, &fb) != 0) {
perror("fbgl_init");
return EXIT_FAILURE;
}
if (fbgl_keyboard_init() != 0) {
perror("fbgl_keyboard_init");
fbgl_destroy(&fb);
return EXIT_FAILURE;
}
font = fbgl_load_psf1_font("/usr/share/kbd/consolefonts/default8x16.psfu");
int frame = 0;
while (running) {
fbgl_set_bg(&fb, FBGL_RGB(0, 0, 0));
int x = 400 + (int)(100 * cos(frame * 0.02));
int y = 300 + (int)(100 * sin(frame * 0.02));
fbgl_draw_circle_filled(x, y, 50, FBGL_RGB(255, 100, 0), &fb);
if (font) {
char fps_text[32];
snprintf(fps_text, sizeof(fps_text), "FPS: %.1f", fbgl_get_fps());
fbgl_render_psf1_text(&fb, font, fps_text, 10, 10,
FBGL_RGB(255, 255, 255));
}
fbgl_key_t key = fbgl_get_key();
if (key == FBGL_KEY_ESCAPE) {
running = false;
}
frame++;
}
if (font) fbgl_destroy_psf1_font(font);
fbgl_destroy_keyboard();
fbgl_destroy(&fb);
return EXIT_SUCCESS;
}
Texture-Based Rendering
#define FBGL_IMPLEMENTATION
#include "fbgl.h"
int main(void)
{
if (fbgl_init(NULL, &fb) != 0) {
return EXIT_FAILURE;
}
sprite = fbgl_load_tga_texture("assets/sprite.tga");
if (!sprite) {
fprintf(stderr, "Warning: Failed to load texture\n");
}
fbgl_set_bg(&fb, FBGL_RGB(50, 50, 50));
if (sprite) {
fbgl_draw_texture(&fb, sprite, 100, 100);
}
getchar();
if (sprite) fbgl_destroy_texture(sprite);
fbgl_destroy(&fb);
return EXIT_SUCCESS;
}
Compilation Command:
gcc -std=c99 -O2 -Wall -Wextra -o example main.c -lm
sudo ./example
Performance Characteristics
Benchmarking Results
Performance measurements conducted on reference hardware (Intel Core i5-8250U, 1920×1080 framebuffer):
| Operation | Throughput | Latency | Notes |
fbgl_put_pixel | ~50M pixels/sec | 20ns | Without validation |
fbgl_draw_line | ~5M pixels/sec | Variable | Depends on length |
fbgl_draw_circle_filled (r=100) | ~800 circles/sec | 1.2ms | Optimized scanline |
fbgl_draw_rectangle_filled (100×100) | ~3000 rects/sec | 330μs | Memcpy-based |
fbgl_draw_texture (256×256) | ~200 blits/sec | 5ms | With alpha blending |
Optimization Strategies
For High-Frequency Pixel Operations:
- Disable validation in production builds (remove
FBGL_VALIDATE_PUT_PIXEL)
- Batch pixel writes when possible
- Consider dirty rectangle tracking for partial updates
For Large-Scale Rendering:
- Implement double buffering at application level
- Use texture atlases to minimize texture switching overhead
- Pre-compute static geometry where applicable
Memory Access Patterns:
- Sequential memory access patterns optimize cache utilization
- Vertical lines perform worse than horizontal due to stride access
- Consider memory alignment for optimal performance
Scalability Considerations
Resolution Impact:
- Linear scaling with pixel count for full-screen clears
- Sub-linear scaling for small primitives due to fixed overhead
- Texture operations scale with source texture size, not framebuffer size
Concurrency:
- Library is not thread-safe; external synchronization required
- Consider separate framebuffer contexts for multi-threaded rendering
- Atomic operations not used; manual locking necessary for parallel access
Development & Testing
Virtual Framebuffer Testing
For development environments without direct framebuffer access:
# Start virtual framebuffer environment
chmod +x fbgl_test_virtual_fb.sh
./fbgl_test_virtual_fb.sh
VNC Connection:
Host: localhost:5900
Protocol: VNC (RFB)
This configuration provides isolated testing without affecting system display or requiring elevated privileges.
Debugging Techniques
Enable Verbose Diagnostics:
#define DEBUG
#define FBGL_VALIDATE_PUT_PIXEL
#define FBGL_IMPLEMENTATION
#include "fbgl.h"
Common Issues:
| Symptom | Cause | Solution |
EACCES on init | Insufficient permissions | Run with sudo or add user to video group |
| Distorted output | Incorrect color format | Verify framebuffer bits per pixel setting |
| Crash on cleanup | Double-free or invalid pointer | Ensure single fbgl_destroy() call |
| Flickering | Direct rendering without buffering | Implement double buffering |
Memory Leak Detection:
valgrind --leak-check=full --show-leak-kinds=all ./application
Unit Testing
The project currently lacks formal unit tests. Contributions implementing test coverage are welcome. Recommended testing framework: Unity or Check.
Architecture
System Architecture
┌─────────────────────────────────────────┐
│ Application Layer │
│ (User Code - Rendering Logic) │
└───────────────┬─────────────────────────┘
│
│ FBGL API Calls
▼
┌─────────────────────────────────────────┐
│ FBGL Library Layer │
│ • Primitive Rendering │
│ • Texture Management │
│ • Font Rendering │
│ • Input Handling │
└───────────────┬─────────────────────────┘
│
│ mmap(), ioctl()
▼
┌─────────────────────────────────────────┐
│ Linux Framebuffer Driver │
│ (/dev/fb0 device) │
└───────────────┬─────────────────────────┘
│
│ Hardware Interface
▼
┌─────────────────────────────────────────┐
│ Display Hardware │
│ (Graphics Card / Embedded Display) │
└─────────────────────────────────────────┘
Memory Architecture
Framebuffer Memory Layout:
┌──────────────────────────────────────┐
│ Framebuffer Device Memory │
│ (Kernel-allocated, device memory) │
└──────────────┬───────────────────────┘
│ mmap()
▼
┌──────────────────────────────────────┐
│ User-space Mapped Region │
│ (Direct R/W access via fb->pixels) │
│ │
│ Layout: Row-major, 32-bit ARGB │
│ Address: pixels[y * width + x] │
└──────────────────────────────────────┘
Data Structure Organization:
fbgl_t: Core framebuffer context (72 bytes on 64-bit systems)
fbgl_tga_texture_t: Texture descriptor with pixel data pointer
fbgl_psf1_font_t: Font metadata with glyph bitmap array
Algorithm Implementation
Line Rendering (Bresenham's Algorithm):
- Incremental error calculation avoids floating-point operations
- Optimized for integer arithmetic and minimal branching
- Complexity: O(max(Δx, Δy))
Circle Rendering (Midpoint Circle Algorithm):
- Exploits 8-way symmetry to minimize calculations
- Decision parameter updated incrementally
- Filled variant uses horizontal span fills for cache efficiency
Alpha Blending:
- Standard source-over compositing:
Cout = Csrc * α + Cdst * (1-α)
- Implemented per-channel for full RGBA support
- Conditional rendering skips fully transparent pixels
Error Handling Philosophy
FBGL employs defensive programming with multiple error handling layers:
- Initialization Errors: Return error codes with
errno preservation
- Runtime Validation: Optional bounds checking via preprocessor flags
- Resource Management: Explicit lifecycle management with cleanup functions
- Graceful Degradation: Functions return early on invalid input rather than crashing
Project Roadmap
Version 0.2.0 (Planned)
High Priority:
- [ ] Double buffering support with swap chain management
- [ ] PNG texture loading via libpng integration
- [ ] Polygon rendering with scanline rasterization
- [ ] Clipping region API for windowed rendering
- [ ] Comprehensive unit test suite
Medium Priority:
- [ ] Ellipse rendering primitives
- [ ] Bezier curve rendering
- [ ] TrueType font rendering via FreeType
- [ ] Color palette management for indexed color modes
- [ ] DMA-based transfer optimization
Low Priority:
- [ ] Multi-monitor support
- [ ] Video mode switching API
- [ ] Hardware cursor integration
- [ ] Wayland backend as alternative to framebuffer
Long-Term Vision
- Cross-platform abstraction layer for non-Linux systems
- SIMD optimization for pixel operations (SSE/AVX/NEON)
- GPU-accelerated rendering path via DRM/KMS
- Comprehensive performance profiling suite
- Interactive examples and tutorials
Contributing
FBGL welcomes contributions from the community. All submissions should maintain code quality standards and follow project conventions.
Contribution Guidelines
Code Standards:
- C99 compliance required
- Follow existing formatting style (K&R with 8-space tabs)
- Include documentation comments for public API functions
- Avoid external dependencies unless critically necessary
- Ensure warning-free compilation with
-Wall -Wextra -Wpedantic
Submission Process:
- Fork repository and create feature branch
- Implement changes with clear commit messages
- Test across multiple resolutions and color depths
- Update documentation to reflect API changes
- Submit pull request with detailed description
Testing Requirements:
- Verify no memory leaks with Valgrind
- Test on both x86_64 and ARM architectures if possible
- Ensure backward compatibility with existing API
- Include example code demonstrating new features
Priority Areas:
- Performance optimization and benchmarking
- Platform compatibility improvements
- Documentation enhancements
- Example applications and tutorials
- Unit test development
Code Review Process
All pull requests undergo review for:
- Correctness and robustness
- Performance implications
- API design consistency
- Documentation completeness
- Code style compliance
License
FBGL is dual-licensed to provide maximum flexibility:
Option A: MIT License
Permissive license allowing commercial use with attribution.
Option B: Public Domain (Unlicense)
No restrictions whatsoever; use freely without attribution.
Choose the license that best suits your project requirements. See LICENSE file for complete terms.
Project Status
Current Version: 0.1.0
Status: Production-ready for specified use cases
Maintenance: Active development, responsive to issues
Platform: Linux (kernel 2.6+)
Known Limitations
- Single-threaded rendering model
- No hardware acceleration support
- Limited to 32-bit color depth
- Requires root access or appropriate permissions
- No built-in vsync mechanism
Security Considerations
FBGL requires direct hardware access and elevated privileges. Consider:
- Input validation on user-supplied data (texture paths, text content)
- Resource limits for texture sizes to prevent memory exhaustion
- Proper cleanup in signal handlers to prevent resource leaks
- Sandboxing applications in production environments
Showcase
Technical Demonstrations
Texture Rendering with Alpha Blending
Demonstrates TGA texture loading, alpha channel compositing, and frame-rate independent animation
Bitmap Font Rendering
PSF1 font rendering with antialiased glyphs and configurable color
Real-time Raycasting Engine
3D perspective rendering using FBGL primitives, showcasing performance capabilities
Acknowledgments
Project Leadership:
Levent Kaya (@lvntky) - Original author and maintainer
Contributors:
See acknowledgements.md for complete contributor list and third-party attribution.
Special Thanks:
Linux framebuffer documentation contributors, academic resources on computer graphics algorithms, and the open-source community for testing and feedback.
References
Support
Issue Tracking: GitHub Issues
Documentation: Project Wiki (coming soon)
Discussions: GitHub Discussions
For bug reports, include:
- FBGL version
- Linux kernel version and distribution
- Framebuffer configuration (
fbset -i)
- Minimal reproduction code
- Expected vs. actual behavior
Disclaimer: This library provides low-level hardware access. Incorrect usage may cause system instability or data corruption. Thoroughly test in development environments before production deployment. The authors assume no liability for damages resulting from use of this software.