Renderer Plugin Collection¶
Description¶
The Renderer plugin collection provides comprehensive cross-platform rendering and visualization capabilities for CVEDIA-RT. It enables video output, user interface rendering, and remote visualization across different graphics APIs and windowing systems, supporting diverse deployment scenarios from high-performance workstations to headless servers.
Key Features¶
- Multi-Graphics API Support: DirectX 11, OpenGL 3.0+, and OpenGL ES 2.0 compatibility
- Cross-Platform Rendering: Windows, Linux, macOS, and mobile platform support
- Remote Visualization: Network-based remote UI streaming via NetImgui protocol
- ImGui Integration: Complete Dear ImGui support with docking and multi-viewport capabilities
- Hardware Acceleration: GPU-accelerated rendering with automatic fallback to software
- Multi-Monitor Support: Native multi-display configurations with DPI awareness
- Performance Optimization: Efficient texture streaming and memory management
Use Cases¶
- Interactive Applications: Real-time video processing with GUI controls
- Remote Monitoring: Headless server deployments with remote visualization
- Multi-Display Setups: Security monitoring across multiple screens
- Cross-Platform Deployment: Consistent rendering across different operating systems
- Embedded Systems: Lightweight rendering for edge computing devices
Renderer Implementations¶
DirectX 11 Renderer¶
Platform: Windows only
Graphics API: DirectX 11.0+
Performance: High-performance GPU acceleration
Features: - Native Windows integration with Win32 API - Hardware-accelerated rendering via ID3D11Device - Multi-monitor support through DirectX display management - DPI awareness with automatic scaling - Efficient texture streaming via DirectX surfaces
GLFW Renderer¶
Platform: Windows, Linux, macOS
Graphics API: OpenGL 3.0+ / OpenGL ES 2.0
Performance: Cross-platform hardware acceleration
Features: - Modern OpenGL rendering pipeline - Cross-platform windowing and input handling - Automatic OpenGL version detection and context creation - macOS Core Profile support (OpenGL 3.2 + GLSL 150) - Platform-optimized OpenGL configurations
Remote Renderer¶
Platform: Multi-platform
Protocol: NetImgui network streaming
Performance: Bandwidth-optimized remote visualization
Features: - Network-based client-server architecture - UDP broadcast discovery for automatic client detection - TCP streaming with configurable compression - Texture downscaling and grayscale conversion for optimization - Multi-client support with headless operation
SDL Renderer¶
Platform: Windows, Linux, macOS, mobile
Graphics API: OpenGL via SDL2
Performance: Universal compatibility with hardware acceleration
Features: - Comprehensive multimedia support via SDL2 - Mobile platform compatibility - Per-monitor DPI awareness (SDL 2.0.4+) - Cross-platform input handling (keyboard, mouse, gamepad) - Embedded system support
Requirements¶
Hardware Requirements¶
DirectX 11 Renderer: - DirectX 11.0 compatible GPU - Windows Display Driver Model (WDDM) drivers - 512MB+ VRAM recommended
OpenGL Renderers (GLFW/SDL): - OpenGL 3.0+ capable GPU or software fallback - Graphics drivers with OpenGL support - 256MB+ VRAM recommended
Remote Renderer: - Network interface (Ethernet/Wi-Fi) - Minimal local graphics requirements - Bandwidth: 1Mbps+ for optimal experience
Software Dependencies¶
Windows Dependencies:
# DirectX 11
d3d11.lib, dxgi.lib
Windows SDK 10.0+
# GLFW
glfw3.lib, opengl32.lib
Windows graphics drivers
# SDL
SDL2.lib, SDL2main.lib
OpenGL drivers
Linux Dependencies:
# GLFW
sudo apt-get install libglfw3-dev libgl1-mesa-dev
# SDL
sudo apt-get install libsdl2-dev
# Remote
Standard networking libraries
macOS Dependencies:
# GLFW
brew install glfw
# SDL
brew install sdl2
# System Frameworks
OpenGL.framework, Cocoa.framework
Configuration¶
Basic Renderer Configuration¶
{
"renderer": {
"type": "dx11",
"window": {
"title": "CVEDIA-RT",
"width": 1920,
"height": 1080,
"fullscreen": false,
"vsync": true
},
"performance": {
"hardwareAcceleration": true,
"textureStreaming": true,
"memoryOptimization": true
}
}
}
Remote Renderer Configuration¶
{
"renderer": {
"type": "remote",
"network": {
"clientPort": 8889,
"broadcastPort": 49888,
"enableBroadcast": true,
"serverName": "CVEDIA-RT Server"
},
"optimization": {
"textureUpdateDelay": 250,
"downscaleFactor": 4,
"maxTextureDimension": 768,
"grayscaleTextures": false,
"compressionEnabled": true
},
"quality": {
"targetFps": 30,
"bandwidthLimit": "10Mbps",
"adaptiveQuality": true
}
}
}
Multi-Monitor Configuration¶
{
"renderer": {
"type": "dx11",
"displays": {
"primary": {
"monitor": 0,
"resolution": [1920, 1080],
"refreshRate": 60,
"dpiScaling": "auto"
},
"secondary": {
"monitor": 1,
"resolution": [1920, 1080],
"refreshRate": 60,
"extendedDesktop": true
}
}
}
}
Configuration Schema¶
Parameter | Type | Default | Description |
---|---|---|---|
type |
string | "auto" | Renderer type (dx11, glfw, sdl, remote) |
window.title |
string | "CVEDIA-RT" | Window title text |
window.width |
integer | 1920 | Initial window width |
window.height |
integer | 1080 | Initial window height |
window.fullscreen |
boolean | false | Start in fullscreen mode |
window.vsync |
boolean | true | Enable vertical synchronization |
performance.hardwareAcceleration |
boolean | true | Enable GPU acceleration |
performance.textureStreaming |
boolean | true | Enable optimized texture streaming |
network.clientPort |
integer | 8889 | Remote renderer client port |
network.broadcastPort |
integer | 49888 | UDP broadcast discovery port |
network.enableBroadcast |
boolean | true | Enable automatic server discovery |
optimization.textureUpdateDelay |
integer | 250 | Milliseconds between texture updates |
optimization.downscaleFactor |
integer | 4 | Texture downscaling ratio for bandwidth |
optimization.maxTextureDimension |
integer | 768 | Maximum texture size for streaming |
optimization.grayscaleTextures |
boolean | false | Convert textures to grayscale |
quality.targetFps |
integer | 30 | Target frames per second |
quality.bandwidthLimit |
string | "10Mbps" | Network bandwidth limit |
quality.adaptiveQuality |
boolean | true | Automatically adjust quality for bandwidth |
API Reference¶
Core Renderer Interface¶
All renderers implement the unified iface::Renderer
interface:
namespace cvedia::rt::iface {
class Renderer {
public:
// Context management
virtual void setCurrentContext(ImGuiContext* ctx) = 0;
virtual ImGuiContext* getCurrentContext() = 0;
virtual void setAllocatorFunctions(ImGuiMemAllocFunc alloc_func,
ImGuiMemFreeFunc free_func,
void* user_data) = 0;
// Texture operations
virtual void* matToTexture(cv::Mat img) = 0;
virtual void* matToTexture(std::string const& name, cv::Mat img, bool update) = 0;
// Window lifecycle
virtual void createWindow(std::string const& windowTitle,
int windowWidth, int windowHeight) = 0;
virtual bool messageLoop() = 0;
virtual bool startFrame() = 0;
virtual void endFrame() = 0;
virtual void cleanup() = 0;
// Display management
virtual std::vector<DisplayInfo> getAvailableDisplays() const = 0;
virtual expected<void> setDisplayConfiguration(const DisplayConfig& config) = 0;
virtual bool supportsMultiViewport() const = 0;
};
}
Renderer Factory¶
namespace cvedia::rt::api::factory {
class Renderer {
public:
static std::unique_ptr<iface::Renderer> create(const std::string& type = "auto");
static std::vector<std::string> getAvailableRenderers();
static bool isRendererAvailable(const std::string& type);
// Registration for plugin system
static void registerImplementation(const std::string& name,
std::function<std::unique_ptr<iface::Renderer>()> factory);
};
}
ImGui Integration API¶
namespace cvedia::rt::ui {
// Texture management
class TextureManager {
public:
static void* uploadTexture(const cv::Mat& image);
static void* updateTexture(void* textureId, const cv::Mat& image);
static void releaseTexture(void* textureId);
static cv::Size getTextureSize(void* textureId);
};
// Window management
class WindowManager {
public:
static expected<void> createWindow(const std::string& title,
int width, int height);
static expected<void> setWindowPosition(int x, int y);
static expected<void> setWindowSize(int width, int height);
static bool isWindowMinimized();
static void setWindowIcon(const cv::Mat& icon);
};
}
Remote Renderer Network API¶
namespace cvedia::rt::network {
class RemoteRenderer {
public:
// Server management
expected<void> startServer(int port = 8889);
expected<void> stopServer();
bool isServerRunning() const;
// Client management
std::vector<ClientInfo> getConnectedClients() const;
expected<void> disconnectClient(const std::string& clientId);
// Broadcasting
expected<void> enableBroadcast(int port = 49888);
expected<void> disableBroadcast();
// Quality control
void setCompressionLevel(int level); // 0-9
void setTextureQuality(float quality); // 0.0-1.0
void enableAdaptiveQuality(bool enable);
// Statistics
NetworkStats getNetworkStatistics() const;
BandwidthInfo getBandwidthUsage() const;
};
}
Examples¶
Basic Renderer Setup¶
#include "api/factory/renderer.h"
#include "interface/renderer.h"
// Create renderer with automatic selection
auto renderer = api::factory::Renderer::create();
if (!renderer) {
PLOG_ERROR << "Failed to create renderer";
return -1;
}
// Initialize window
renderer->createWindow("CVEDIA-RT Application", 1920, 1080);
// Main render loop
while (renderer->messageLoop()) {
if (!renderer->startFrame()) {
continue;
}
// ImGui rendering
ImGui::Begin("Main Window");
ImGui::Text("Hello, CVEDIA-RT!");
ImGui::End();
// Upload and display texture
cv::Mat frame = getVideoFrame();
void* textureId = renderer->matToTexture(frame);
ImGui::Begin("Video Display");
ImGui::Image(textureId, ImVec2(640, 480));
ImGui::End();
renderer->endFrame();
}
// Cleanup
renderer->cleanup();
Platform-Specific Renderer Creation¶
// Create DirectX 11 renderer for Windows
#ifdef _WIN32
auto dx11Renderer = api::factory::Renderer::create("dx11");
if (dx11Renderer) {
PLOG_INFO << "Using DirectX 11 renderer";
}
#endif
// Create GLFW renderer for cross-platform
auto glfwRenderer = api::factory::Renderer::create("glfw");
if (glfwRenderer) {
PLOG_INFO << "Using GLFW OpenGL renderer";
}
// Create SDL renderer for maximum compatibility
auto sdlRenderer = api::factory::Renderer::create("sdl");
if (sdlRenderer) {
PLOG_INFO << "Using SDL renderer";
}
Remote Renderer Server Setup¶
#include "renderer/remote/remote_renderer.h"
// Create and configure remote renderer
auto remoteRenderer = std::make_unique<RemoteRenderer>();
// Configure network settings
remoteRenderer->setClientPort(8889);
remoteRenderer->setBroadcastPort(49888);
remoteRenderer->enableBroadcast(true);
// Configure optimization
remoteRenderer->setTextureUpdateDelay(250);
remoteRenderer->setDownscaleFactor(4);
remoteRenderer->setMaxTextureDimension(768);
remoteRenderer->enableGrayscaleTextures(false);
// Start server
if (auto result = remoteRenderer->startServer(); !result) {
PLOG_ERROR << "Failed to start remote renderer server: " << result.error();
return -1;
}
PLOG_INFO << "Remote renderer server started on port 8889";
// Main application loop
while (applicationRunning) {
if (remoteRenderer->hasConnectedClients()) {
// Process UI when clients are connected
if (remoteRenderer->startFrame()) {
renderUserInterface();
remoteRenderer->endFrame();
}
}
// Monitor client connections
auto clients = remoteRenderer->getConnectedClients();
for (const auto& client : clients) {
PLOG_INFO << "Client connected: " << client.address << ":" << client.port;
}
std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60 FPS
}
// Cleanup
remoteRenderer->stopServer();
Multi-Monitor Display Setup¶
#include "renderer/display_manager.h"
// Enumerate available displays
auto displays = renderer->getAvailableDisplays();
PLOG_INFO << "Found " << displays.size() << " displays";
for (const auto& display : displays) {
PLOG_INFO << "Display " << display.id << ": "
<< display.width << "x" << display.height
<< " @ " << display.refreshRate << "Hz"
<< " (DPI: " << display.dpi << ")";
}
// Configure primary display
DisplayConfig primaryConfig;
primaryConfig.displayId = 0;
primaryConfig.resolution = {1920, 1080};
primaryConfig.refreshRate = 60;
primaryConfig.primary = true;
// Configure secondary display
DisplayConfig secondaryConfig;
secondaryConfig.displayId = 1;
secondaryConfig.resolution = {1920, 1080};
secondaryConfig.refreshRate = 60;
secondaryConfig.position = {1920, 0}; // Extended desktop
secondaryConfig.primary = false;
// Apply display configuration
if (auto result = renderer->setDisplayConfiguration(primaryConfig); !result) {
PLOG_ERROR << "Failed to configure primary display";
}
if (auto result = renderer->setDisplayConfiguration(secondaryConfig); !result) {
PLOG_ERROR << "Failed to configure secondary display";
}
Texture Streaming Optimization¶
#include "renderer/texture_streamer.h"
class OptimizedTextureStreamer {
public:
OptimizedTextureStreamer(iface::Renderer* renderer) : renderer_(renderer) {
// Initialize texture cache
textureCache_.reserve(100);
}
void* streamTexture(const std::string& name, const cv::Mat& image, bool forceUpdate = false) {
auto it = textureCache_.find(name);
if (it != textureCache_.end() && !forceUpdate) {
// Use cached texture
return it->second.textureId;
}
// Optimize image for streaming
cv::Mat optimized = optimizeImageForStreaming(image);
// Upload or update texture
void* textureId;
if (it != textureCache_.end()) {
textureId = renderer_->matToTexture(name, optimized, true);
} else {
textureId = renderer_->matToTexture(optimized);
TextureInfo info;
info.textureId = textureId;
info.lastUpdate = std::chrono::steady_clock::now();
info.size = optimized.size();
textureCache_[name] = info;
}
return textureId;
}
private:
cv::Mat optimizeImageForStreaming(const cv::Mat& input) {
cv::Mat output;
// Resize if too large
if (input.cols > maxDimension_ || input.rows > maxDimension_) {
double scale = static_cast<double>(maxDimension_) /
std::max(input.cols, input.rows);
cv::resize(input, output, cv::Size(), scale, scale, cv::INTER_LINEAR);
} else {
output = input;
}
// Convert to grayscale if enabled
if (grayscaleMode_ && output.channels() == 3) {
cv::cvtColor(output, output, cv::COLOR_BGR2GRAY);
}
return output;
}
struct TextureInfo {
void* textureId;
std::chrono::steady_clock::time_point lastUpdate;
cv::Size size;
};
iface::Renderer* renderer_;
std::unordered_map<std::string, TextureInfo> textureCache_;
int maxDimension_ = 1024;
bool grayscaleMode_ = false;
};
Performance Monitoring¶
#include "renderer/performance_monitor.h"
class RendererPerformanceMonitor {
public:
void recordFrameTime(std::chrono::milliseconds frameTime) {
frameTimes_.push_back(frameTime);
if (frameTimes_.size() > 100) {
frameTimes_.erase(frameTimes_.begin());
}
}
void recordTextureUpload(size_t textureSize, std::chrono::milliseconds uploadTime) {
textureUploads_.push_back({textureSize, uploadTime});
if (textureUploads_.size() > 50) {
textureUploads_.erase(textureUploads_.begin());
}
}
double getAverageFps() const {
if (frameTimes_.empty()) return 0.0;
auto totalTime = std::accumulate(frameTimes_.begin(), frameTimes_.end(),
std::chrono::milliseconds{0});
double avgTime = totalTime.count() / static_cast<double>(frameTimes_.size());
return avgTime > 0.0 ? 1000.0 / avgTime : 0.0;
}
double getTextureUploadRate() const {
if (textureUploads_.empty()) return 0.0;
size_t totalSize = 0;
auto totalTime = std::chrono::milliseconds{0};
for (const auto& upload : textureUploads_) {
totalSize += upload.size;
totalTime += upload.time;
}
double avgTime = totalTime.count() / static_cast<double>(textureUploads_.size());
double avgSize = totalSize / static_cast<double>(textureUploads_.size());
return avgTime > 0.0 ? (avgSize / 1024.0) / (avgTime / 1000.0) : 0.0; // KB/s
}
void printStatistics() const {
PLOG_INFO << "Renderer Performance Statistics:";
PLOG_INFO << " Average FPS: " << std::fixed << std::setprecision(1) << getAverageFps();
PLOG_INFO << " Texture Upload Rate: " << std::fixed << std::setprecision(2)
<< getTextureUploadRate() << " KB/s";
}
private:
struct TextureUpload {
size_t size;
std::chrono::milliseconds time;
};
std::vector<std::chrono::milliseconds> frameTimes_;
std::vector<TextureUpload> textureUploads_;
};
Platform Compatibility¶
Graphics API Support Matrix¶
Platform | DirectX 11 | OpenGL 3.0+ | OpenGL ES 2.0 | Remote |
---|---|---|---|---|
Windows | ✅ Native | ✅ GLFW/SDL | ✅ SDL | ✅ Network |
Linux | ❌ N/A | ✅ GLFW/SDL | ✅ SDL | ✅ Network |
macOS | ❌ N/A | ✅ GLFW/SDL | ❌ N/A | ✅ Network |
Mobile | ❌ N/A | ❌ N/A | ✅ SDL | ✅ Network |
Embedded | ❌ N/A | ⚠️ Limited | ✅ SDL | ✅ Network |
Hardware Acceleration Support¶
Feature | DX11 | GLFW | SDL | Remote |
---|---|---|---|---|
GPU Acceleration | ✅ Full | ✅ Full | ✅ Full | ⚠️ Server-side |
Multi-GPU | ✅ Yes | ⚠️ Limited | ⚠️ Limited | ❌ N/A |
Zero-Copy | ✅ DirectX | ⚠️ OpenGL | ⚠️ OpenGL | ❌ N/A |
Hardware Decode | ✅ Yes | ✅ Yes | ✅ Yes | ⚠️ Server-side |
Performance Optimization¶
Texture Management Optimization¶
// Efficient texture streaming
class TextureStreamOptimizer {
public:
struct OptimizationSettings {
int maxTextureDimension = 1024;
float compressionRatio = 0.8f;
bool enableCaching = true;
bool enableDownscaling = true;
int cacheSize = 100;
};
void* optimizeAndUploadTexture(iface::Renderer* renderer,
const cv::Mat& image,
const OptimizationSettings& settings) {
cv::Mat optimized = image;
// Apply optimizations
if (settings.enableDownscaling) {
optimized = downscaleTexture(optimized, settings.maxTextureDimension);
}
if (settings.compressionRatio < 1.0f) {
optimized = compressTexture(optimized, settings.compressionRatio);
}
// Upload to GPU
return renderer->matToTexture(optimized);
}
private:
cv::Mat downscaleTexture(const cv::Mat& input, int maxDimension) {
if (input.cols <= maxDimension && input.rows <= maxDimension) {
return input;
}
double scale = static_cast<double>(maxDimension) / std::max(input.cols, input.rows);
cv::Mat output;
cv::resize(input, output, cv::Size(), scale, scale, cv::INTER_LINEAR);
return output;
}
cv::Mat compressTexture(const cv::Mat& input, float ratio) {
std::vector<int> compression_params;
compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
compression_params.push_back(static_cast<int>(ratio * 100));
std::vector<uchar> compressed;
cv::imencode(".jpg", input, compressed, compression_params);
return cv::imdecode(compressed, cv::IMREAD_COLOR);
}
};
Memory Management¶
// GPU memory pool for texture management
class GPUMemoryPool {
public:
GPUMemoryPool(size_t poolSize) : poolSize_(poolSize) {
// Pre-allocate texture slots
texturePool_.reserve(poolSize);
}
void* allocateTexture(const cv::Size& size, int channels) {
std::lock_guard<std::mutex> lock(poolMutex_);
// Try to find existing texture of same size
for (auto& slot : texturePool_) {
if (!slot.inUse && slot.size == size && slot.channels == channels) {
slot.inUse = true;
return slot.textureId;
}
}
// Create new texture if pool not full
if (texturePool_.size() < poolSize_) {
TextureSlot slot;
slot.textureId = createNewTexture(size, channels);
slot.size = size;
slot.channels = channels;
slot.inUse = true;
texturePool_.push_back(slot);
return slot.textureId;
}
// Pool is full, return null
return nullptr;
}
void releaseTexture(void* textureId) {
std::lock_guard<std::mutex> lock(poolMutex_);
for (auto& slot : texturePool_) {
if (slot.textureId == textureId && slot.inUse) {
slot.inUse = false;
break;
}
}
}
private:
struct TextureSlot {
void* textureId;
cv::Size size;
int channels;
bool inUse = false;
};
std::vector<TextureSlot> texturePool_;
std::mutex poolMutex_;
size_t poolSize_;
void* createNewTexture(const cv::Size& size, int channels) {
// Platform-specific texture creation
// Implementation depends on graphics API
return nullptr; // Placeholder
}
};
Troubleshooting¶
Common Issues¶
Graphics Driver Issues
// Check graphics driver compatibility
class GraphicsDriverChecker {
public:
static bool checkDirectXSupport() {
#ifdef _WIN32
// Check DirectX 11 support
ID3D11Device* device = nullptr;
HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE,
nullptr, 0, nullptr, 0,
D3D11_SDK_VERSION, &device, nullptr, nullptr);
if (device) {
device->Release();
return SUCCEEDED(hr);
}
return false;
#else
return false;
#endif
}
static bool checkOpenGLSupport() {
// Create minimal OpenGL context to check support
glfwInit();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
GLFWwindow* window = glfwCreateWindow(1, 1, "Test", nullptr, nullptr);
if (!window) {
glfwTerminate();
return false;
}
glfwMakeContextCurrent(window);
const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
bool supported = version != nullptr;
glfwDestroyWindow(window);
glfwTerminate();
return supported;
}
};
Memory Leak Prevention
// RAII wrapper for renderer resources
class RendererResourceManager {
public:
RendererResourceManager(std::unique_ptr<iface::Renderer> renderer)
: renderer_(std::move(renderer)) {}
~RendererResourceManager() {
// Cleanup all textures
for (auto textureId : allocatedTextures_) {
// Platform-specific texture cleanup
cleanupTexture(textureId);
}
// Cleanup renderer
if (renderer_) {
renderer_->cleanup();
}
}
void* createTexture(const cv::Mat& image) {
void* textureId = renderer_->matToTexture(image);
if (textureId) {
allocatedTextures_.insert(textureId);
}
return textureId;
}
void releaseTexture(void* textureId) {
if (allocatedTextures_.erase(textureId) > 0) {
cleanupTexture(textureId);
}
}
private:
std::unique_ptr<iface::Renderer> renderer_;
std::unordered_set<void*> allocatedTextures_;
void cleanupTexture(void* textureId) {
// Platform-specific cleanup implementation
}
};
Network Issues (Remote Renderer)
// Network diagnostics for remote renderer
class NetworkDiagnostics {
public:
static bool testNetworkConnectivity(const std::string& host, int port) {
try {
// Test TCP connection
asio::io_context io_context;
tcp::socket socket(io_context);
tcp::resolver resolver(io_context);
auto endpoints = resolver.resolve(host, std::to_string(port));
asio::connect(socket, endpoints);
socket.close();
return true;
} catch (const std::exception& e) {
PLOG_ERROR << "Network connectivity test failed: " << e.what();
return false;
}
}
static double measureLatency(const std::string& host, int port) {
auto start = std::chrono::high_resolution_clock::now();
bool connected = testNetworkConnectivity(host, port);
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
return connected ? duration.count() / 1000.0 : -1.0; // ms
}
static double measureBandwidth(const std::string& host, int port, size_t testDataSize = 1024 * 1024) {
// Implementation for bandwidth measurement
// Send test data and measure transfer rate
return 0.0; // Placeholder
}
};
Error Recovery¶
// Robust renderer with automatic recovery
class RobustRenderer {
public:
RobustRenderer() {
initializeRenderer();
}
bool renderFrame() {
if (!renderer_) {
if (!initializeRenderer()) {
return false;
}
}
try {
if (!renderer_->startFrame()) {
handleRenderError();
return false;
}
// Render UI here
renderUserInterface();
renderer_->endFrame();
errorCount_ = 0; // Reset error counter on success
return true;
} catch (const std::exception& e) {
PLOG_ERROR << "Render error: " << e.what();
handleRenderError();
return false;
}
}
private:
std::unique_ptr<iface::Renderer> renderer_;
int errorCount_ = 0;
static const int maxErrors_ = 5;
bool initializeRenderer() {
// Try different renderer types in order of preference
std::vector<std::string> rendererTypes = {"dx11", "glfw", "sdl", "remote"};
for (const auto& type : rendererTypes) {
try {
renderer_ = api::factory::Renderer::create(type);
if (renderer_) {
renderer_->createWindow("CVEDIA-RT", 1920, 1080);
PLOG_INFO << "Successfully initialized " << type << " renderer";
return true;
}
} catch (const std::exception& e) {
PLOG_WARNING << "Failed to initialize " << type << " renderer: " << e.what();
}
}
PLOG_ERROR << "Failed to initialize any renderer";
return false;
}
void handleRenderError() {
errorCount_++;
if (errorCount_ >= maxErrors_) {
PLOG_ERROR << "Too many render errors, reinitializing renderer";
renderer_.reset();
errorCount_ = 0;
}
}
void renderUserInterface() {
// Application-specific UI rendering
ImGui::Begin("Status");
ImGui::Text("Renderer: %s", renderer_ ? "Active" : "Inactive");
ImGui::Text("Error Count: %d", errorCount_);
ImGui::End();
}
};
Best Practices¶
Renderer Selection Strategy¶
- Platform Optimization: Use DirectX 11 on Windows for best performance, OpenGL on other platforms
- Fallback Chain: Implement automatic fallback from hardware to software rendering
- Resource Management: Use RAII patterns for automatic resource cleanup
- Error Handling: Implement comprehensive error handling with recovery mechanisms
Performance Guidelines¶
- Texture Management: Use texture caching and pooling for frequently updated images
- Memory Optimization: Monitor GPU memory usage and implement cleanup strategies
- Frame Rate Management: Implement VSync and frame rate limiting to prevent resource waste
- Network Optimization: Use compression and quality adaptation for remote rendering
Integration Best Practices¶
- Factory Pattern: Use the renderer factory for consistent renderer creation
- Configuration Management: Centralize renderer configuration through CVEDIA-RT config system
- Thread Safety: Ensure thread-safe access to renderer resources
- Testing: Validate renderer functionality across different hardware configurations