static int gltex_set(struct kmscon_text *txt) { struct gltex *gt = txt->data; int ret; static char *attr[] = { "position", "texture_position", "fgcolor", "bgcolor" }; GLint s; const char *ext; struct uterm_mode *mode; bool opengl; memset(gt, 0, sizeof(*gt)); shl_dlist_init(>->atlases); ret = shl_hashtable_new(>->glyphs, shl_direct_hash, shl_direct_equal, NULL, free_glyph); if (ret) return ret; ret = shl_hashtable_new(>->bold_glyphs, shl_direct_hash, shl_direct_equal, NULL, free_glyph); if (ret) goto err_htable; ret = uterm_display_use(txt->disp, &opengl); if (ret < 0 || !opengl) { if (ret == -EOPNOTSUPP) log_error("display doesn't support hardware-acceleration"); goto err_bold_htable; } gl_clear_error(); ret = gl_shader_new(>->shader, gl_static_gltex_vert, gl_static_gltex_frag, attr, 4, log_llog, NULL); if (ret) goto err_bold_htable; gt->uni_proj = gl_shader_get_uniform(gt->shader, "projection"); gt->uni_atlas = gl_shader_get_uniform(gt->shader, "atlas"); gt->uni_advance_htex = gl_shader_get_uniform(gt->shader, "advance_htex"); gt->uni_advance_vtex = gl_shader_get_uniform(gt->shader, "advance_vtex"); if (gl_has_error(gt->shader)) { log_warning("cannot create shader"); goto err_shader; } mode = uterm_display_get_current(txt->disp); gt->sw = uterm_mode_get_width(mode); gt->sh = uterm_mode_get_height(mode); txt->cols = gt->sw / FONT_WIDTH(txt); txt->rows = gt->sh / FONT_HEIGHT(txt); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &s); if (s <= 0) s = 64; else if (s > 2048) s = 2048; gt->max_tex_size = s; gl_clear_error(); ext = (const char*)glGetString(GL_EXTENSIONS); if (ext && strstr((const char*)ext, "GL_EXT_unpack_subimage")) { gt->supports_rowlen = true; } else { log_warning("your GL implementation does not support GL_EXT_unpack_subimage, glyph-rendering may be slower than usual"); } return 0; err_shader: gl_shader_unref(gt->shader); err_bold_htable: shl_hashtable_free(gt->bold_glyphs); err_htable: shl_hashtable_free(gt->glyphs); return ret; }
static int init_shaders(struct uterm_video *video) { struct uterm_drm3d_video *v3d = uterm_drm_video_get_data(video); int ret; char *fill_attr[] = { "position", "color" }; char *blend_attr[] = { "position", "texture_position" }; char *blit_attr[] = { "position", "texture_position" }; int blend_vlen, blend_flen, blit_vlen, blit_flen, fill_vlen, fill_flen; const char *blend_vert, *blend_frag; const char *blit_vert, *blit_frag; const char *fill_vert, *fill_frag; if (v3d->sinit == 1) return -EFAULT; else if (v3d->sinit == 2) return 0; v3d->sinit = 1; blend_vert = _binary_src_uterm_drm3d_blend_vert_bin_start; blend_vlen = _binary_src_uterm_drm3d_blend_vert_bin_end - blend_vert; blend_frag = _binary_src_uterm_drm3d_blend_frag_bin_start; blend_flen = _binary_src_uterm_drm3d_blend_frag_bin_end - blend_frag; blit_vert = _binary_src_uterm_drm3d_blit_vert_bin_start; blit_vlen = _binary_src_uterm_drm3d_blit_vert_bin_end - blit_vert; blit_frag = _binary_src_uterm_drm3d_blit_frag_bin_start; blit_flen = _binary_src_uterm_drm3d_blit_frag_bin_end - blit_frag; fill_vert = _binary_src_uterm_drm3d_fill_vert_bin_start; fill_vlen = _binary_src_uterm_drm3d_fill_vert_bin_end - fill_vert; fill_frag = _binary_src_uterm_drm3d_fill_frag_bin_start; fill_flen = _binary_src_uterm_drm3d_fill_frag_bin_end - fill_frag; ret = gl_shader_new(&v3d->fill_shader, fill_vert, fill_vlen, fill_frag, fill_flen, fill_attr, 2, log_llog, NULL); if (ret) return ret; v3d->uni_fill_proj = gl_shader_get_uniform(v3d->fill_shader, "projection"); ret = gl_shader_new(&v3d->blend_shader, blend_vert, blend_vlen, blend_frag, blend_flen, blend_attr, 2, log_llog, NULL); if (ret) return ret; v3d->uni_blend_proj = gl_shader_get_uniform(v3d->blend_shader, "projection"); v3d->uni_blend_tex = gl_shader_get_uniform(v3d->blend_shader, "texture"); v3d->uni_blend_fgcol = gl_shader_get_uniform(v3d->blend_shader, "fgcolor"); v3d->uni_blend_bgcol = gl_shader_get_uniform(v3d->blend_shader, "bgcolor"); ret = gl_shader_new(&v3d->blit_shader, blit_vert, blit_vlen, blit_frag, blit_flen, blit_attr, 2, log_llog, NULL); if (ret) return ret; v3d->uni_blit_proj = gl_shader_get_uniform(v3d->blit_shader, "projection"); v3d->uni_blit_tex = gl_shader_get_uniform(v3d->blit_shader, "texture"); gl_tex_new(&v3d->tex, 1); v3d->sinit = 2; return 0; }
static int set_outputs(struct uterm_video *video) { struct uterm_display *iter; int j, ret; struct gl_shader *shader; struct uterm_screen *screen; ret = gl_shader_new(&shader); if (ret) { log_err("Cannot create shader: %d", ret); return ret; } j = 0; iter = uterm_video_get_displays(video); for ( ; iter; iter = uterm_display_next(iter)) { log_notice("Activating display %d %p...", j, iter); ret = uterm_display_activate(iter, NULL); if (ret) log_err("Cannot activate display %d: %d", j, ret); else log_notice("Successfully activated display %d", j); ret = uterm_display_set_dpms(iter, UTERM_DPMS_ON); if (ret) log_err("Cannot set DPMS to ON: %d", ret); ++j; } iter = uterm_video_get_displays(video); for ( ; iter; iter = uterm_display_next(iter)) { if (uterm_display_get_state(iter) != UTERM_DISPLAY_ACTIVE) continue; ret = uterm_screen_new_single(&screen, iter); if (ret) { log_err("Cannot create temp-screen object: %d", ret); continue; } ret = uterm_screen_use(screen); if (ret) { log_err("Cannot use screen: %d", ret); uterm_screen_unref(screen); continue; } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, uterm_screen_width(screen), uterm_screen_height(screen)); gl_shader_draw_def(shader, d_vert, d_col, 6); if (gl_has_error()) log_err("GL error occurred"); ret = uterm_screen_swap(screen); if (ret) { log_err("Cannot swap screen: %d", ret); uterm_screen_unref(screen); continue; } log_notice("Successfully set screen on display %p", iter); uterm_screen_unref(screen); } log_notice("Waiting 5 seconds..."); ev_eloop_run(eloop, 5000); log_notice("Exiting..."); gl_shader_unref(shader); return 0; }