Remove gtk-webkit and replace with sdl2-opengl

This commit is contained in:
blackle 2019-06-15 00:26:38 -04:00
parent a8ea838715
commit d317e693b0
8 changed files with 155 additions and 79 deletions

1
.gitignore vendored
View File

@ -2,4 +2,5 @@
gtk-webkit
gtk-opengl
xlib-opengl
sdl2-opengl
shader.h

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "Section-Header-Stripper"]
path = Section-Header-Stripper
url = https://github.com/blackle/Section-Header-Stripper
[submodule "noelfver"]
path = noelfver
url = https://gitlab.com/PoroCYon/noelfver

View File

@ -1,7 +1,19 @@
all : gtk-webkit gtk-opengl xlib-opengl
CFLAGS := -fno-plt -O1 -std=gnu11 -nostartfiles -Wall -Wextra
CFLAGS += -fno-stack-protector -fno-stack-check -fno-unwind-tables -fno-asynchronous-unwind-tables -fomit-frame-pointer
CFLAGS += -no-pie -fno-pic -fno-PIE -fno-PIC -march=core2 -ffunction-sections -fdata-sections
.PHONY: clean
.PHONY: clean checkgccversion noelfver
all : checkgccversion gtk-opengl xlib-opengl sdl2-opengl
noelfver:
make -C noelfver
checkgccversion :
ifneq ($(shell expr `gcc -dumpversion`),8.3.0)
$(error GCC version must be 8.3.0)
endif
packer : vondehi/vondehi.asm
cd vondehi; nasm -fbin -o vondehi vondehi.asm
@ -9,18 +21,14 @@ packer : vondehi/vondehi.asm
shader.h : shader.frag Makefile
mono ./shader_minifier.exe --preserve-externals shader.frag -o shader.h
# not using `pkg-config --libs` here because it will include too many libs
gtk-webkit.elf : gtk-webkit.c index.html.inc Makefile
gcc -o $@ $< `pkg-config --cflags webkit2gtk-4.0` -lgobject-2.0 -lgtk-3 -lwebkit2gtk-4.0 -no-pie -fno-plt -Os -std=gnu11 -nostartfiles -nostdlib
gtk-opengl.elf : gtk-opengl.c shader.h Makefile
gcc -o $@ $< `pkg-config --cflags gtk+-3.0` -lGL -lgtk-3 -lgdk-3 -lgobject-2.0 -no-pie -fno-plt -Os -std=gnu11 -nostartfiles -nostdlib
gcc -o $@ $< `pkg-config --cflags gtk+-3.0` -lGL -lgtk-3 -lgdk-3 -lgobject-2.0 $(CFLAGS)
xlib-opengl.elf : xlib-opengl.c shader.h Makefile
gcc -o $@ $< -lX11 -lGL -lcairo -lXrandr -no-pie -fno-plt -Os -std=gnu11 -nostartfiles -nostdlib
gcc -o $@ $< -lX11 -lGL -lXrandr $(CFLAGS)
gtk-webkit : gtk-webkit_opt.elf.packed
mv $< $@
sdl2-opengl.elf : sdl2-opengl.c shader.h Makefile
gcc -o $@ $< -lSDL2 -lGL $(CFLAGS)
gtk-opengl : gtk-opengl_opt.elf.packed
mv $< $@
@ -28,15 +36,20 @@ gtk-opengl : gtk-opengl_opt.elf.packed
xlib-opengl : xlib-opengl_opt.elf.packed
mv $< $@
sdl2-opengl : sdl2-opengl_opt.elf.packed
mv $< $@
index.html.inc : index.html
cat index.html | xxd -i > index.html.inc
echo ", 0" >> index.html.inc
#all the rest of these rules just takes a compiled elf file and generates a packed version of it with vondehi
%_opt.elf : %.elf Makefile
%_opt.elf : %.elf Makefile noelfver
cp $< $@
strip $@
strip -R .note -R .comment -R .eh_frame -R .eh_frame_hdr -R .note.gnu.build-id -R .got -R .got.plt -R .gnu.version -R .rela.dyn -R .shstrtab $@
strip -R .note -R .comment -R .eh_frame -R .eh_frame_hdr -R .note.gnu.build-id -R .got -R .got.plt -R .gnu.version -R .shstrtab -R .gnu.version_r -R .gnu.hash $@
./noelfver/noelfver $@ > $@.nover
mv $@.nover $@
#remove section header
./Section-Header-Stripper/section-stripper.py $@
@ -44,14 +57,13 @@ index.html.inc : index.html
sed -i 's/_edata/\x00\x00\x00\x00\x00\x00/g' $@;
sed -i 's/__bss_start/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/g' $@;
sed -i 's/_end/\x00\x00\x00\x00/g' $@;
sed -i 's/GLIBC_2\.2\.5/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/g' $@;
wc -c $@
chmod +x $@
%.xz : % Makefile
-rm $@
lzma --format=lzma -9 --extreme --lzma1=preset=9,lc=1,lp=0,pb=1,nice=270,depth=64,dict=16384 --keep --stdout $< > $@
wc -c $@
lzma --format=lzma -9 --extreme --lzma1=preset=9,lc=0,lp=0,pb=0,nice=40,depth=32,dict=16384 --keep --stdout $< > $@
%.packed : %.xz packer Makefile
cat ./vondehi/vondehi $< > $@
@ -59,4 +71,4 @@ index.html.inc : index.html
wc -c $@
clean :
-rm *.elf shader.h gtk-webkit gtk-opengl xlib-opengl
-rm *.elf shader.h gtk-opengl xlib-opengl sdl2-opengl

View File

@ -1,15 +1,18 @@
# Linux-OpenGL-Examples
Some code examples for opening windows for various purposes in very few bytes. The examples mostly do the same thing, the only difference being gtk-webkit uses a different shader source, and is also heavily unoptimized.
Here are examples of rendering a shader full screen on linux. All of these examples do it in less than 2 kilobytes thanks to vondehi and copious amounts of ELF stripping.
## gtk-opengl - 1292 bytes
There are three examples, each using a different library to open a window and get an opengl context.
Example code for opening a glsl shader fullscreen with gtk. Closes with the standard ALT+F4 on Ubuntu. Renders the shader once on load.
## xlib-opengl - 1503 bytes
## gtk-webkit - 1482 bytes
Vanilla xlib is the largest of the bunch and the most brittle. It is highly not recommended to use xlib in a demo unless you cannot assume these other libraries will be on the system.
Example code for opening a webgl enabled html page fullscreen with gtk and webkit. Closes with the standard ALT+F4 on Ubuntu. WebGL is used to display a shader full screen with some very unoptimized javascript. Like gtk-opengl, the shader is rendered once. Optimizing the js for size will probably take off another 100 bytes or two.
## gtk-opengl - 1396 bytes
## xlib-opengl - 1474 bytes
GTK is a step up from xlib, being both smaller and more robust. If the compo you are entering doesn't allow using SDL2, GTK is an ok alternative. Before switching to GCC 8.3.0, this was 100 bytes smaller than it is now. I am not sure why it is larger, but this likely means it can be sizecoded/stripped further.
## sdl2-opengl - 1010 bytes
Using SDL2 will give you very small binaries. Use SDL2 whenever you can, as it also has a few other useful subsystems at minimal cost (for example, audio.)
Example code for opening a glsl shader fullscreen with vanilla xlib. Like gtk-opengl and gtk-webkit, the shader is rendered once. Unlike gtk-opengl, the window must be closed with ESC. This code is based on the code for Cenotaph For Soda, a 4k gfx demo for Revision 2018. OPINION: xlib feels the most fragile of the bunch here...

View File

@ -14,7 +14,7 @@
#include <GL/glext.h>
#include "shader.h"
static char* vshader = "#version 450\nvec2 y=vec2(1.,-1);\nvec4 x[4]={y.yyxx,y.xyxx,y.yxxx,y.xxxx};void main(){gl_Position=x[gl_VertexID];}";
static char* vshader = "#version 450\nvec2 y=vec2(1.,-1);vec4 x[4]={y.yyxx,y.xyxx,y.yxxx,y.xxxx};void main(){gl_Position=x[gl_VertexID];}";
#define CANVAS_WIDTH 1920
#define CANVAS_HEIGHT 1080

View File

@ -1,55 +0,0 @@
#define GL_GLEXT_PROTOTYPES why
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<stdint.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <webkit2/webkit2.h>
#define CANVAS_WIDTH 1920
#define CANVAS_HEIGHT 1080
gboolean on_load_changed(WebKitWebView *web_view, WebKitLoadEvent load_event, GtkWindow* window)
{
if (load_event == WEBKIT_LOAD_FINISHED) {
gtk_widget_show_all(GTK_WIDGET(window));
gtk_window_fullscreen(window);
}
return TRUE;
}
static char html[] = {
#include "index.html.inc"
};
void _start() {
asm volatile("sub $8, %rsp\n");
typedef void (*voidWithOneParam)(int*);
voidWithOneParam gtk_init_one_param = (voidWithOneParam)gtk_init;
(*gtk_init_one_param)(NULL);
GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
WebKitSettings *webSettings = webkit_settings_new_with_settings("enable-webgl", TRUE, NULL);
WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_settings(webSettings));
webkit_web_view_load_html(webView, html, NULL);
gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(webView));
g_signal_connect(win, "destroy", gtk_main_quit, NULL);
g_signal_connect(webView, "load-changed", G_CALLBACK(on_load_changed), (GtkWindow*)(win));
gtk_main();
asm volatile(".intel_syntax noprefix");
asm volatile("push 231"); //exit_group
asm volatile("pop rax");
// asm volatile("xor edi, edi");
asm volatile("syscall");
asm volatile(".att_syntax prefix");
__builtin_unreachable();
}

1
noelfver Submodule

@ -0,0 +1 @@
Subproject commit 3022b4ef8bb37db07b0008f7eb7f9839ffac8cd0

111
sdl2-opengl.c Normal file
View File

@ -0,0 +1,111 @@
#define GL_GLEXT_PROTOTYPES
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<stdint.h>
#include <SDL2/SDL.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
#include <GL/glext.h>
#include "shader.h"
#define CANVAS_WIDTH 1920
#define CANVAS_HEIGHT 1080
// #define KEY_HANDLING
// #define DEBUG
static void on_render ()
{
glRecti(-1,-1,1,1);
}
static void on_realize()
{
// compile shader
GLuint f = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(f, 1, &shader_frag, NULL);
glCompileShader(f);
#ifdef DEBUG
GLint isCompiled = 0;
glGetShaderiv(f, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE) {
GLint maxLength = 0;
glGetShaderiv(f, GL_INFO_LOG_LENGTH, &maxLength);
char* error = malloc(maxLength);
glGetShaderInfoLog(f, maxLength, &maxLength, error);
printf("%s\n", error);
exit(-10);
}
#endif
// link shader
GLuint p = glCreateProgram();
glAttachShader(p,f);
glLinkProgram(p);
#ifdef DEBUG
GLint isLinked = 0;
glGetProgramiv(p, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE) {
GLint maxLength = 0;
glGetProgramiv(p, GL_INFO_LOG_LENGTH, &maxLength);
char* error = malloc(maxLength);
glGetProgramInfoLog(p, maxLength, &maxLength,error);
printf("%s\n", error);
exit(-10);
}
#endif
glUseProgram(p);
}
void _start() {
asm volatile("sub $8, %rsp\n");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
SDL_Window* mainwindow = SDL_CreateWindow(
"",
0,
0,
CANVAS_WIDTH,
CANVAS_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN
);
SDL_GL_CreateContext(mainwindow);
SDL_ShowCursor(false);
on_realize();
while (true) {
SDL_Event Event;
while (SDL_PollEvent(&Event)) {
if (Event.type == SDL_QUIT
#if defined(KEY_HANDLING)
|| (Event.type == SDL_KEYDOWN && Event.key.keysym.sym == SDLK_ESCAPE)
#endif
) {
exit(0);
}
if (Event.type == SDL_WINDOWEVENT) {
switch(Event.window.event) {
case SDL_WINDOWEVENT_EXPOSED:
on_render();
SDL_GL_SwapWindow(mainwindow);
default:
break;
}
}
}
}
__builtin_unreachable();
}