Skip to content

Commit 36e2b8d

Browse files
author
msieben
committed
[libdrm-examples]: Add a unprivileged 'drm-prime' example.
- Updated 'drm-prime-tile' to scan out only valid buffers. - 'drm-prime-unpriv' uses both the priviliged mode setting and unprivileged render nodes.
1 parent cf30005 commit 36e2b8d

File tree

4 files changed

+1380
-81
lines changed

4 files changed

+1380
-81
lines changed

package/libdrm-examples/libdrm-examples.mk

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,16 @@ $(MAKE) -f $(@D)/Makefile CC="$(TARGET_CROSS)cc" CXX="$(TARGET_CROSS)c++" CPPFLA
5656
popd;
5757
endef
5858

59+
define LIBDRM_EXAMPLES_BUILD_DRM_PRIME_UNPRIV
60+
pushd $(@D); \
61+
$(MAKE) -f $(@D)/Makefile CC="$(TARGET_CROSS)cc" CXX="$(TARGET_CROSS)c++" CPPFLAGS="$(LIBDRM_EXAMPLES_CPPFLAGS)" CFLAGS="$(LIBDRM_EXAMPLES_CFLAGS)" CXXFLAGS="$(LIBDRM_EXAMPLES_CXXFLAGS)" LDFLAGS="$(LIBDRM_EXAMPLES_LDFLAGS)" drm-prime-unpriv; \
62+
popd;
63+
endef
5964

6065
define LIBDRM_EXAMPLES_BUILD_CMDS
6166
$(call LIBDRM_EXAMPLES_BUILD_DRM_PRIME_SIMPLE)
6267
$(call LIBDRM_EXAMPLES_BUILD_DRM_PRIME_TILE)
68+
$(call LIBDRM_EXAMPLES_BUILD_DRM_PRIME_UNPRIV)
6369
endef
6470

6571
define LIBDRM_EXAMPLES_INSTALL_STAGING_CMDS
@@ -68,6 +74,8 @@ endef
6874

6975
define LIBDRM_EXAMPLES_INSTALL_TARGET_CMDS
7076
[ -f $(@D)/.bin/drm-prime-simple ] && $(INSTALL) -D -m 755 $(@D)/.bin/drm-prime-simple $(TARGET_DIR)/usr/bin/drm-prime-simple
77+
[ -f $(@D)/.bin/drm-prime-tile ] && $(INSTALL) -D -m 755 $(@D)/.bin/drm-prime-tile $(TARGET_DIR)/usr/bin/drm-prime-tle
78+
[ -f $(@D)/.bin/drm-prime-unpriv ] && $(INSTALL) -D -m 755 $(@D)/.bin/drm-prime-unpriv $(TARGET_DIR)/usr/bin/drm-prime-unpriv
7179
endef
7280

7381
$(eval $(generic-package))

package/libdrm-examples/src/Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ rebuild = touch $(sources);
6868

6969
# The main target(s)
7070
all:
71-
$(error "Specify drm-prime-simple or drm-prime-tile as target")
71+
$(error "Specify drm-prime-simple, drm-prime-tile or drm-prime-unpriv as target")
7272

7373
#https://www.gnu.org/software/make/manual/make.html#Target_002dspecific
7474
drm-prime-simple: EXTRA_FLAGS=-DNO_FLAGS
7575

7676
drm-prime-tile: EXTRA_FLAGS=-DNO_FLAGS
7777

78+
drm-prime-unpriv: EXTRA_FLAGS=-DNO_FLAGS
79+
7880
# Generate the binaries
7981
drm-prime-simple: $(objects) | $(bindir)
8082

@@ -84,6 +86,10 @@ drm-prime-tile: $(objects) | $(bindir)
8486

8587
$(call build)
8688

89+
drm-prime-unpriv: $(objects) | $(bindir)
90+
91+
$(call build)
92+
8793
# Create all object files
8894
$(objdir)/%.o: %.cpp | $(objdir)
8995

package/libdrm-examples/src/drm-prime-tile.cpp

Lines changed: 84 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ There is much room for improvement!
4141
#include <type_traits>
4242
#include <atomic>
4343
#include <array>
44+
#include <algorithm>
4445

4546
#ifdef __cplusplus
4647
extern "C" {
@@ -208,98 +209,101 @@ static auto FindModeSet (struct configuration& settings) -> uint32_t {
208209
static auto ScanOut (struct configuration settings) -> bool {
209210
bool _ret = false;
210211

211-
uint32_t _width = gbm_bo_get_width (settings.gbm.bo);
212-
uint32_t _height = gbm_bo_get_height (settings.gbm.bo);
213-
uint32_t _format = gbm_bo_get_format (settings.gbm.bo);
214-
uint32_t _bpp = gbm_bo_get_bpp (settings.gbm.bo);
215-
uint32_t _handle = gbm_bo_get_handle (settings.gbm.bo).u32;
216-
uint32_t _stride = gbm_bo_get_stride (settings.gbm.bo);
212+
if (settings.gbm.bo != InvalidGBMbo ()) {
217213

218-
if (settings.drm.fb != InvalidDRMfb ()) {
219-
/* void */ drmModeRmFB (settings.drm.fd, settings.drm.fb);
220-
settings.drm.fb = InvalidDRMfb ();
221-
}
214+
uint32_t _width = gbm_bo_get_width (settings.gbm.bo);
215+
uint32_t _height = gbm_bo_get_height (settings.gbm.bo);
216+
uint32_t _format = gbm_bo_get_format (settings.gbm.bo);
217+
uint32_t _bpp = gbm_bo_get_bpp (settings.gbm.bo);
218+
uint32_t _handle = gbm_bo_get_handle (settings.gbm.bo).u32;
219+
uint32_t _stride = gbm_bo_get_stride (settings.gbm.bo);
222220

223-
if (drmModeAddFB (settings.drm.fd, _width, _height, _format != ColorFormat () ? _bpp - 8 : _bpp, _bpp, _stride, _handle, &settings.drm.fb) == 0) {
224-
static std::atomic <bool> _callback_data (true);
221+
if (settings.drm.fb != InvalidDRMfb ()) {
222+
/* void */ drmModeRmFB (settings.drm.fd, settings.drm.fb);
223+
settings.drm.fb = InvalidDRMfb ();
224+
}
225225

226-
int _err = drmModePageFlip (settings.drm.fd, settings.drm.crtc, settings.drm.fb, DRM_MODE_PAGE_FLIP_EVENT, &_callback_data);
226+
if (drmModeAddFB (settings.drm.fd, _width, _height, _format != ColorFormat () ? _bpp - 8 : _bpp, _bpp, _stride, _handle, &settings.drm.fb) == 0) {
227+
static std::atomic <bool> _callback_data (true);
227228

228-
switch (0 - _err) {
229-
case 0 : {
230-
// Strictly speaking c++ linkage and not C linkage
231-
auto handler = +[] (int fd, unsigned int frame, unsigned int sec, unsigned int usec, void* data) {
232-
if (data != nullptr) {
233-
decltype (_callback_data) * _data = reinterpret_cast <decltype (_callback_data) *> (data);
234-
*_data = false;
235-
}
236-
else {
237-
std::cout << "Error: invalid callback data" << std::endl;
238-
}
239-
};
229+
int _err = drmModePageFlip (settings.drm.fd, settings.drm.crtc, settings.drm.fb, DRM_MODE_PAGE_FLIP_EVENT, &_callback_data);
240230

241-
// Use the magic constant here because the struct is versioned!
242-
drmEventContext _context = { .version = 2, . vblank_handler = nullptr, .page_flip_handler = handler };
231+
switch (0 - _err) {
232+
case 0 : {
233+
// Strictly speaking c++ linkage and not C linkage
234+
auto handler = +[] (int fd, unsigned int frame, unsigned int sec, unsigned int usec, void* data) {
235+
if (data != nullptr) {
236+
decltype (_callback_data) * _data = reinterpret_cast <decltype (_callback_data) *> (data);
237+
*_data = false;
238+
}
239+
else {
240+
std::cout << "Error: invalid callback data" << std::endl;
241+
}
242+
};
243243

244-
bool _waiting = _callback_data;
244+
// Use the magic constant here because the struct is versioned!
245+
drmEventContext _context = { .version = 2, . vblank_handler = nullptr, .page_flip_handler = handler };
245246

246-
fd_set _fds;
247+
bool _waiting = _callback_data;
247248

248-
struct timespec _timeout = { .tv_sec = FrameDurationMax (), .tv_nsec = 0 };
249+
fd_set _fds;
249250

250-
while (_waiting != false) {
251-
FD_ZERO (&_fds);
252-
FD_SET (settings.drm.fd, &_fds);
251+
struct timespec _timeout = { .tv_sec = FrameDurationMax (), .tv_nsec = 0 };
253252

254-
_err = pselect (settings.drm.fd + 1, &_fds, nullptr, nullptr, &_timeout, nullptr);
253+
while (_waiting != false) {
254+
FD_ZERO (&_fds);
255+
FD_SET (settings.drm.fd, &_fds);
255256

256-
if (_err < 0) {
257-
break;
258-
}
259-
else {
260-
if (_err == 0) {
261-
// Timeout; retry
257+
_err = pselect (settings.drm.fd + 1, &_fds, nullptr, nullptr, &_timeout, nullptr);
258+
259+
if (_err < 0) {
260+
break;
262261
}
263-
else { // ret > 0
264-
if (FD_ISSET (settings.drm.fd, &_fds) != 0) {
265-
if (drmHandleEvent (settings.drm.fd, &_context) != 0) {
266-
_ret = false;
267-
break;
262+
else {
263+
if (_err == 0) {
264+
// Timeout; retry
265+
}
266+
else { // ret > 0
267+
if (FD_ISSET (settings.drm.fd, &_fds) != 0) {
268+
if (drmHandleEvent (settings.drm.fd, &_context) != 0) {
269+
_ret = false;
270+
break;
271+
}
272+
273+
_ret = true;
268274
}
269-
270-
_ret = true;
271275
}
272276
}
277+
278+
_waiting = _callback_data;
273279
}
274280

275-
_waiting = _callback_data;
281+
break;
276282
}
283+
case EINVAL :
284+
{ // Probably a missing drmModeSetCrtc or an invalid _crtc
285+
drmModeCrtcPtr _ptr = drmModeGetCrtc (settings.drm.fd, settings.drm.crtc);
277286

278-
break;
279-
}
280-
case EINVAL :
281-
{ // Probably a missing drmModeSetCrtc or an invalid _crtc
282-
drmModeCrtcPtr _ptr = drmModeGetCrtc (settings.drm.fd, settings.drm.crtc);
287+
if (_ptr != nullptr) {
288+
constexpr uint32_t _count = 1;
283289

284-
if (_ptr != nullptr) {
285-
constexpr uint32_t _count = 1;
290+
_ret = drmModeSetCrtc (settings.drm.fd, settings.drm.crtc, settings.drm.fb, _ptr->x, _ptr->y, &settings.drm.connectors, _count, &_ptr->mode) == 0;
286291

287-
_ret = drmModeSetCrtc (settings.drm.fd, settings.drm.crtc, settings.drm.fb, _ptr->x, _ptr->y, &settings.drm.connectors, _count, &_ptr->mode) == 0;
292+
drmModeFreeCrtc (_ptr);
293+
}
288294

289-
drmModeFreeCrtc (_ptr);
295+
break;
290296
}
291-
292-
break;
293-
}
294-
case EBUSY :
295-
default :
296-
{
297-
// There is nothing to be done about it
298-
}
297+
case EBUSY :
298+
default :
299+
{
300+
// There is nothing to be done about it
301+
}
302+
}
303+
}
304+
else {
305+
_ret = false;
299306
}
300-
}
301-
else {
302-
_ret = false;
303307
}
304308

305309
return _ret;
@@ -970,17 +974,6 @@ bool RenderEGLImage (struct configuration& settings) {
970974
_ret = RenderTile ();
971975
}
972976

973-
// TODO: move remainder, do after all tiles
974-
975-
if (settings.gbm.bo != InvalidGBMbo ()) {
976-
/* void */ gbm_surface_release_buffer (settings.gbm.surf, settings.gbm.bo);
977-
settings.gbm.bo = InvalidGBMbo ();
978-
}
979-
980-
if (eglSwapBuffers (settings.egl.dpy, settings.egl.surf) != EGL_FALSE) {
981-
settings.gbm.bo = gbm_surface_lock_front_buffer (settings.gbm.surf);
982-
}
983-
984977
return _ret;
985978
}
986979

@@ -1160,7 +1153,18 @@ void Parent (int sock, pid_t child) {
11601153
std::cout << "Error: scan out impossible" << std::endl;
11611154
}
11621155
else {
1163-
ScanOut (_settings);
1156+
1157+
if (eglSwapBuffers (_settings.egl.dpy, _settings.egl.surf) != EGL_FALSE) {
1158+
_settings.gbm.bo = gbm_surface_lock_front_buffer (_settings.gbm.surf);
1159+
}
1160+
1161+
/* bool */ ScanOut (_settings);
1162+
1163+
if (_settings.gbm.bo != InvalidGBMbo ()) {
1164+
/* void */ gbm_surface_release_buffer (_settings.gbm.surf, _settings.gbm.bo);
1165+
_settings.gbm.bo = InvalidGBMbo ();
1166+
}
1167+
11641168
}
11651169
}
11661170
}

0 commit comments

Comments
 (0)