diff options
| author | Levent Kaya <levent@dev> | 2025-11-02 12:32:55 +0300 |
|---|---|---|
| committer | Levent Kaya <levent@dev> | 2025-11-02 12:32:55 +0300 |
| commit | 91cfe0c6b969c10987c8a06cd9048ff4b01a1788 (patch) | |
| tree | 338dd9655a8a0291c086b860c92efa661b792e70 | |
| parent | 0f519511db8eb92275d37d04cc53e7179e32a17e (diff) | |
[feature] emulator init commit for testing wo hardware access
| -rw-r--r-- | emu/README.md | 230 | ||||
| -rw-r--r-- | test/Dockerfile | 20 | ||||
| -rw-r--r-- | test/README.md | 168 | ||||
| -rw-r--r-- | test/test.sh | 119 |
4 files changed, 230 insertions, 307 deletions
diff --git a/emu/README.md b/emu/README.md new file mode 100644 index 0000000..5033baf --- /dev/null +++ b/emu/README.md @@ -0,0 +1,230 @@ +# FBGL Virtual Framebuffer Emulator + +Test your FBGL programs without actual framebuffer hardware using SDL2! + +## Quick Start + +```bash +# 1. Install dependencies +sudo apt-get install libsdl2-dev build-essential + +# 2. Build the emulator +make + +# 3. Run your FBGL program +./fbgl_run.sh ./your_fbgl_program +``` + +## Components + +1. **libfbgl_preload.so** - LD_PRELOAD library that intercepts framebuffer calls +2. **fbgl_viewer** - SDL2 window that displays the virtual framebuffer +3. **fbgl_run.sh** - Convenient wrapper script to run everything + +## Installation + +### Option 1: Using Makefile + +```bash +# Download/create these files in the same directory: +# - fbgl_preload.c +# - fbgl_viewer.c +# - fbgl_run.sh +# - Makefile (below) + +make all +``` + +### Option 2: Manual compilation + +```bash +# Compile the preload library +gcc -shared -fPIC fbgl_preload.c -ldl -o libfbgl_preload.so + +# Compile the viewer +gcc fbgl_viewer.c -lSDL2 -o fbgl_viewer + +# Make runner script executable +chmod +x fbgl_run.sh +``` + +## Usage + +### Basic Usage + +```bash +./fbgl_run.sh ./my_fbgl_app +``` + +### With Arguments + +```bash +./fbgl_run.sh ./my_fbgl_app --arg1 value1 --arg2 value2 +``` + +### Manual Usage (without script) + +```bash +# Terminal 1: Start the viewer +./fbgl_viewer & + +# Terminal 2: Run your program with LD_PRELOAD +LD_PRELOAD=./libfbgl_preload.so ./my_fbgl_app +``` + +## Example Test Program + +Create a simple test program (`test_fbgl.c`): + +```c +#define FBGL_IMPLEMENTATION +#include "fbgl.h" +#include <unistd.h> + +int main() { + fbgl_t fb; + + if (fbgl_init(NULL, &fb) < 0) { + return 1; + } + + // Draw some shapes + for (int i = 0; i < 100; i++) { + fbgl_set_bg(&fb, FBGL_RGB(0, 0, 0)); + + // Draw moving circle + int x = 400 + (int)(200 * cos(i * 0.1)); + int y = 300 + (int)(200 * sin(i * 0.1)); + fbgl_draw_circle_filled(x, y, 50, FBGL_RGB(255, 0, 0), &fb); + + // Draw rectangle + fbgl_point_t tl = {100, 100}; + fbgl_point_t br = {300, 300}; + fbgl_draw_rectangle_outline(tl, br, FBGL_RGB(0, 255, 0), &fb); + + usleep(16666); // ~60 FPS + } + + fbgl_destroy(&fb); + return 0; +} +``` + +Compile and run: + +```bash +gcc test_fbgl.c -o test_fbgl -lm +./fbgl_run.sh ./test_fbgl +``` + +## Makefile + +Create a file named `Makefile`: + +```makefile +CC = gcc +CFLAGS = -Wall -Wextra -O2 +LDFLAGS = -lSDL2 -ldl -lm + +.PHONY: all clean test + +all: libfbgl_preload.so fbgl_viewer fbgl_run.sh + +libfbgl_preload.so: fbgl_preload.c + @echo "Building preload library..." + $(CC) -shared -fPIC $(CFLAGS) $< -ldl -o $@ + +fbgl_viewer: fbgl_viewer.c + @echo "Building SDL viewer..." + $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@ + +fbgl_run.sh: + @echo "Making runner script executable..." + @chmod +x fbgl_run.sh + +test: all test_fbgl + @echo "Running test program..." + ./fbgl_run.sh ./test_fbgl + +test_fbgl: test_fbgl.c fbgl.h + @echo "Compiling test program..." + $(CC) $(CFLAGS) test_fbgl.c -lm -o test_fbgl + +clean: + @echo "Cleaning up..." + rm -f libfbgl_preload.so fbgl_viewer test_fbgl + @# Clean up shared memory + @ipcrm -M $$(ftok /tmp F 2>/dev/null | awk '{print $$NF}') 2>/dev/null || true + +install: + @echo "Installing to /usr/local/bin..." + sudo cp libfbgl_preload.so /usr/local/lib/ + sudo cp fbgl_viewer /usr/local/bin/ + sudo cp fbgl_run.sh /usr/local/bin/fbgl-run + @echo "Done! You can now run: fbgl-run ./your_program" + +uninstall: + @echo "Uninstalling..." + sudo rm -f /usr/local/lib/libfbgl_preload.so + sudo rm -f /usr/local/bin/fbgl_viewer + sudo rm -f /usr/local/bin/fbgl-run + @echo "Done!" +``` + +## Troubleshooting + +### "Shared memory not found" error + +The viewer needs to be started before the FBGL program. Use the `fbgl_run.sh` script which handles this automatically. + +### Black screen + +Make sure your FBGL program is actually drawing to the framebuffer and not exiting immediately. + +### Viewer doesn't start + +Check that SDL2 is installed: +```bash +sudo apt-get install libsdl2-dev +``` + +### Program crashes + +Check stderr output for preload messages. Make sure your program is compiled with `-lm` for math functions. + +## Configuration + +Edit the following constants in the source files to change resolution: + +In `fbgl_preload.c` and `fbgl_viewer.c`: +```c +#define VIRTUAL_FB_WIDTH 800 +#define VIRTUAL_FB_HEIGHT 600 +``` + +Then recompile: +```bash +make clean && make +``` + +## How It Works + +1. **LD_PRELOAD** intercepts system calls (`open`, `ioctl`, `mmap`, etc.) that your FBGL program makes +2. Instead of real framebuffer device, it provides a shared memory buffer +3. The SDL viewer reads from this shared memory and displays it in a window +4. Your FBGL program thinks it's writing to `/dev/fb0`, but it's actually writing to shared memory + +## Performance + +The emulator adds minimal overhead: +- Shared memory for zero-copy data transfer +- VSync enabled in SDL for smooth rendering +- ~60 FPS typical performance + +## License + +This emulator is public domain. Use it however you want! + +## Credits + +Created for testing FBGL applications without hardware framebuffer access. diff --git a/test/Dockerfile b/test/Dockerfile deleted file mode 100644 index 31debe0..0000000 --- a/test/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ubuntu:22.04 - -# Install required packages -RUN apt-get update && apt-get install -y \ - build-essential \ - xvfb \ - imagemagick \ - && rm -rf /var/lib/apt/lists/* - -# Create app directory -WORKDIR /app - -# Copy your library and any dependencies -COPY . /app - -# Make sure binaries are executable -RUN chmod +x /app/* - -# Accept program name as argument and run with virtual framebuffer -ENTRYPOINT ["xvfb-run", "-a"]
\ No newline at end of file diff --git a/test/README.md b/test/README.md deleted file mode 100644 index 3f77c6b..0000000 --- a/test/README.md +++ /dev/null @@ -1,168 +0,0 @@ -# Framebuffer Graphics Library Testing - -This directory contains Docker-based testing setup for your Linux framebuffer graphics library. Test your programs in an isolated environment without affecting your main system. - -## Quick Start - -1. **Setup** (one-time): - ```bash - chmod +x test.sh - ./test.sh build - ``` - -2. **Run your tests**: - ```bash - ./test.sh run ./your_program - ``` - -## Prerequisites - -- Docker installed and running -- Your compiled graphics programs in this directory - -## Files - -- `Dockerfile` - Container configuration with framebuffer support -- `test.sh` - Management script for Docker operations -- Your compiled programs and library files - -## Usage - -### Build Test Environment -```bash -./test.sh build -``` -Creates the Docker image with virtual framebuffer support. - -### Run Programs -```bash -# Basic usage -./test.sh run ./my_graphics_test - -# With arguments -./test.sh run ./demo --width 800 --height 600 - -# Full path -./test.sh run /app/bin/test_suite -``` - -### Management Commands -```bash -./test.sh stop # Stop any running test -./test.sh clean # Remove container and image -./test.sh rebuild # Clean build from scratch -./test.sh shell # Interactive debugging shell -./test.sh help # Show all commands -``` - -## How It Works - -1. **Virtual Framebuffer**: Uses `xvfb` to create a virtual display -2. **Isolated Environment**: Your programs run in Ubuntu container -3. **Live Code**: Your directory is mounted, so code changes are immediate -4. **No Graphics Hardware**: No GPU drivers or display required - -## Directory Structure - -``` -your-project/ -├── Dockerfile # Container setup -├── test.sh # Test runner script -├── README.md # This file -├── your_library.so # Your graphics library -├── test_program1 # Compiled test program -├── test_program2 # Another test program -└── src/ # Source code (optional) -``` - -## Testing Workflow - -1. **Develop**: Write and compile your graphics programs -2. **Test**: Run `./test.sh run ./program_name` -3. **Debug**: Use `./test.sh shell` for interactive debugging -4. **Iterate**: Make changes and test again (no rebuild needed) - -## Troubleshooting - -### Build Issues -```bash -./test.sh rebuild # Clean rebuild -``` - -### Permission Problems -```bash -chmod +x test.sh # Make script executable -chmod +x ./your_program # Make test programs executable -``` - -### Container Won't Stop -```bash -docker kill fb-test-runner # Force stop -./test.sh clean # Clean everything -``` - -### Debug Inside Container -```bash -./test.sh shell -# Now you're inside the container -ls -la /app -./your_program --debug -exit -``` - -## Advanced Usage - -### Custom Framebuffer Size -Modify the Dockerfile to set specific display dimensions: -```dockerfile -ENV DISPLAY=:99 -ENV XVFB_RES=1920x1080x24 -``` - -### Capture Screenshots -Add to your test programs: -```bash -# Inside container -import -window root screenshot.png -``` - -### Multiple Test Runs -```bash -for test in test_*.exe; do - ./test.sh run ./$test -done -``` - -## Performance Notes - -- **Fast startup**: Containers start instantly -- **Low overhead**: Minimal resource usage -- **Quick iteration**: Code changes don't require rebuilds -- **Parallel testing**: Can run multiple containers - -## Integration with CI/CD - -Add to your build pipeline: -```yaml -# Example GitHub Actions -- name: Test Graphics Library - run: | - chmod +x test.sh - ./test.sh build - ./test.sh run ./test_suite -``` - -## Cleanup - -When done testing: -```bash -./test.sh clean # Remove everything -# Or just let Docker clean up automatically -``` - -## Tips - -- Keep your test programs in the main directory for easy access -- Use descriptive names for test programs: `test_rendering.exe`, `demo_shapes.exe` -- The container has full Ubuntu tools available for debugging -- Virtual framebuffer works with most graphics operations your library performs diff --git a/test/test.sh b/test/test.sh deleted file mode 100644 index 2eb0899..0000000 --- a/test/test.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/bash - -IMAGE_NAME="fb-test" -CONTAINER_NAME="fb-test-runner" - -show_help() { - echo "Usage: $0 <command> [program_name]" - echo "" - echo "Commands:" - echo " build Build the Docker image" - echo " run <program> Run a program in the container" - echo " stop Stop running container" - echo " clean Remove container and image" - echo " rebuild Clean and build fresh" - echo " shell Start interactive shell in container" - echo "" - echo "Examples:" - echo " $0 build" - echo " $0 run ./my_graphics_test" - echo " $0 run /app/test_program arg1 arg2" - echo " $0 stop" - echo " $0 clean" -} - -build_image() { - echo "Building Docker image..." - docker build -t $IMAGE_NAME . - if [ $? -eq 0 ]; then - echo "✓ Image built successfully" - else - echo "✗ Build failed" - exit 1 - fi -} - -run_program() { - if [ -z "$1" ]; then - echo "Error: No program specified" - echo "Usage: $0 run <program> [args...]" - exit 1 - fi - - echo "Running program: $@" - docker run --rm \ - --name $CONTAINER_NAME \ - -v $(pwd):/app \ - $IMAGE_NAME "$@" -} - -stop_container() { - echo "Stopping container..." - docker stop $CONTAINER_NAME 2>/dev/null - if [ $? -eq 0 ]; then - echo "✓ Container stopped" - else - echo "No running container found" - fi -} - -clean_all() { - echo "Cleaning up..." - - # Stop container if running - docker stop $CONTAINER_NAME 2>/dev/null - - # Remove container if exists - docker rm $CONTAINER_NAME 2>/dev/null - - # Remove image - docker rmi $IMAGE_NAME 2>/dev/null - - echo "✓ Cleanup complete" -} - -rebuild() { - echo "Rebuilding..." - clean_all - build_image -} - -start_shell() { - echo "Starting interactive shell..." - docker run --rm -it \ - --name $CONTAINER_NAME \ - -v $(pwd):/app \ - --entrypoint /bin/bash \ - $IMAGE_NAME -} - -# Main command handling -case "$1" in - "build") - build_image - ;; - "run") - shift - run_program "$@" - ;; - "stop") - stop_container - ;; - "clean") - clean_all - ;; - "rebuild") - rebuild - ;; - "shell") - start_shell - ;; - "help"|"-h"|"--help"|"") - show_help - ;; - *) - echo "Unknown command: $1" - show_help - exit 1 - ;; -esac |
