Simple Rendering Manager
SRM is a C library that simplifies the development of Linux DRM/KMS applications.
Bạn đang xem: srm simple
With SRM, you can focus on the OpenGL ES 2.0 logic of your application. For each available display, you can start a rendering thread that triggers common events lượt thích initializeGL(), paintGL(), resizeGL(), pageFlipped() and uninitializeGL().
Xem thêm: trang trí bảng tết
Xem thêm: fate/apocrypha
SRM allows you to lớn use multiple GPUs simultaneously and automatically finds the most efficient configuration. It also offers functions for creating OpenGL textures, which are automatically shared among GPUs.
Links
- 📖 C API Documentation
- 🎓 Tutorial
- 🕹️ Examples
- 📦 Downloads
- 💬 Contact
Used By
SRM is the main graphic backend used by the Louvre C++ Wayland Library, as depicted in the image below.
Features
- Multiple GPUs support
- Automatic optimal GPUs/connectors configuration
- Automatic texture sharing between GPUs
- Texture allocation from CPU buffers, DMA buffers, GBM BOs, Flink Handles, Wayland DRM buffers.
- Multi seat tư vấn (libseat can be used to lớn open DRM devices for example)
- GPU hot-plugging sự kiện listener
- Connectors hot-plugging sự kiện listener
- Hardware cursor compositing
- V-Sync
- Frame buffer damage (improves performance when DMA is not supported)
- Access to lớn renderbuffers as textures.
Tested on
- Intel GPUs (i915 driver)
- NVIDIA GPUs (Nouveau and propietary drivers)
- Mali GPUs (Lima driver)
Basic Example
#include <SRMCore.h> #include <SRMDevice.h> #include <SRMConnector.h> #include <SRMConnectorMode.h> #include <SRMListener.h> #include <SRMList.h> #include <SRMLog.h> #include <GLES2/gl2.h> #include <math.h> #include <fcntl.h> #include <unistd.h> float color = 0.f; /* Opens a DRM device */ static int openRestricted(const char *path, int flags, void *userData) { SRM_UNUSED(userData); // Here something lượt thích libseat could be used instead return open(path, flags); } /* Closes a DRM device */ static void closeRestricted(int fd, void *userData) { SRM_UNUSED(userData); close(fd); } static SRMInterface srmInterface = { .openRestricted = &openRestricted, .closeRestricted = &closeRestricted }; static void initializeGL(SRMConnector *connector, void *userData) { SRM_UNUSED(userData); /* You must not tự any drawing here as it won't make it to * the screen. */ SRMConnectorMode *mode = srmConnectorGetCurrentMode(connector); glViewport(0, 0, srmConnectorModeGetWidth(mode), srmConnectorModeGetHeight(mode)); // Schedule a repaint (this eventually calls paintGL() later, not directly) srmConnectorRepaint(connector); } static void paintGL(SRMConnector *connector, void *userData) { SRM_UNUSED(userData); glClearColor((sinf(color) + 1.f) / 2.f, (sinf(color * 0.5f) + 1.f) / 2.f, (sinf(color * 0.25f) + 1.f) / 2.f, 1.f); color += 0.01f; if (color > M_PI*4.f) color = 0.f; glClear(GL_COLOR_BUFFER_BIT); srmConnectorRepaint(connector); } static void resizeGL(SRMConnector *connector, void *userData) { /* You must not tự any drawing here as it won't make it to * the screen. * This is called when the connector changes its current mode, * mix with srmConnectorSetMode() */ // Reuse initializeGL() as it only sets the viewport initializeGL(connector, userData); } static void pageFlipped(SRMConnector *connector, void *userData) { SRM_UNUSED(connector); SRM_UNUSED(userData); /* You must not tự any drawing here as it won't make it to * the screen. * This is called when the last rendered frame is now being * displayed on screen. * Google v-sync for more info. */ } static void uninitializeGL(SRMConnector *connector, void *userData) { SRM_UNUSED(connector); SRM_UNUSED(userData); /* You must not tự any drawing here as it won't make it to * the screen. * Here you should không tính tiền any resource created on initializeGL() * lượt thích shaders, programs, textures, etc. */ } static SRMConnectorInterface connectorInterface = { .initializeGL = &initializeGL, .paintGL = &paintGL, .resizeGL = &resizeGL, .pageFlipped = &pageFlipped, .uninitializeGL = &uninitializeGL }; static void connectorPluggedEventHandler(SRMListener *listener, SRMConnector *connector) { SRM_UNUSED(listener); /* This is called when a new connector is avaliable (E.g. Plugging an HDMI display). */ /* Got a new connector, let's render on it */ if (!srmConnectorInitialize(connector, &connectorInterface, NULL)) SRMError("[srm-basic] Failed to lớn initialize connector %s.", srmConnectorGetModel(connector)); } static void connectorUnpluggedEventHandler(SRMListener *listener, SRMConnector *connector) { SRM_UNUSED(listener); SRM_UNUSED(connector); /* This is called when a connector is no longer avaliable (E.g. Unplugging an HDMI display). */ /* The connnector is automatically uninitialized after this sự kiện (if initialized) * ví calling srmConnectorUninitialize() here is not required. */ } int main(void) { SRMCore *core = srmCoreCreate(&srmInterface, NULL); if (!core) { SRMFatal("[srm-basic] Failed to lớn initialize SRM core."); return 1; } // Subscribe to lớn Udev events SRMListener *connectorPluggedEventListener = srmCoreAddConnectorPluggedEventListener(core, &connectorPluggedEventHandler, NULL); SRMListener *connectorUnpluggedEventListener = srmCoreAddConnectorUnpluggedEventListener(core, &connectorUnpluggedEventHandler, NULL); // Find and initialize avaliable connectors // Loop each GPU (device) SRMListForeach (deviceIt, srmCoreGetDevices(core)) { SRMDevice *device = srmListItemGetData(deviceIt); // Loop each GPU connector (screen) SRMListForeach (connectorIt, srmDeviceGetConnectors(device)) { SRMConnector *connector = srmListItemGetData(connectorIt); if (srmConnectorIsConnected(connector)) { if (!srmConnectorInitialize(connector, &connectorInterface, NULL)) SRMError("[srm-basic] Failed to lớn initialize connector %s.", srmConnectorGetModel(connector)); } } } while (1) { /* Udev monitor poll DRM devices/connectors hotplugging events (-1 disables timeout). * To get a pollable FD use srmCoreGetMonitorFD() */ if (srmCoreProcessMonitor(core, -1) < 0) break; } /* Unsubscribe to lớn DRM events * * These listeners are automatically destroyed when calling srmCoreDestroy() * ví there is no need to lớn không tính tiền them manually. * This is here just to lớn show how to lớn unsubscribe to lớn events on the fly. */ srmListenerDestroy(connectorPluggedEventListener); srmListenerDestroy(connectorUnpluggedEventListener); // Finish SRM srmCoreDestroy(core); return 0; }
Bình luận