Back to the Linux Framebuffer! - FOSDEM · Contents 1. Getting started – /dev/fb0 and mmap –...

Post on 01-Oct-2020

0 views 0 download

Transcript of Back to the Linux Framebuffer! - FOSDEM · Contents 1. Getting started – /dev/fb0 and mmap –...

Back to the Linux Framebuffer!

Linux Framebuffer support in free software

Nicolas Caramelli

Contents1. Getting started

– /dev/fb0 and mmap

– fb-test-app, fbmark

2. Some tools– Fbpad terminal emulator

– Fbi, FIM image viewers

– NetSurf, Links web browsers

– Fbff, MPlayer media players

– Fbpdf document viewer

3. Drawing libraries– Cairo

– Evas

4. OpenGL rendering– GLFBDev extension

– EGL for Linux Framebuffer

Contents5. Multimedia frameworks

– FFmpeg

– GStreamer

– Xine

– VLC

6. Graphics abstraction layers– GLUT

– SDL

7. User interface toolkits– EFL

– GTK+

– Qt

8. Extra

Contents

1.Getting started

2.Some tools

3.Drawing libraries

4.OpenGL rendering

5.Multimedia frameworks

6.Graphics abstraction layers

7.User interface toolkits

8.Extra

/dev/fb0 and mmap● First check cat /dev/urandom > /dev/fb0● Example with 3 bytes (blue, green and red) per pixel on 1024 x 768 screen resolution

Framebuffer memory = 1024 * 768 pixels * 3 bytes

fd = open("/dev/fb0", O_RDWR);

fbmem = mmap(NULL, 1024 * 768 * 3, PROT_WRITE, MAP_SHARED, fd, 0);

fbmem += 200 * 1024 * 3 + 100 * 3;

for (y = 0; y < 360; y++) {

  for (x = 0; x < 480; x++) {

    fbmem[x * 3    ] = 255;

    fbmem[x * 3 + 1] = 0;

    fbmem[x * 3 + 2] = 0;

  }

  fbmem += 1024 * 3;

}767

1024 * 3 - 1

B G R

B G R B G R

B G R

B G R100 * 310 2

0

1

100 * 3 + 480 * 3

B G R

B G R

200

200 +360

x

y

480 * 3

360

B G R

B G R

B G R

B G R

/dev/fb0 and mmap demo

fb-test-app, fbmark

fb-test-app, fbmark● fb-test-app test suite

https://gitlab.com/meetroger/fb-test-app

fb-string.c, fb-test.c

→ fb_open() in common.c

→ fbmem = mmap() on /dev/fb0

● fbmark benchmarks

https://github.com/caramelli/fbmark

fb_sierpinski.c, fb_mandelbrot.c, fb_rectangle.c→ fbmem = mmap() on /dev/fb0

Contents

1.Getting started

2.Some tools

3.Drawing libraries

4.OpenGL rendering

5.Multimedia frameworks

6.Graphics abstraction layers

7.User interface toolkits

8.Extra

Fbpad terminal emulator

Fbpad https://github.com/aligrudi/fbpad

→ fb_init() in fbpad/draw.c

→ fbmem = mmap() on /dev/fb0

→ execterm("sh") in fbpad/fbpad.c

→ term_exec("sh") in fbpad/term.c

→ openpty() open pseudoterminal master /dev/ptmx and slave /dev/pts/0 descriptors

→ fork() child process duplicates slave descriptor to 0, 1, 2 and calls execve("sh")

→ pollterms() in fbpad/fbpad.c

→ readchar() in fbpad/fbpad.c read on stdin

→ term_send() in fbpad/term.c

→ writepty() master writes to the slave

→ term_read() in fbpad/term.c

→ readpty() master reads data written by the slave

→ pad_put() in fbpad/pad.c–

→ fb_set() copy of character to fbmem

Fbpad terminal emulator

Fbi, FIM image viewers

Fbi, FIM image viewers● Fbi https://git.kraxel.org/cgit/fbida

→ fb_init() in fbi/fbtools.c

→ fbmem = mmap() on /dev/fb0

→ read_image() in fbi/fbi.c use of libjpeg, libpng, ...

→ shadow_render() in fbi/fb-gui.c

● FIM http://svn.savannah.nongnu.org/svn/fbi-improved/trunk

→ fb_init() in fim/src/FramebufferDevice.cpp

→ fbmem = mmap() on /dev/fb0

→ read_image() in fim/src/FbiStuff.cpp use of libjpeg, libpng, ...

→ convert_line() in fim/src/FramebufferDevice.cpp

copy of decoded image to fbmem

copy of decoded image to fbmem

NetSurf, Links web browsers

NetSurf, Links web browsers● NetSurf https://git.netsurf-browser.org/netsurf.git

Libnsfb https://git.netsurf-browser.org/libnsfb.git

→ linux_register_surface() __attribute__((constructor)) in libnsfb/src/surface/linux.c

→ nsfb_register_surface("linux", NSFB_SURFACE_LINUX, linux_rtns)

in libnsfb/src/surface/surface.c

→ gui_init() in netsurf/framebuffer/gui.c

→ framebuffer_initialise() in netsurf/framebuffer/framebuffer.c

→ nsfb_t * nsfb_new(NSFB_SURFACE_LINUX) in libnsfb/src/libnsfb.c

→ nsfb_init(nsfb_t *) in libnsfb/src/libnsfb.c

→ linux_initialise() in libnsfb/src/surface/linux.c→ fbmem = mmap() on /dev/fb0

→ nsfb_plot_bitmap(), … in libnsfb/src/plot/api.c

● Links http://links.twibright.com/download

→ init() in links/main.c

→ init_graphics() in links/drivers.c

→ init_graphics_driver(fb_driver) in links/drivers.c

→ fb_init_driver() in links/framebuffer.c→ fbmem = mmap() on /dev/fb0

→ fb_draw_bitmap(), … in links/framebuffer.c draw in fbmem

draw in fbmem

Fbff, MPlayer media players

Fbff, MPlayer media players● Fbff https://github.com/aligrudi/fbff

→ fb_init() in fbff/draw.c

→ fbmem = mmap() on /dev/fb0

→ ffs_vdec() in fbff/ffs.c

→ draw_frame() in fbff/fbff.c

→ fb_set() in fbff/draw.c

● MPlayer http://svn.mplayerhq.hu/MPlayer/releases

→ vo_functions_t * init_best_video_out() in MPlayer/libvo/video_out.c

return LIBVO_EXTERN(fbdev)

→ decode_video() in Mplayer/libmpcodecs/dec_video.c

→ mpcodecs_config_vo() in MPlayer/libmpcodecs/vd.c

→ config() in MPlayer/libmpcodecs/vf_vo.c

→ config_video_out() in MPlayer/libvo/video_out.c→ config() in MPlayer/libvo/vo_fbdev.c

→ fbmem = mmap() on /dev/fb0

→ mpcodecs_get_image() in MPlayer/libmpcodecs/vd.c

→ filter_video() in MPlayer/libmpcodecs/dec_video.c

→ put_image() in MPlayer/libmpcodecs/vf_vo.c

→ draw_slice() in MPlayer/libvo/vo_fbdev.c

copy of decoded video to fbmem

copy of decoded video to fbmem

Fbpdf document viewer

Fbpdf document viewerFbpdf https://github.com/aligrudi/fbpdf

● fbmupdf based on MuPDF framework

→ fb_init() in fbpdf/draw.c

→ fbmem = mmap() on /dev/fb0

→ showpage() in fbpdf/fbpdf.c

→ doc_draw() in fbpdf/mupdf.c

→ fz_run_page()

→ fb_set() in fbpdf/draw.c

● fbpoppler based on Poppler framework

→ fb_init() in fbpdf/draw.c

→ fbmem = mmap() on /dev/fb0

→ showpage() in fbpdf/fbpdf.c

→ doc_draw() in fbpdf/poppler.c

→ poppler_page_render()

→ fb_set() in fbpdf/draw.c copy of PDF page to render in fbmem

copy of PDF page to render in fbmem

Contents

1.Getting started

2.Some Tools

3.Drawing libraries

4.OpenGL rendering

5.Multimedia frameworks

6.Graphics abstraction layers

7.User interface toolkits

8.Extra

Cairo

● Cairo https://cgit.freedesktop.org/cairo● Cairo-demos

– https://gitlab.com/cairo/cairo-demos

fbdev/cairo-fb.c

– https://cgit.freedesktop.org/~ickle/cairo-demos

fbdev.c

Cairo demo

● Create a target surface for Linux Framebuffer (2 methods)1) cairo_surface_t * cairo_image_surface_create_for_data(void *fbmem)

where fbmem = mmap() on /dev/fb0

→ pixman_image_create_bits() in cairo/src/cairo-image-surface.c

cairo_surface_t * cairo_surface_create_similar(cairo_surface_t *) for double buffering

2) cairo_surface_t * cairo_image_surface_create()

→ pixman_image_create_bits() in cairo/src/cairo-image-surface.c

● Create Cairo contextcairo_t * cairo_create(cairo_surface_t *)

● Draw using the Cairo APIcairo_rectangle(cairo_t *), cairo_line_to(cairo_t *),

cairo_arc(cairo_t *), cairo_show_text(cairo_t *), ...

cairo_set_source_surface(cairo_t *, cairo_surface_t *), cairo_paint(cairo_t *)

cairo_image_surface_get_data(cairo_surface_t *)

Cairo internal

copy to fbmem

to be copied to fbmem

Evas

● Evas– https://git.enlightenment.org/core/efl.git/

– https://git.enlightenment.org/legacy/evas.git/

→ Linux Framebuffer support in engines/fb directory

● Expedite https://git.enlightenment.org/tools/expedite.git/

src/bin/engine_fb.c

Evas demo

Evas internal● Setup a canvas for Linux Framebuffer

– Evas * evas_new()

– evas_output_method_set(Evas *,

evas_render_method_lookup("fb"))

– evas_engine_info_set(Evas *, Evas_Engine_Info_FB *)

→ setup() in evas/engines/fb/evas_engine.c

→ evas_fb_outbuf_fb_setup_fb() in evas/engines/fb/evas_outbuf.c

→ fb_postinit() in evas/engines/fb/evas_fb_main.c

→ fbmem = mmap() on /dev/fb0

● Draw using the Evas API

evas_object_rectangle_add(Evas *), evas_object_line_add(Evas *),

evas_object_image_add(Evas *), evas_object_text_add(Evas *), ...

evas_render(Evas *) or evas_render_updates(Evas *)

→ output_redraws_next_update_push() in evas/engines/fb/evas_engine.c

→ evas_fb_outbuf_fb_push_updated_region() in evas/engines/fb/evas_outbuf.c

copy to fbmem

Contents

1.Getting started

2.Some tools

3.Drawing libraries

4.OpenGL rendering

5.Multimedia frameworks

6.Graphics abstraction layers

7.User interface toolkits

8.Extra

OpenGL rendering

● The Mesa 3D project makes OpenGL and OpenGL ES rendering possible using CPU operations only and the Linux Framebuffer (without requiring a GPU)

● Applications can choose between 2 APIs for rendering– GLFBDev (OpenGL Extension to the Linux Framebuffer)

based on Mesa legacy infrastructure

– EGL for Linux Framebuffer platform

based on Mesa Gallium3D infrastructure

GLFBDev extension

● Implemented in Mesa https://gitlab.freedesktop.org/mesa/mesa

→ Interfaces and Linux Framebuffer support in src/mesa/drivers/fbdev/glfbdev.c● Examples:

– mesa-demos https://gitlab.freedesktop.org/mesa/demos

progs/fbdev/glfbdevtest.c

– yagears https://github.com/caramelli/yagears

GLFBDev extension demo

GLFBDev extension internal

● GLFBDevBufferPtr glFBDevCreateBuffer(void *fbmem)

where fbmem = mmap() on /dev/fb0

→ in Mesa/src/mesa/drivers/fbdev/glfbdev.c

_mesa_initialize_window_framebuffer(struct gl_framebuffer *)

● glFBDevSetWindow(GLFBDevBufferPtr, struct fb_window)

with struct fb_window { int width; int height; int posx; int posy; };

● GLFBDevContextPtr glFBDevCreateContext()

● glFBDevMakeCurrent(GLFBDevContextPtr, GLFBDevBufferPtr)●

● glFBDevSwapBuffers(GLFBDevBufferPtr)

yagears -b gl-fbdev -e gl

copy of 3D drawing based on OpenGL API to fbmem

EGL for Linux Framebuffer

● Implemented in Mesa https://gitlab.freedesktop.org/mesa/mesa

→ Interfaces in src/egl/main/eglapi.c, Linux Framebuffer support in src/gallium/state_trackers/egl/fbdev and src/gallium/winsys/sw/fbdev directories

● Examples:– mesa-demos https://gitlab.freedesktop.org/mesa/demos

src/egl/opengles1/eglfbdev.c

– yagears https://github.com/caramelli/yagears

EGL for Linux Framebuffer demo

EGL for Linux Framebuffer internal

● EGLDisplay eglGetDisplay()

→ eglGetNativePlatform() in Mesa/src/egl/main/egldisplay.c

→ getenv("EGL_PLATFORM") EGL_PLATFORM needs to be set to “fbdev”

● eglInitialize(egl_dpy, ...)

→ egl_g3d_initialize() in Mesa/src/gallium/state_trackers/egl/common/egl_g3d.c

→ native_create_display() in Mesa/src/gallium/state_trackers/egl/fbdev/native_fbdev.c

→ fbdev_create_sw_winsys() in Mesa/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c

→ fbmem = mmap() on /dev/fb0● EGLSurface eglCreateWindowSurface(EGLDisplay, struct fb_window *)

with struct fb_window { int width; int height; int posx; int posy; };

● EGLContext eglCreateContext()

● eglMakeCurrent(EGLSurface, EGLContext)

→ egl_g3d_make_current() in Mesa/src/gallium/state_trackers/egl/common/egl_g3d_api.c

→ st_api_make_current() in Mesa/src/mesa/state_tracker/st_manager.c

→ _mesa_initialize_window_framebuffer(struct gl_framebuffer *)

yagears -b egl-fbdev -e gl

EGL for Linux Framebuffer internal

● eglSwapBuffers(EGLSurface)

→ egl_g3d_swap_buffers() in Mesa/src/gallium/state_trackers/egl/common/egl_g3d_api.c

→ fbdev_surface_present() in Mesa/src/gallium/state_trackers/egl/fbdev/native_fbdev.c

→ resource_surface_present() in Mesa/src/gallium/state_trackers/egl/common/native_helper.c

→ softpipe_flush_frontbuffer() in Mesa/src/gallium/drivers/softpipe/sp_screen.c

→ fbdev_displaytarget_display() in Mesa/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c

yagears -b egl-fbdev -e gl

● EGL_LOG_LEVEL = debug to print some informations

copy of 3D drawing based on OpenGL API to fbmem

Contents

1.Getting started

2.Some tools

3.Drawing libraries

4.OpenGL rendering

5.Multimedia frameworks

6.Graphics abstraction layers

7.User interface toolkits

8.Extra

Multimedia frameworks

● Multimedia frameworks (FFmpeg, GStreamer, Xine, VLC) provide an output based on the Linux Framebuffer

● Display of the decoded video is CPU based

no video overlay

FFmpeg

FFmpeg internalFFmpeg https://git.ffmpeg.org/ffmpeg.git

ffmpeg in fftools or root directory

→ avcodec_register_all() / av_register_all()

→ avdevice_register_all() in libavdevice/alldevices.c

→ av_register_output_format(fbdev_muxer) in libavformat/utils.c

→ parse_options() in cmdutils.c

→ AVFormatContext *ic = avformat_alloc_context(), av_open_input_file(ic, …)

→ AVFormatContext *oc = avformat_alloc_context(), av_guess_format("fbdev"),

av_new_stream(oc), av_guess_codec(fbdev_muxer) CODEC_ID_RAWVIDEO

→ transcode() in ffmpeg.c

→ av_write_header(oc) in libavformat/utils.c

→ fbdev_write_header(oc) in libavdevice/fbdev_enc.c→ fbmem = mmap() on /dev/fb0

→ av_read_frame(ic, AVPacket *)

→ avcodec_decode_video(ic­>streams[0]­>codec, AVFrame *, AVPacket *)

→ avcodec_encode_video(oc­>streams[0]­>codec, AVPacket *, AVFrame *)

→ av_interleaved_write_frame(oc, AVPacket *) in libavformat/utils.c

→ fbdev_write_packet(oc, AVPacket *) in libavdevice/fbdev_enc.c

copy to fbmem

GStreamer

GStreamer internal● GStreamer https://gitlab.freedesktop.org/gstreamer/gstreamer

gst-launch in tools directory

→ gst_init()

→ GstElement * gst_parse_launchv("... ! fbdevsink ...")

→ gst_parse_launch_full() in gstreamer/gst/gstparse.c

→ gst_element_factory_make() in gstreamer/gst/gstelementfactory.c

→ g_object_new(GST_TYPE_FBDEVSINK) from GLib→ gst_fbdevsink_class_init() in gst-plugins-bad/sys/fbdev/gstfbdevsink.c

→ gst_element_set_state(GstElement *, GST_STATE_PLAYING);

→ Decoding (for example by Libavcodec from FFmpeg through GStreamer Libav plug-in)

● Rendering to Linux Framebuffer in GStreamer Bad Plug-ins

https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad

→ gst_fbdevsink_start() in gst-plugins-bad/sys/fbdev/gstfbdevsink.c

→ fbmem = mmap() on /dev/fb0

in gst-plugins-bad/sys/fbdev/gstfbdevsink.c

→ gst_fbdevsink_render() on GStreamer 0.10

→ gst_fbdevsink_show_frame() on GStreamer 1 copy to fbmem

Xine

Xine internal● xine-lib

- https://sourceforge.net/p/xine/xine-lib

- https://sourceforge.net/p/xine/xine-lib-1.2

● xine-ui https://sourceforge.net/p/xine/xine-ui

fbxine in src/fb directory

→ xine_t * xine_new(), xine_init(xine_t *)

→ xine_video_port_t * xine_open_video_driver(xine_t *, "fb")

→ load_video_driver() in xine-lib/src/xine-engine/load_plugins.c

→ load_plugin_class() in xine-lib/src/xine-engine/load_plugins.c

→ fb_init_class() in xine-lib/src/video_out/video_out_fb.c→ fb_open_plugin() in xine-lib/src/video_out/video_out_fb.c

→ fbmem = mmap() on /dev/fb0

→ xine_stream_t * xine_stream_new(xine_t *, xine_video_port_t *)

→ xine_open(xine_stream_t *, ...), xine_play (xine_stream_t *)

→ Decoding (for example by Libavcodec from FFmpeg)

→ fb_display_frame() in xine-lib/src/video_out/video_out_fb.c copy to fbmem

VLC

VLC internalVLC https://git.videolan.org/?p=vlc.git

vlc in bin directory

→ libvlc_new("... ­­vout fb ...") in vlc/src/control/core.c

→ libvlc_InternalCreate(), libvlc_InternalInit() in vlc/src/libvlc.c

→ playlist_ThreadCreate() in vlc/src/playlist/thread.c

→ playlist_PlayItem() in vlc/src/playlist/control.c→ input_CreateThreadExtended() in vlc/src/input/input.c

→ input_DecoderNew() in vlc/src/input/decoder.c→ vout_Create() in vlc/src/video_output/video_output.c

→ module_Need() in vlc/src/modules/modules.c→ module_Call() in vlc/src/modules/os.c

→ vlc_entry() in vlc/modules/video_output/fb.c

→ Create() in vlc/modules/video_output/fb.c

→ fbmem = mmap() on /dev/fb0

→ Decoding (for example by Libavcodec from FFmpeg)

→ Display() in vlc/modules/video_output/fb.c copy to fbmem

Contents

1.Getting started

2.Some tools

3.Drawing libraries

4.OpenGL rendering

5.Multimedia frameworks

6.Graphics abstraction layers

7.User interface toolkits

8.Extra

GLUT

● GLUT https://gitlab.freedesktop.org/mesa/glut

Linux Framebuffer support in src/glut/fbdev directory

Note: EGL for Linux Framebuffer could be used instead of GLFBDev

● Examples– mesa-demos https://gitlab.freedesktop.org/mesa/demos

projtex, reflect, ... in src/demos directory

– yagears https://github.com/caramelli/yagears

GLUT demo

● glutInit()

● glutCreateWindow()

→ in MesaGLUT/src/glut/fbdev/fbdev.cfbmem = mmap() on /dev/fb0glFBDevCreateBuffer(), glFBDevSetWindow(struct fb_window *)glFBDevCreateContext(), glFBDevMakeCurrent()

● glutSwapBuffers()

→ in MesaGLUT/src/glut/fbdev/fbdev.cglFBDevSwapBuffers()

GLUT internal

copy of 3D drawing based on OpenGL API to fbmem

SDL

● SDL https://hg.libsdl.org/SDL

Linux Framebuffer support in src/video/fbcon directory

Note: GLFBDev extension could be used instead of EGL

● Examples– testsprite, testoverlay2, ... in test in directory

– yagears https://github.com/caramelli/yagears

SDL demo

SDL internal● SDL_Init()

→ SDL_VideoInit() in SDL/src/video/SDL_video.c

→ FB_VideoInit() in SDL/src/video/fbcon/SDL_fbvideo.c

→ fbmem = mmap() on /dev/fb0

● SDL_SetVideoMode() Set up window for drawing

→ FB_SetVideoMode() in SDL/src/video/fbcon/SDL_fbvideo.c

For OpenGL→ eglGetDisplay(), eglInitialize(), eglCreateWindowSurface(), eglCreateContext()

For OpenGL

→ FB_GL_MakeCurrent() in SDL/src/video/fbcon/SDL_fbvideo.c

→ eglMakeCurrent()

● SDL_Flip(), SDL_UpdateRects()

→ SDL_LowerBlit() in SDL/src/video/SDL_surface.c

→ SDL_SoftBlit() in SDL/src/video/SDL_blit.c

● For OpenGL, SDL_GL_SwapBuffers()

→ FB_GL_SwapBuffers() in SDL/src/video/fbcon/SDL_fbvideo.c–

→ eglSwapBuffers()

copy to fbmem

copy of 3D drawing based on OpenGL API to fbmem

Contents

1.Getting started

2.Some tools

3.Drawing libraries

4.OpenGL rendering

5.Multimedia frameworks

6.Graphics abstraction layers

7.User interface toolkits

8.Extra

EFL

● EFL

https://git.enlightenment.org/core/elementary.git/

https://git.enlightenment.org/core/efl.git/ or https://git.enlightenment.org/legacy/{ecore.git,evas.git,...}/

– Linux Framebuffer support in ecore/src/lib/ecore_evas/ecore_evas_fb.c and ecore/src/lib/ecore_fb directory

– Evas_GL interfaces in evas/src/lib/canvas/evas_gl.c

Note: EGL for Linux Framebuffer could be used instead of GLFBDev

● Examples– elementary_test in elementary/src/bin in directory

– yagears https://github.com/caramelli/yagears

EFL demo

EFL internal

● elm_init()

● elm_win_add() toplevel window for widgets drawing

→ ecore_evas_fb_new() in ecore/src/lib/ecore_evas/ecore_evas_fb.c

→ evas_new(), evas_output_method_set("fb"), evas_engine_info_set()

fbmem = mmap() on /dev/fb0

● elm_run()

→ ecore_main_loop_begin() in ecore/src/lib/ecore/ecore_main.c

→ ecore_evas_idle_enter() in ecore/src/lib/ecore_evas/ecore_evas.c

→ ecore_evas_fb_render() in ecore/src/lib/ecore_evas/ecore_evas_fb.c→ evas_render_updates()

→ output_redraws_next_update_push() in evas/engines/fb/evas_engine.c

copy to fbmem

EFL internalFor OpenGL

● elm_glview_add()

→ evas_gl_surface_create()

→ gl_surface_create() in evas/engines/fb/evas_engine.c→ glFBDevCreateBuffer()

→ evas_gl_context_create()

→ gl_context_create() in evas/engines/fb/evas_engine.c→ glFBDevCreateBuffer()

● elm_glview_changed_set()

→ evas_gl_make_current()

→ gl_make_current() in evas/engines/fb/evas_engine.c→ glFBDevMakeCurrent()

→ evas_object_image_pixels_dirty_set() in evas/src/lib/canvas/evas_object_image.c

→ output_redraws_next_update_push() in evas/engines/fb/evas_engine.c→ glFBDevSetWindow(struct fb_window *), glFBDevSwapBuffers()

copy of 3D drawing based on OpenGL API to fbmem

GTK+

● GTK+ https://gitlab.gnome.org/GNOME/gtk– Linux Framebuffer support in gdk/linux-fb directory

– GtkGLArea interfaces in gtkgl/gtkglarea.c

Note: EGL for Linux Framebuffer could be used instead of GLFBDev

● Examples– gtk-demo in demos/gtk-demo directory

– yagears https://github.com/caramelli/yagears

GTK+ demo

● gtk_init()

→ gdk_pre_parse_libgtk_only() in gtk/gdk/gdk.c

→ gdk_fb_display_new() in gtk/gdk/linux-fb/gdkmain-fb.c

→ fbmem = mmap() on /dev/fb0

● gtk_window_new() toplevel window for widgets drawing

● gtk_main()

→ gdk_drawable_ref_cairo_surface() in gtk/gdk/gdkdraw.c

→ gdk_fb_ref_cairo_surface() in gtk/gdk/linux-fb/gdkdrawable-fb2.c

→ cairo_image_surface_create()

→ gdk_draw_drawable() in gtk/gdk/gdkdraw.c

→ gdk_fb_draw_drawable() in gtk/gdk/linux-fb/gdkdrawable-fb2.c

→ gdk_fb_draw_drawable_memmove() in gtk/gdk/linux-fb/gdkrender-fb.c→ cairo_image_surface_get_data()

GTK+ internal

copy to fbmem

For OpenGL● gtk_gl_area_new()

→ gdk_gl_context_share_new() in gtk/gtkgl/gdkgl.c

→ glFBDevCreateBuffer(), glFBDevCreateContext()

● gtk_gl_area_make_current()

→ gdk_gl_make_current() in gtk/gtkgl/gdkgl.c

→ glFBDevMakeCurrent()

● gtk_gl_area_swap_buffers()

→ gdk_gl_swap_buffers() in gtk/gtkgl/gdkgl.c

→ glFBDevSetWindow(struct fb_window *), glFBDevSwapBuffers()

GTK+ internal

copy of 3D drawing based on OpenGL API to fbmem

WebKitGTK+

WebKitGTK+ https://svn.webkit.org/repository/webkit/releases/WebKitGTK

→ Tools/GtkLauncher

→ Source/WebKit/gtk WebView widget

→ Source/WebCore/platform/{gtk, graphics/gtk, graphics/gstreamer}

WebKitGTK+ demo● WebGL demos https://github.com/KhronosGroup/WebGL● Plyr HTML5 media player https://github.com/sampotts/plyr

Qt

● Qt 4 https://code.qt.io/cgit/qt/qt.git and QT 5 https://code.qt.io/cgit/qt/qtbase.git– Linux Framebuffer support for Qt 4 in src/plugins/gfxdrivers/linuxfb directory QWS (Qt Windowing System)

– Linux Framebuffer support for Qt 5 in src/plugins/platforms/linuxfb directory QPA (Qt Platform Abstraction)

– QtOpenGL interfaces in src/opengl/qgl.cpp

Note: GLFBDev extension could be used instead of EGL

● Examples– qtdemo in demos/qtdemo directory

– yagears https://github.com/caramelli/yagears

Qt demo

● QApplication::QApplication()

→ qt_init() in qt/src/gui/kernel/qapplication_qws.cpp

→ QWSServer::startup() in qt/src/gui/embedded/qwindowsystem_qws.cpp

→ qt_init_display() in qt/src/gui/kernel/qapplication_qws.cpp→ qt_get_screen() in qt/src/gui/embedded/qscreen_qws.cpp

→ QscreenDriverFactory::create() in qt/src/gui/embedded/qscreendriverfactory_qws.cpp→ QScreenLinuxFbPlugin::create() in qt/src/plugins/gfxdrivers/linuxfb/main.cpp

→ QlinuxFbScreen::QlinuxFbScreen() in qt/src/gui/embedded/qscreenlinuxfb_qws.cpp

→ QLinuxFbScreen::connect() in qt/src/gui/embedded/qscreenlinuxfb_qws.cpp→ fbmem = mmap() on /dev/fb0

● QWidget  class for widgets drawing

● Qapplication::exec()

→ qt/src/gui/painting/qdrawhelper.cpp

Qt internal

copy to fbmem

For OpenGL● QGLWidget class for OpenGL rendering

→ QEglContext::chooseConfig() in qt/src/gui/egl/qegl.cpp

→ eglGetDisplay(), eglInitialize()→ QEglContext::createContext() in qt/src/gui/egl/qegl.cpp

→ eglCreateContext()→ QGLWidget::glInit() in qt/src/opengl/qgl.cpp

→ qt_egl_create_surface() in qt/src/opengl/qgl_qws.cpp→ struct fb_window * QlinuxFbScreenSurfaceFunctions::createNativeWindow() in qt/src/gui/embedded/qscreenlinuxfb_qws.cpp→ eglCreateWindowSurface(struct fb_window *)

● QGLWidget::updateGL()

→ QeglContext::makeCurrent() in qt/src/gui/egl/qegl.cpp

→ eglMakeCurrent()→ QEglContext::swapBuffers() in qt/src/gui/egl/qegl.cpp

→ eglSwapBuffers()

Qt internal

copy of 3D drawing based on OpenGL API to fbmem

QtWebKit

QtWebKit for QT 4 https://gitorious.org/webkit/qtwebkit or https://gitorious.org/webkit/qtwebkit-23

QtWebKit for QT 5 https://code.qt.io/cgit/qt/qtwebkit.git

→ Tools/QtTestBrowser

→ Source/WebKit/qt WebView widget

→ Source/WebCore/platform/{qt, graphics/qt, graphics/gstreamer}

QtWebKit demo● WebGL demos https://github.com/KhronosGroup/WebGL● Plyr HTML5 media player https://github.com/sampotts/plyr

Contents

1.Getting started

2.Some tools

3.Drawing libraries

4.OpenGL rendering

5.Multimedia frameworks

6.Graphics abstraction layers

7.User interface toolkits

8.Extra

Running DirectFB, X11 or Wayland on top of the Linux Framebuffer

DirectFB https://github.com/deniskropp/DirectFB

→ Linux Framebuffer support in systems/fbdev directory

X11 https://gitlab.freedesktop.org/xorg/driver/xf86-video-fbdev

→ Xorg Device Dependent X (DDX) for Linux Framebuffer

Wayland https://gitlab.freedesktop.org/wayland

→ Linux Framebuffer support in weston/src/compositor-fbdev.c

But it's another story ...

Origins of this presentation ?

● Started a Linux from scratch distribution in 2005 for understanding how graphics work, and have continued to play with for the past 15 years

● Realized that some graphics backends will not be maintained anymore, and now belong to the past

● More infos on https://github.com/caramelli/higfxback/wiki

HiGFXback (History of graphics backends) project in order to preserve them