diff --git a/shared/libblight_client/main.cpp b/shared/libblight_client/main.cpp index e7031502..8e3acab3 100644 --- a/shared/libblight_client/main.cpp +++ b/shared/libblight_client/main.cpp @@ -148,49 +148,193 @@ namespace { _INFO("%s", "InputWorker quitting"); } + int __fb_send_update(mxcfb_update_data* update){ + _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SEND_UPDATE") + Blight::ClockWatch cw; + if(!blightBuffer->surface){ + Blight::addSurface(blightBuffer); + } + if(!blightBuffer->surface){ + _CRIT("Failed to create surface: %s", std::strerror(errno)); + std::exit(errno); + } + auto region = update->update_region; + auto maybe = blightConnection->repaint( + blightBuffer, + region.left, + region.top, + region.width, + region.height, + (Blight::WaveformMode)update->waveform_mode, + update->update_marker + ); + if(maybe.has_value()){ + maybe.value()->wait(); + } + _DEBUG("ioctl /dev/fb0 MXCFB_SEND_UPDATE done: %f", cw.elapsed()) + // TODO - notify on rM2 for screensharing + return 0; + } + + int __fb_wait(mxcfb_update_marker_data* update){ + _DEBUG("%s", "ioctl /dev/fb0 MXCFB_WAIT_FOR_UPDATE_COMPLETE"); + Blight::ClockWatch cw; + blightConnection->waitForMarker(update->update_marker); + _DEBUG("ioctl /dev/fb0 MXCFB_WAIT_FOR_UPDATE_COMPLETE done: %f", cw.elapsed()); + return 0; + } + + int __fb_get_vscreeninfo(fb_var_screeninfo* screenInfo){ + _DEBUG("%s", "ioctl /dev/fb0 FBIOGET_VSCREENINFO"); + screenInfo->xres = blightBuffer->width; + screenInfo->yres = blightBuffer->height; + screenInfo->xoffset = 0; + screenInfo->yoffset = 0; + screenInfo->xres_virtual = blightBuffer->width; + screenInfo->yres_virtual = blightBuffer->height; + screenInfo->bits_per_pixel = blightBuffer->stride / blightBuffer->width * 8; + // TODO - determine the following from the buffer format + // Format_RGB16 / RGB565 + screenInfo->grayscale = 0; + screenInfo->red.offset = 11; + screenInfo->red.length = 5; + screenInfo->red.msb_right = 0; + screenInfo->green.offset = 5; + screenInfo->green.length = 6; + screenInfo->green.msb_right = 0; + screenInfo->blue.offset = 0; + screenInfo->blue.length = 5; + screenInfo->blue.msb_right = 0; + // TODO what should this even be? + screenInfo->nonstd = 0; + screenInfo->activate = FB_ACTIVATE_FORCE; + // It would be cool to have the actual mm width/height here + screenInfo->height = 0; + screenInfo->width = 0; + screenInfo->accel_flags = 0; + // screenInfo->pixclock = 28800; // Stick with what is reported + screenInfo->left_margin = 0; + screenInfo->right_margin = 0; + screenInfo->upper_margin = 0; + screenInfo->lower_margin = 0; + screenInfo->hsync_len = 1; + screenInfo->vsync_len = 1; + screenInfo->sync = 0; + screenInfo->vmode = 0; + screenInfo->rotate = 0; + screenInfo->colorspace = 0; + screenInfo->reserved[0] = 0; + screenInfo->reserved[1] = 0; + screenInfo->reserved[2] = 0; + screenInfo->reserved[3] = 0; + return 0; + } + + int __fb_get_fscreeninfo(fb_fix_screeninfo* screenInfo){ + _DEBUG("%s", "ioctl /dev/fb0 FBIOGET_FSCREENINFO"); + constexpr char fb_id[] = "mxcfb"; + memcpy(screenInfo->id, fb_id, sizeof(fb_id)); + // TODO determine all the values dynamically + screenInfo->smem_len = blightBuffer->size(); + screenInfo->smem_start = (unsigned long)blightBuffer->data; + screenInfo->type = 0; + screenInfo->type_aux = 0; + screenInfo->visual = FB_VISUAL_TRUECOLOR; + screenInfo->xpanstep = 8; + screenInfo->ypanstep = 0; + screenInfo->ywrapstep = 5772; + screenInfo->line_length = blightBuffer->stride; + screenInfo->mmio_start = 0; + screenInfo->mmio_len = 0; + screenInfo->accel = 0; + screenInfo->reserved[0] = 0; + screenInfo->reserved[1] = 0; + return 0; + } + + int __fb_put_vscreeninfo(fb_var_screeninfo* screenInfo){ + _DEBUG("%s", "ioctl /dev/fb0 FBIOPUT_VSCREENINFO"); + // TODO - Explore allowing some screen info updating + _DEBUG( + "\n" + "res: %dx%d\n" + "res_virtual: %dx%d\n" + "offset: %d, %d\n" + "bits_per_pixel: %d\n" + "grayscale: %d\n" + "red: %d, %d, %d\n" + "green: %d, %d, %d\n" + "blue: %d, %d, %d\n" + "tansp: %d, %d, %d\n" + "nonstd: %d\n" + "activate: %d\n" + "size: %dx%dmm\n" + "accel_flags: %d\n" + "pixclock: %d\n" + "margins: %d %d %d %d\n" + "hsync_len: %d\n" + "vsync_len: %d\n" + "sync: %d\n" + "vmode: %d\n" + "rotate: %d\n" + "colorspace: %d\n" + "reserved: %d, %d, %d, %d\n", + screenInfo->xres, + screenInfo->yres, + screenInfo->xres_virtual, + screenInfo->yres_virtual, + screenInfo->xoffset, + screenInfo->yoffset, + screenInfo->bits_per_pixel, + screenInfo->grayscale, + screenInfo->red.offset, + screenInfo->red.length, + screenInfo->red.msb_right, + screenInfo->green.offset, + screenInfo->green.length, + screenInfo->green.msb_right, + screenInfo->blue.offset, + screenInfo->blue.length, + screenInfo->blue.msb_right, + screenInfo->transp.offset, + screenInfo->transp.length, + screenInfo->transp.msb_right, + screenInfo->nonstd, + screenInfo->activate, + screenInfo->height, + screenInfo->width, + screenInfo->accel_flags, + screenInfo->pixclock, + screenInfo->left_margin, + screenInfo->right_margin, + screenInfo->upper_margin, + screenInfo->lower_margin, + screenInfo->hsync_len, + screenInfo->vsync_len, + screenInfo->sync, + screenInfo->vmode, + screenInfo->rotate, + screenInfo->colorspace, + screenInfo->reserved[0], + screenInfo->reserved[1], + screenInfo->reserved[2], + screenInfo->reserved[3] + ); + // TODO allow resizing? + return 0; + } + int __fb_ioctl(unsigned long request, char* ptr){ switch(request){ // Look at linux/fb.h and mxcfb.h for more possible request types // https://www.kernel.org/doc/html/latest/fb/api.html case MXCFB_SEND_UPDATE:{ - _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SEND_UPDATE") - Blight::ClockWatch cw; - if(!blightBuffer->surface){ - Blight::addSurface(blightBuffer); - } - if(!blightBuffer->surface){ - _CRIT("Failed to create surface: %s", std::strerror(errno)); - std::exit(errno); - } - auto update = reinterpret_cast(ptr); - auto region = update->update_region; - auto maybe = blightConnection->repaint( - blightBuffer, - region.left, - region.top, - region.width, - region.height, - (Blight::WaveformMode)update->waveform_mode, - update->update_marker - ); - if(maybe.has_value()){ - maybe.value()->wait(); - } - _DEBUG("ioctl /dev/fb0 MXCFB_SEND_UPDATE done: %f", cw.elapsed()) - // TODO - notify on rM2 for screensharing - return 0; + return __fb_send_update(reinterpret_cast(ptr)); } case MXCFB_WAIT_FOR_UPDATE_COMPLETE:{ - _DEBUG("%s", "ioctl /dev/fb0 MXCFB_WAIT_FOR_UPDATE_COMPLETE"); - Blight::ClockWatch cw; - auto update = reinterpret_cast(ptr); - blightConnection->waitForMarker(update->update_marker); - _DEBUG("ioctl /dev/fb0 MXCFB_WAIT_FOR_UPDATE_COMPLETE done: %f", cw.elapsed()); - return 0; + return __fb_wait(reinterpret_cast(ptr)); } case FBIOGET_VSCREENINFO:{ - _DEBUG("%s", "ioctl /dev/fb0 FBIOGET_VSCREENINFO"); - auto screenInfo = reinterpret_cast(ptr); int fd = func_open("/dev/fb0", O_RDONLY, 0); if(fd == -1){ return -1; @@ -198,52 +342,9 @@ namespace { if(func_ioctl(fd, request, ptr) == -1){ return -1; } - screenInfo->xres = blightBuffer->width; - screenInfo->yres = blightBuffer->height; - screenInfo->xoffset = 0; - screenInfo->yoffset = 0; - screenInfo->xres_virtual = blightBuffer->width; - screenInfo->yres_virtual = blightBuffer->height; - screenInfo->bits_per_pixel = blightBuffer->stride / blightBuffer->width * 8; - // TODO - determine the following from the buffer format - // Format_RGB16 / RGB565 - screenInfo->grayscale = 0; - screenInfo->red.offset = 11; - screenInfo->red.length = 5; - screenInfo->red.msb_right = 0; - screenInfo->green.offset = 5; - screenInfo->green.length = 6; - screenInfo->green.msb_right = 0; - screenInfo->blue.offset = 0; - screenInfo->blue.length = 5; - screenInfo->blue.msb_right = 0; - // TODO what should this even be? - screenInfo->nonstd = 0; - screenInfo->activate = 0; - // It would be cool to have the actual mm width/height here - screenInfo->height = 0; - screenInfo->width = 0; - screenInfo->accel_flags = 0; - // screenInfo->pixclock = 28800; // Stick with what is reported - screenInfo->left_margin = 0; - screenInfo->right_margin = 0; - screenInfo->upper_margin = 0; - screenInfo->lower_margin = 0; - screenInfo->hsync_len = 0; - screenInfo->vsync_len = 2; - screenInfo->sync = 0; - screenInfo->vmode = 0; - screenInfo->rotate = 0; - screenInfo->colorspace = 0; - screenInfo->reserved[0] = 0; - screenInfo->reserved[1] = 0; - screenInfo->reserved[2] = 0; - screenInfo->reserved[3] = 0; - return 0; + return __fb_get_vscreeninfo(reinterpret_cast(ptr)); } case FBIOGET_FSCREENINFO:{ - _DEBUG("%s", "ioctl /dev/fb0 FBIOGET_FSCREENINFO"); - auto screenInfo = reinterpret_cast(ptr); int fd = func_open("/dev/fb0", O_RDONLY, 0); if(fd == -1){ return -1; @@ -251,94 +352,10 @@ namespace { if(func_ioctl(fd, request, ptr) == -1){ return -1; } - // TODO determine all the values dynamically - screenInfo->smem_len = blightBuffer->size(); - screenInfo->smem_start = (unsigned long)blightBuffer->data; - screenInfo->type = 0; - screenInfo->type_aux = 0; - screenInfo->visual = 0; - screenInfo->xpanstep = 8; - screenInfo->ypanstep = 0; - screenInfo->ywrapstep = 5772; - screenInfo->line_length = blightBuffer->stride; - screenInfo->mmio_start = 0; - screenInfo->mmio_len = 0; - screenInfo->accel = 0; - screenInfo->reserved[0] = 0; - screenInfo->reserved[1] = 0; - return 0; + return __fb_get_fscreeninfo(reinterpret_cast(ptr)); } case FBIOPUT_VSCREENINFO:{ - _DEBUG("%s", "ioctl /dev/fb0 FBIOPUT_VSCREENINFO"); - // TODO - Explore allowing some screen info updating - auto screenInfo = reinterpret_cast(ptr); - _DEBUG( - "\n" - "res: %dx%d\n" - "res_virtual: %dx%d\n" - "offset: %d, %d\n" - "bits_per_pixel: %d\n" - "grayscale: %d\n" - "red: %d, %d, %d\n" - "green: %d, %d, %d\n" - "blue: %d, %d, %d\n" - "tansp: %d, %d, %d\n" - "nonstd: %d\n" - "activate: %d\n" - "size: %dx%dmm\n" - "accel_flags: %d\n" - "pixclock: %d\n" - "margins: %d %d %d %d\n" - "hsync_len: %d\n" - "vsync_len: %d\n" - "sync: %d\n" - "vmode: %d\n" - "rotate: %d\n" - "colorspace: %d\n" - "reserved: %d, %d, %d, %d\n", - screenInfo->xres, - screenInfo->yres, - screenInfo->xres_virtual, - screenInfo->yres_virtual, - screenInfo->xoffset, - screenInfo->yoffset, - screenInfo->bits_per_pixel, - screenInfo->grayscale, - screenInfo->red.offset, - screenInfo->red.length, - screenInfo->red.msb_right, - screenInfo->green.offset, - screenInfo->green.length, - screenInfo->green.msb_right, - screenInfo->blue.offset, - screenInfo->blue.length, - screenInfo->blue.msb_right, - screenInfo->transp.offset, - screenInfo->transp.length, - screenInfo->transp.msb_right, - screenInfo->nonstd, - screenInfo->activate, - screenInfo->height, - screenInfo->width, - screenInfo->accel_flags, - screenInfo->pixclock, - screenInfo->left_margin, - screenInfo->right_margin, - screenInfo->upper_margin, - screenInfo->lower_margin, - screenInfo->hsync_len, - screenInfo->vsync_len, - screenInfo->sync, - screenInfo->vmode, - screenInfo->rotate, - screenInfo->colorspace, - screenInfo->reserved[0], - screenInfo->reserved[1], - screenInfo->reserved[2], - screenInfo->reserved[3] - ); - // TODO allow resizing? - return 0; + return __fb_put_vscreeninfo(reinterpret_cast(ptr)); } case MXCFB_SET_AUTO_UPDATE_MODE: _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SET_AUTO_UPDATE_MODE");