init
This commit is contained in:
commit
cf8a80d0d6
2 changed files with 323 additions and 0 deletions
196
failed-egl-server.c
Normal file
196
failed-egl-server.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
#include <rfb/rfb.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
|
||||
// #define APIENTRY
|
||||
// #define APIENTRYP APIENTRY *
|
||||
// #define GLAPI extern
|
||||
// // FIXME integrate into glad
|
||||
// typedef void(APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)(
|
||||
// GLenum target, GLeglImageOES image);
|
||||
// GLAPI PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glad_glEGLImageTargetTexture2DOES;
|
||||
// typedef void(APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)(
|
||||
// GLenum target, GLeglImageOES image);
|
||||
// GLAPI PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC
|
||||
// glad_glEGLImageTargetRenderbufferStorageOES;
|
||||
|
||||
// // FIXME glad
|
||||
// static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
|
||||
// extern void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("not enough arguments\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *card = argv[1];
|
||||
const int drmfd = open(card, O_RDONLY);
|
||||
if (drmfd < 0) {
|
||||
fprintf(stderr, "card %s open failed: %s\n", card, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
int err;
|
||||
int source_plane = 0;
|
||||
int source_crtc = 0;
|
||||
err = drmSetClientCap(drmfd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
if (err < 0) {
|
||||
perror("Failed to set universal planes capability: primary planes will not be usable");
|
||||
}
|
||||
drmModePlane *plane = NULL;
|
||||
drmModePlaneRes *plane_res = NULL;
|
||||
drmModeFB2 *fb = NULL;
|
||||
if (source_plane > 0) {
|
||||
plane = drmModeGetPlane(drmfd, source_plane);
|
||||
if (!plane) {
|
||||
fprintf(stderr, "Failed to get plane %d: %s\n", source_plane, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
if (plane->fb_id == 0) {
|
||||
fprintf(stderr, "Place %d does not have an attached framebuffer\n", source_plane);
|
||||
}
|
||||
}
|
||||
else {
|
||||
plane_res = drmModeGetPlaneResources(drmfd);
|
||||
if (!plane_res) {
|
||||
perror("Failed to get plane resources");
|
||||
goto cleanup;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < plane_res->count_planes; i++) {
|
||||
plane = drmModeGetPlane(drmfd, plane_res->planes[i]);
|
||||
if (!plane) {
|
||||
fprintf(stderr, "Failed to get plane %u: %s\n", plane_res->planes[i], strerror(errno));
|
||||
continue;
|
||||
}
|
||||
printf("Plane %u CRTC %u FB %u\n", plane->plane_id, plane->crtc_id, plane->fb_id);
|
||||
if ((source_crtc > 0 && plane->crtc_id != source_crtc) || plane->fb_id == 0) {
|
||||
// Either not connected to the target source CRTC
|
||||
// or not active.
|
||||
drmModeFreePlane(plane);
|
||||
plane = NULL;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (i == plane_res->count_planes) {
|
||||
if (source_crtc > 0) {
|
||||
fprintf(stderr, "No usable planes found on CRTC %d\n", source_crtc);
|
||||
} else {
|
||||
fprintf(stderr, "No usable planes found\n");
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
printf("Using plane %u to locate framebuffers\n", plane->plane_id);
|
||||
}
|
||||
uint32_t plane_id = plane->plane_id;
|
||||
|
||||
fb = drmModeGetFB2(drmfd, plane->fb_id);
|
||||
if (!fb) {
|
||||
fprintf(stderr, "Failed to get framebuffer %u: %s\n", plane->fb_id, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
//printf("Template framebuffer is %u: %ux%u %ubpp %ub depth %u pitch\n", fb->fb_id, fb->width, fb->height, fb->bpp, fb->depth, fb->pitch);
|
||||
printf("Template framebuffer is %u: %ux%u fourcc:%u mod:%u flags:%u\n", fb->fb_id, fb->width, fb->height, fb->pixel_format, fb->modifier, fb->flags);
|
||||
printf("handles %u %u %u %u\n", fb->handles[0], fb->handles[1], fb->handles[2], fb->handles[3]);
|
||||
printf("offsets %u %u %u %u\n", fb->offsets[0], fb->offsets[1], fb->offsets[2], fb->offsets[3]);
|
||||
printf("pitches %u %u %u %u\n", fb->pitches[0], fb->pitches[1], fb->pitches[2], fb->pitches[3]);
|
||||
printf("format %s, modifier %s:%s\n", drmGetFormatName(fb->pixel_format), drmGetFormatModifierVendor(fb->modifier), drmGetFormatModifierName(fb->modifier));
|
||||
|
||||
if (!fb->handles[0]) {
|
||||
fprintf(stderr, "No handle set on framebuffer: maybe you need some additional capabilities?\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
int fd = -1;
|
||||
err = drmPrimeHandleToFD(drmfd, fb->handles[0], O_RDONLY, &fd);
|
||||
if (err < 0 || fd < 0) {
|
||||
perror("Failed to get PRIME fd from framebuffer handle");
|
||||
}
|
||||
|
||||
// //size_t buflen = fb->width * fb->height * fb->bpp / 8;
|
||||
// size_t buflen = fb->width * fb->height * 32 / 8;
|
||||
// char *buf = malloc(buflen);
|
||||
// char *mapped = mmap(NULL, buflen, PROT_READ, MAP_SHARED, fd, 0);
|
||||
// if (mapped == MAP_FAILED) {
|
||||
// perror("mmap");
|
||||
// goto cleanup;
|
||||
// }
|
||||
// memcpy(buf, mapped, buflen);
|
||||
|
||||
//unlink("/tmp/1.raw");
|
||||
//write(open("/tmp/1.raw", O_WRONLY | O_CREAT, 00644), buf, buflen);
|
||||
|
||||
// EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
// eglInitialize(display, NULL, NULL);
|
||||
// EGLContext context = eglCreateContext(display, NULL, EGL_NO_CONTEXT, NULL);
|
||||
// eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context);
|
||||
EGLAttrib attrs[] = {
|
||||
EGL_WIDTH, fb->width,
|
||||
EGL_HEIGHT, fb->height,
|
||||
EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
|
||||
EGL_DMA_BUF_PLANE0_FD_EXT, fd,
|
||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, 1,
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, 1 >> 32,
|
||||
EGL_NONE,
|
||||
};
|
||||
EGLImage image = eglCreateImage(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
fprintf(stderr, "eglCreateImage\n");
|
||||
}
|
||||
|
||||
// Create an OpenGL texture and bind it to the EGL image
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
fprintf(stderr, "glGenTextures\n");
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
fprintf(stderr, "glBindTexture\n");
|
||||
}
|
||||
|
||||
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES =
|
||||
(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
fprintf(stderr, "glEGLImageTargetTexture2DOES\n");
|
||||
}
|
||||
|
||||
// Read the pixel data from the texture
|
||||
GLubyte *buf = malloc(fb->width * fb->height * 4);
|
||||
glReadPixels(0, 0, fb->width, fb->height, GL_RGB, GL_UNSIGNED_BYTE, buf);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
fprintf(stderr, "glReadPixels\n");
|
||||
}
|
||||
|
||||
// write(open("/tmp/1.raw", O_WRONLY | O_CREAT, 00644), buf, fb->width * fb->height * 4);
|
||||
|
||||
rfbScreenInfoPtr server=rfbGetScreen(0,NULL,fb->width,fb->height,8,3,32/8);
|
||||
if(!server)
|
||||
return 1;
|
||||
server->frameBuffer=buf;
|
||||
rfbInitServer(server);
|
||||
rfbRunEventLoop(server,-1,FALSE);
|
||||
return(0);
|
||||
|
||||
cleanup:
|
||||
close(drmfd);
|
||||
return 1;
|
||||
|
||||
}
|
127
server.c
Normal file
127
server.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
#include <rfb/rfb.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("not enough arguments\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *card = argv[1];
|
||||
const int drmfd = open(card, O_RDONLY);
|
||||
if (drmfd < 0) {
|
||||
fprintf(stderr, "card %s open failed: %s\n", card, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
int err;
|
||||
int source_plane = 0;
|
||||
int source_crtc = 0;
|
||||
err = drmSetClientCap(drmfd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
if (err < 0) {
|
||||
perror("Failed to set universal planes capability: primary planes will not be usable");
|
||||
}
|
||||
drmModePlane *plane = NULL;
|
||||
drmModePlaneRes *plane_res = NULL;
|
||||
drmModeFB2 *fb = NULL;
|
||||
if (source_plane > 0) {
|
||||
plane = drmModeGetPlane(drmfd, source_plane);
|
||||
if (!plane) {
|
||||
fprintf(stderr, "Failed to get plane %d: %s\n", source_plane, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
if (plane->fb_id == 0) {
|
||||
fprintf(stderr, "Place %d does not have an attached framebuffer\n", source_plane);
|
||||
}
|
||||
}
|
||||
else {
|
||||
plane_res = drmModeGetPlaneResources(drmfd);
|
||||
if (!plane_res) {
|
||||
perror("Failed to get plane resources");
|
||||
goto cleanup;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < plane_res->count_planes; i++) {
|
||||
plane = drmModeGetPlane(drmfd, plane_res->planes[i]);
|
||||
if (!plane) {
|
||||
fprintf(stderr, "Failed to get plane %u: %s\n", plane_res->planes[i], strerror(errno));
|
||||
continue;
|
||||
}
|
||||
printf("Plane %u CRTC %u FB %u\n", plane->plane_id, plane->crtc_id, plane->fb_id);
|
||||
if ((source_crtc > 0 && plane->crtc_id != source_crtc) || plane->fb_id == 0) {
|
||||
// Either not connected to the target source CRTC
|
||||
// or not active.
|
||||
drmModeFreePlane(plane);
|
||||
plane = NULL;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (i == plane_res->count_planes) {
|
||||
if (source_crtc > 0) {
|
||||
fprintf(stderr, "No usable planes found on CRTC %d\n", source_crtc);
|
||||
} else {
|
||||
fprintf(stderr, "No usable planes found\n");
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
printf("Using plane %u to locate framebuffers\n", plane->plane_id);
|
||||
}
|
||||
uint32_t plane_id = plane->plane_id;
|
||||
|
||||
fb = drmModeGetFB2(drmfd, plane->fb_id);
|
||||
if (!fb) {
|
||||
fprintf(stderr, "Failed to get framebuffer %u: %s\n", plane->fb_id, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
//printf("Template framebuffer is %u: %ux%u %ubpp %ub depth %u pitch\n", fb->fb_id, fb->width, fb->height, fb->bpp, fb->depth, fb->pitch);
|
||||
printf("Template framebuffer is %u: %ux%u fourcc:%u mod:%u flags:%u\n", fb->fb_id, fb->width, fb->height, fb->pixel_format, fb->modifier, fb->flags);
|
||||
printf("handles %u %u %u %u\n", fb->handles[0], fb->handles[1], fb->handles[2], fb->handles[3]);
|
||||
printf("offsets %u %u %u %u\n", fb->offsets[0], fb->offsets[1], fb->offsets[2], fb->offsets[3]);
|
||||
printf("pitches %u %u %u %u\n", fb->pitches[0], fb->pitches[1], fb->pitches[2], fb->pitches[3]);
|
||||
printf("format %s, modifier %s:%s\n", drmGetFormatName(fb->pixel_format), drmGetFormatModifierVendor(fb->modifier), drmGetFormatModifierName(fb->modifier));
|
||||
|
||||
if (!fb->handles[0]) {
|
||||
fprintf(stderr, "No handle set on framebuffer: maybe you need some additional capabilities?\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
int fd = -1;
|
||||
err = drmPrimeHandleToFD(drmfd, fb->handles[0], O_RDONLY, &fd);
|
||||
if (err < 0 || fd < 0) {
|
||||
perror("Failed to get PRIME fd from framebuffer handle");
|
||||
}
|
||||
|
||||
//size_t buflen = fb->width * fb->height * fb->bpp / 8;
|
||||
size_t buflen = fb->width * fb->height * 32 / 8;
|
||||
char *buf = malloc(buflen);
|
||||
char *mapped = mmap(NULL, buflen, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (mapped == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(buf, mapped, buflen);
|
||||
|
||||
//unlink("/tmp/1.raw");
|
||||
//write(open("/tmp/1.raw", O_WRONLY | O_CREAT, 00644), buf, buflen);
|
||||
|
||||
rfbScreenInfoPtr server=rfbGetScreen(0,NULL,fb->width,fb->height,8,3,32/8);
|
||||
if(!server)
|
||||
return 1;
|
||||
server->frameBuffer=buf+8;
|
||||
rfbInitServer(server);
|
||||
rfbRunEventLoop(server,-1,FALSE);
|
||||
return(0);
|
||||
|
||||
cleanup:
|
||||
close(drmfd);
|
||||
return 1;
|
||||
|
||||
}
|
Loading…
Reference in a new issue