ssize_t drmtest_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *f_pos) { init_drm(); display_animation(); exit_drm(); return count; }
static void *drm_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { struct drm_video *_drmvars = (struct drm_video*) calloc(1, sizeof(struct drm_video)); if (!_drmvars) return NULL; /* Setup surface parameters */ _drmvars->menu_active = false; _drmvars->rgb32 = video->rgb32; /* It's very important that we set aspect here because the * call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame() * and we don't want the main surface to be setup in set_aspect() * before we get to gfx_frame(). */ _drmvars->current_aspect = video_driver_get_aspect_ratio(); /* Initialize the rest of the mutexes and conditions. */ _drmvars->vsync_condition = scond_new(); _drmvars->vsync_cond_mutex = slock_new(); _drmvars->pending_mutex = slock_new(); _drmvars->core_width = 0; _drmvars->core_height = 0; _drmvars->main_surface = NULL; _drmvars->menu_surface = NULL; if (input && input_data) *input = NULL; /* DRM Init */ if (!init_drm()) { RARCH_ERR ("DRM: Failed to initialize DRM\n"); return NULL; } else RARCH_LOG ("DRM: Init succesful.\n"); _drmvars->kms_width = drm.current_mode->hdisplay; _drmvars->kms_height = drm.current_mode->vdisplay; return _drmvars; }
struct display * display_create(int *argc, char **argv[], const GOptionEntry *option_entries) { struct display *d; GOptionContext *context; GOptionGroup *xkb_option_group; GError *error; g_type_init(); context = g_option_context_new(NULL); if (option_entries) g_option_context_add_main_entries(context, option_entries, "Wayland View"); xkb_option_group = g_option_group_new("xkb", "Keyboard options", "Show all XKB options", NULL, NULL); g_option_group_add_entries(xkb_option_group, xkb_option_entries); g_option_context_add_group (context, xkb_option_group); if (!g_option_context_parse(context, argc, argv, &error)) { fprintf(stderr, "option parsing failed: %s\n", error->message); exit(EXIT_FAILURE); } d = malloc(sizeof *d); if (d == NULL) return NULL; d->display = wl_display_connect(NULL); if (d->display == NULL) { fprintf(stderr, "failed to create display: %m\n"); return NULL; } wl_list_init(&d->input_list); /* Set up listener so we'll catch all events. */ wl_display_add_global_listener(d->display, display_handle_global, d); /* Process connection events. */ wl_display_iterate(d->display, WL_DISPLAY_READABLE); if (d->device_name && init_drm(d) < 0) return NULL; create_pointer_surfaces(d); display_render_frame(d); d->loop = g_main_loop_new(NULL, FALSE); d->source = wl_glib_source_new(d->display); g_source_attach(d->source, NULL); wl_list_init(&d->window_list); init_xkb(d); return d; }
const struct drm *init_drm_atomic(const char *device, uint64_t *modifiers, unsigned int num_modifiers) { uint32_t plane_id; int ret; ret = init_drm(&drm, device); if (ret) return NULL; drm.num_modifiers = num_modifiers; drm.modifiers = modifiers; ret = drmSetClientCap(drm.fd, DRM_CLIENT_CAP_ATOMIC, 1); if (ret) { printf("no atomic modesetting support: %s\n", strerror(errno)); return NULL; } ret = get_plane_id(); if (!ret) { printf("could not find a suitable plane\n"); return NULL; } else { plane_id = ret; } /* We only do single plane to single crtc to single connector, no * fancy multi-monitor or multi-plane stuff. So just grab the * plane/crtc/connector property info for one of each: */ drm.plane = calloc(1, sizeof(*drm.plane)); drm.crtc = calloc(1, sizeof(*drm.crtc)); drm.connector = calloc(1, sizeof(*drm.connector)); #define get_resource(type, Type, id) do { \ drm.type->type = drmModeGet##Type(drm.fd, id); \ if (!drm.type->type) { \ printf("could not get %s %i: %s\n", \ #type, id, strerror(errno)); \ return NULL; \ } \ } while (0) get_resource(plane, Plane, plane_id); get_resource(crtc, Crtc, drm.crtc_id); get_resource(connector, Connector, drm.connector_id); #define get_properties(type, TYPE, id) do { \ uint32_t i; \ drm.type->props = drmModeObjectGetProperties(drm.fd, \ id, DRM_MODE_OBJECT_##TYPE); \ if (!drm.type->props) { \ printf("could not get %s %u properties: %s\n", \ #type, id, strerror(errno)); \ return NULL; \ } \ drm.type->props_info = calloc(drm.type->props->count_props, \ sizeof(drm.type->props_info)); \ for (i = 0; i < drm.type->props->count_props; i++) { \ drm.type->props_info[i] = drmModeGetProperty(drm.fd, \ drm.type->props->props[i]); \ } \ } while (0) get_properties(plane, PLANE, plane_id); get_properties(crtc, CRTC, drm.crtc_id); get_properties(connector, CONNECTOR, drm.connector_id); if (num_modifiers == 0) { ret = drm_atomic_get_modifiers(&drm); if (ret < 0) return NULL; } drm.run = atomic_run; return &drm; }
int init_egl_drm() { fd_set fds; drmEventContext evctx = { .version = DRM_EVENT_CONTEXT_VERSION, .vblank_handler = 0, .page_flip_handler = page_flip_handler, }; struct gbm_bo *bo; struct drm_fb *fb; ret = init_drm(); if (ret) { printf("failed to initialize DRM\n"); return ret; } printf("### Primary display => ConnectorId = %d, Resolution = %dx%d\n", drm.connector_id[DISP_ID], drm.mode[DISP_ID]->hdisplay, drm.mode[DISP_ID]->vdisplay); FD_ZERO(&fds); FD_SET(drm.fd, &fds); ret = init_gbm(); if (ret) { printf("failed to initialize GBM\n"); return ret; } //Initialise egl regularly here } void egl_drm_draw_flip() { /* set mode: */ if (all_display) { for (i=0; i<drm.ndisp; i++) { ret = drmModeSetCrtc(drm.fd, drm.crtc_id[i], fb->fb_id, 0, 0, &drm.connector_id[i], 1, drm.mode[i]); if (ret) { printf("display %d failed to set mode: %s\n", i, strerror(errno)); return ret; } } } else { ret = drmModeSetCrtc(drm.fd, drm.crtc_id[DISP_ID], fb->fb_id, 0, 0, &drm.connector_id[DISP_ID], 1, drm.mode[DISP_ID]); if (ret) { printf("display %d failed to set mode: %s\n", DISP_ID, strerror(errno)); return ret; } } //Draw call here //Swapping is involved next_bo = gbm_surface_lock_front_buffer(gbm.surface); fb = drm_fb_get_from_bo(next_bo); /* * Here you could also update drm plane layers if you want * hw composition */ ret = drmModePageFlip(drm.fd, drm.crtc_id[DISP_ID], fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip); if (ret) { printf("failed to queue page flip: %s\n", strerror(errno)); return -1; } while (waiting_for_flip) { ret = select(drm.fd + 1, &fds, NULL, NULL, NULL); if (ret < 0) { printf("select err: %s\n", strerror(errno)); return ret; } else if (ret == 0) { printf("select timeout!\n"); return -1; } else if (FD_ISSET(0, &fds)) { continue; } drmHandleEvent(drm.fd, &evctx); } /* release last buffer to render on again: */ gbm_surface_release_buffer(gbm.surface, bo); bo = next_bo; }
int main(int argc, char *argv[]) { struct opt_data opts; optproc(argc, argv, &opts); if(audio_init(&opts) < 0) exit(1); if(opts.w < 0 && opts.h < 0) opts.w = opts.h = 512; else if(opts.w < 0) opts.w = opts.h; else if(opts.h < 0) opts.h = opts.w; int ret; ret = init_drm(&opts, 512); if (ret) { printf("failed to initialize DRM\n"); return ret; } ret = init_gbm(); if (ret) { printf("failed to initialize GBM\n"); return ret; } ret = init_egl(); if (ret) { printf("failed to initialize EGL\n"); return ret; } // call init_gl //init_gl(&opts, drm.mode->hdisplay, drm.mode->vdisplay); init_gl(&opts, opts.w, opts.h); //TODO: better dealing with our great big screen eglSwapBuffers(gl.display, gl.surface); struct gbm_bo *bo = gbm_surface_lock_front_buffer(gbm.surface); fb = drm_fb_get_from_bo(bo); /* set mode: */ ret = drmModeSetCrtc(drm.fd, drm.crtc_id, fb->fb_id, 0, 0, &drm.connector_id, 1, drm.mode); if (ret) { printf("failed to set mode: %s\n", strerror(errno)); return ret; } // turn off line buffering on input and echoing of characters struct termios term; tcgetattr(STDIN_FILENO, &save_term); tcgetattr(STDIN_FILENO, &term); term.c_lflag &= ~(ICANON|ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &term); atexit(shutdown_cleanup); drmVBlank vbl; /* Get current count first hopefully also sync up with blank too*/ vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 1; ret = drmWaitVBlank(drm.fd, &vbl); if (ret != 0) { printf("drmWaitVBlank (relative, event) failed ret: %i\n", ret); return -1; } printf("starting msc: %d\n", vbl.request.sequence); /* Queue an event for frame + 1 */ vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; vbl.request.sequence = 1; vbl.request.signal = NULL; ret = drmWaitVBlank(drm.fd, &vbl); if (ret != 0) { printf("drmWaitVBlank (relative, event) failed ret: %i\n", ret); return -1; } struct pollfd pfds[] = { {drm.fd, POLLIN | POLLPRI, 0 }, {STDIN_FILENO, POLLIN, 0 }, }; int debug_maxsrc = 0, debug_pal = 0, show_mandel = 0, show_fps_hist = 0; bool done = false; while (!done) { render_frame(debug_maxsrc, debug_pal, show_mandel, show_fps_hist); while (waiting_for_flip) { // TODO: input handling ret = poll(pfds, 2, -1); if (ret < 0) { printf("poll err: %s\n", strerror(errno)); return ret; } else if (ret == 0) { printf("poll timeout!\n"); done = true; break; } if (pfds[1].revents) { char buf[128]; int cnt = read(STDIN_FILENO, buf, sizeof(buf)); if(buf[0] == 27) done = true; else if(buf[0] == '1') debug_maxsrc = !debug_maxsrc; else if(buf[0] == '2') debug_pal = !debug_pal; else if(buf[0] == '3') show_mandel = !show_mandel; else if(buf[0] == '4') show_fps_hist = !show_fps_hist; //continue; } if(pfds[0].revents) drmHandleEvent(drm.fd, &evctx); } /* release last buffer to render on again: */ gbm_surface_release_buffer(gbm.surface, bo); bo = next_bo; } audio_shutdown(); return ret; }