From 9c8bf69a53f628b62fb196182ea55fb34c1c19e1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 15 Feb 2024 20:53:28 -0700 Subject: [PATCH] loader: Only create gfx 4th bindings when gfx is available Only create the gfx bindings for 4th when it's compiled into the loader. We do this with a linker set that only gets brought in to those loaders that call gfx_framework_init. This calls gfx_interp_md() will will drag in gfx_loader.c which will add to the linker set that registers these bindings. Sponsored by: Netflix Reviewed by: kevans, jhb Differential Revision: https://reviews.freebsd.org/D43904 --- stand/common/gfx_fb.c | 1 + stand/ficl/Makefile | 5 +- stand/ficl/gfx_loader.c | 259 ++++++++++++++++++++++++++++++++++++++++ stand/ficl/loader.c | 188 ----------------------------- 4 files changed, 263 insertions(+), 190 deletions(-) create mode 100644 stand/ficl/gfx_loader.c diff --git a/stand/common/gfx_fb.c b/stand/common/gfx_fb.c index b61591bf3d45..3a5b851915e0 100644 --- a/stand/common/gfx_fb.c +++ b/stand/common/gfx_fb.c @@ -181,6 +181,7 @@ gfx_framework_init(void) * Setup font list to have builtin font. */ (void) insert_font(NULL, FONT_BUILTIN); + gfx_interp_md(); /* Draw in the gfx interpreter for this thing */ } static uint8_t * diff --git a/stand/ficl/Makefile b/stand/ficl/Makefile index a9b384024667..fe4ee03974b1 100644 --- a/stand/ficl/Makefile +++ b/stand/ficl/Makefile @@ -11,8 +11,8 @@ BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \ SRCS= ${BASE_SRCS} sysdep.c softcore.c CLEANFILES+= softcore.c testmain testmain.o -CFLAGS.loader.c += -I${SRCTOP}/sys/teken -CFLAGS.loader.c += -I${SRCTOP}/contrib/pnglite +CFLAGS.gfx_loader.c += -I${SRCTOP}/sys/teken +CFLAGS.gfx_loader.c += -I${SRCTOP}/contrib/pnglite .ifmake testmain CFLAGS= -DTESTMAIN -D_TESTMAIN CFLAGS+= -I${FICLSRC} -I${FICLSRC}/${FICL_CPUARCH} -I${LDRSRC} @@ -21,6 +21,7 @@ PROG= testmain .include .else LIB= ficl +BASE_SRCS+= gfx_loader.c # Not TESTMAINable .include .endif diff --git a/stand/ficl/gfx_loader.c b/stand/ficl/gfx_loader.c new file mode 100644 index 000000000000..a4501a7d3c39 --- /dev/null +++ b/stand/ficl/gfx_loader.c @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2024 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* Copied from a file that likely shoulve have had this at the top */ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2020 Toomas Soome + * Copyright 2020 RackTop Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/******************************************************************* +** g f x _ l o a d e r . c +** Additional FICL words designed for FreeBSD's loader +** for graphics +*******************************************************************/ + +#include +#include "bootstrap.h" +#include +#include +#include "ficl.h" + +/* FreeBSD's loader interaction words and extras + * for graphics + * fb-bezier ( x0 y0 x1 y1 x2 y2 wd -- ) + * fb-drawrect ( x1 y1 x2 y2 fill -- ) + * fb-line ( x0 y0 x1 y1 wd -- ) + * fb-putimage ( flags x1 y1 x2 y2 -- flag ) + * fb-setpixel ( x y -- ) + * term-drawrect ( x1 y1 x2 y2 fill -- ) + * term-putimage ( flags x1 y1 x2 y2 -- flag ) + */ + +/* ( flags x1 y1 x2 y2 -- flag ) */ +void +ficl_term_putimage(FICL_VM *pVM) +{ + char *namep, *name; + int names; + unsigned long ret = FICL_FALSE; + uint32_t x1, y1, x2, y2, f; + png_t png; + int error; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 7, 1); +#endif + names = stackPopINT(pVM->pStack); + namep = (char *) stackPopPtr(pVM->pStack); + y2 = stackPopINT(pVM->pStack); + x2 = stackPopINT(pVM->pStack); + y1 = stackPopINT(pVM->pStack); + x1 = stackPopINT(pVM->pStack); + f = stackPopINT(pVM->pStack); + + x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; + y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; + if (x2 != 0) { + x2 = gfx_state.tg_origin.tp_col + + x2 * gfx_state.tg_font.vf_width; + } + if (y2 != 0) { + y2 = gfx_state.tg_origin.tp_row + + y2 * gfx_state.tg_font.vf_height; + } + + name = ficlMalloc(names + 1); + if (!name) + vmThrowErr(pVM, "Error: out of memory"); + (void) strncpy(name, namep, names); + name[names] = '\0'; + + if ((error = png_open(&png, name)) != PNG_NO_ERROR) { + if (f & FL_PUTIMAGE_DEBUG) + printf("%s\n", png_error_string(error)); + } else { + if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) + ret = FICL_TRUE; /* success */ + (void) png_close(&png); + } + ficlFree(name); + stackPushUNS(pVM->pStack, ret); +} + +/* ( flags x1 y1 x2 y2 -- flag ) */ +void +ficl_fb_putimage(FICL_VM *pVM) +{ + char *namep, *name; + int names; + unsigned long ret = FICL_FALSE; + uint32_t x1, y1, x2, y2, f; + png_t png; + int error; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 7, 1); +#endif + names = stackPopINT(pVM->pStack); + namep = (char *) stackPopPtr(pVM->pStack); + y2 = stackPopINT(pVM->pStack); + x2 = stackPopINT(pVM->pStack); + y1 = stackPopINT(pVM->pStack); + x1 = stackPopINT(pVM->pStack); + f = stackPopINT(pVM->pStack); + + name = ficlMalloc(names + 1); + if (!name) + vmThrowErr(pVM, "Error: out of memory"); + (void) strncpy(name, namep, names); + name[names] = '\0'; + + if ((error = png_open(&png, name)) != PNG_NO_ERROR) { + if (f & FL_PUTIMAGE_DEBUG) + printf("%s\n", png_error_string(error)); + } else { + if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) + ret = FICL_TRUE; /* success */ + (void) png_close(&png); + } + ficlFree(name); + stackPushUNS(pVM->pStack, ret); +} + +void +ficl_fb_setpixel(FICL_VM *pVM) +{ + FICL_UNS x, y; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 2, 0); +#endif + + y = stackPopUNS(pVM->pStack); + x = stackPopUNS(pVM->pStack); + gfx_fb_setpixel(x, y); +} + +void +ficl_fb_line(FICL_VM *pVM) +{ + FICL_UNS x0, y0, x1, y1, wd; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 5, 0); +#endif + + wd = stackPopUNS(pVM->pStack); + y1 = stackPopUNS(pVM->pStack); + x1 = stackPopUNS(pVM->pStack); + y0 = stackPopUNS(pVM->pStack); + x0 = stackPopUNS(pVM->pStack); + gfx_fb_line(x0, y0, x1, y1, wd); +} + +void +ficl_fb_bezier(FICL_VM *pVM) +{ + FICL_UNS x0, y0, x1, y1, x2, y2, width; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 7, 0); +#endif + + width = stackPopUNS(pVM->pStack); + y2 = stackPopUNS(pVM->pStack); + x2 = stackPopUNS(pVM->pStack); + y1 = stackPopUNS(pVM->pStack); + x1 = stackPopUNS(pVM->pStack); + y0 = stackPopUNS(pVM->pStack); + x0 = stackPopUNS(pVM->pStack); + gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); +} + +void +ficl_fb_drawrect(FICL_VM *pVM) +{ + FICL_UNS x1, x2, y1, y2, fill; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 5, 0); +#endif + + fill = stackPopUNS(pVM->pStack); + y2 = stackPopUNS(pVM->pStack); + x2 = stackPopUNS(pVM->pStack); + y1 = stackPopUNS(pVM->pStack); + x1 = stackPopUNS(pVM->pStack); + gfx_fb_drawrect(x1, y1, x2, y2, fill); +} + +void +ficl_term_drawrect(FICL_VM *pVM) +{ + FICL_UNS x1, x2, y1, y2; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 4, 0); +#endif + + y2 = stackPopUNS(pVM->pStack); + x2 = stackPopUNS(pVM->pStack); + y1 = stackPopUNS(pVM->pStack); + x1 = stackPopUNS(pVM->pStack); + gfx_term_drawrect(x1, y1, x2, y2); +} + +/************************************************************************** + f i c l C o m p i l e G f x +** Build FreeBSD platform extensions into the system dictionary +** for gfx +**************************************************************************/ +static void ficlCompileGfx(FICL_SYSTEM *pSys) +{ + ficlCompileFcn **fnpp; + FICL_DICT *dp = pSys->dp; + assert (dp); + + dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT); + dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT); + dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT); + dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT); + dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT); + dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT); + dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT); + + return; +} +FICL_COMPILE_SET(ficlCompileGfx); + +void +gfx_interp_md(void) +{ +} diff --git a/stand/ficl/loader.c b/stand/ficl/loader.c index edde4f477d55..618d9483fbd9 100644 --- a/stand/ficl/loader.c +++ b/stand/ficl/loader.c @@ -44,8 +44,6 @@ #include "bootstrap.h" #include #include -#include -#include #include "ficl.h" /* FreeBSD's loader interaction words and extras @@ -65,182 +63,6 @@ * .# ( value -- ) */ -#ifndef TESTMAIN -/* ( flags x1 y1 x2 y2 -- flag ) */ -void -ficl_term_putimage(FICL_VM *pVM) -{ - char *namep, *name; - int names; - unsigned long ret = FICL_FALSE; - uint32_t x1, y1, x2, y2, f; - png_t png; - int error; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 7, 1); -#endif - names = stackPopINT(pVM->pStack); - namep = (char *) stackPopPtr(pVM->pStack); - y2 = stackPopINT(pVM->pStack); - x2 = stackPopINT(pVM->pStack); - y1 = stackPopINT(pVM->pStack); - x1 = stackPopINT(pVM->pStack); - f = stackPopINT(pVM->pStack); - - x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; - y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; - if (x2 != 0) { - x2 = gfx_state.tg_origin.tp_col + - x2 * gfx_state.tg_font.vf_width; - } - if (y2 != 0) { - y2 = gfx_state.tg_origin.tp_row + - y2 * gfx_state.tg_font.vf_height; - } - - name = ficlMalloc(names + 1); - if (!name) - vmThrowErr(pVM, "Error: out of memory"); - (void) strncpy(name, namep, names); - name[names] = '\0'; - - if ((error = png_open(&png, name)) != PNG_NO_ERROR) { - if (f & FL_PUTIMAGE_DEBUG) - printf("%s\n", png_error_string(error)); - } else { - if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) - ret = FICL_TRUE; /* success */ - (void) png_close(&png); - } - ficlFree(name); - stackPushUNS(pVM->pStack, ret); -} - -/* ( flags x1 y1 x2 y2 -- flag ) */ -void -ficl_fb_putimage(FICL_VM *pVM) -{ - char *namep, *name; - int names; - unsigned long ret = FICL_FALSE; - uint32_t x1, y1, x2, y2, f; - png_t png; - int error; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 7, 1); -#endif - names = stackPopINT(pVM->pStack); - namep = (char *) stackPopPtr(pVM->pStack); - y2 = stackPopINT(pVM->pStack); - x2 = stackPopINT(pVM->pStack); - y1 = stackPopINT(pVM->pStack); - x1 = stackPopINT(pVM->pStack); - f = stackPopINT(pVM->pStack); - - name = ficlMalloc(names + 1); - if (!name) - vmThrowErr(pVM, "Error: out of memory"); - (void) strncpy(name, namep, names); - name[names] = '\0'; - - if ((error = png_open(&png, name)) != PNG_NO_ERROR) { - if (f & FL_PUTIMAGE_DEBUG) - printf("%s\n", png_error_string(error)); - } else { - if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) - ret = FICL_TRUE; /* success */ - (void) png_close(&png); - } - ficlFree(name); - stackPushUNS(pVM->pStack, ret); -} - -void -ficl_fb_setpixel(FICL_VM *pVM) -{ - FICL_UNS x, y; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 2, 0); -#endif - - y = stackPopUNS(pVM->pStack); - x = stackPopUNS(pVM->pStack); - gfx_fb_setpixel(x, y); -} - -void -ficl_fb_line(FICL_VM *pVM) -{ - FICL_UNS x0, y0, x1, y1, wd; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 5, 0); -#endif - - wd = stackPopUNS(pVM->pStack); - y1 = stackPopUNS(pVM->pStack); - x1 = stackPopUNS(pVM->pStack); - y0 = stackPopUNS(pVM->pStack); - x0 = stackPopUNS(pVM->pStack); - gfx_fb_line(x0, y0, x1, y1, wd); -} - -void -ficl_fb_bezier(FICL_VM *pVM) -{ - FICL_UNS x0, y0, x1, y1, x2, y2, width; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 7, 0); -#endif - - width = stackPopUNS(pVM->pStack); - y2 = stackPopUNS(pVM->pStack); - x2 = stackPopUNS(pVM->pStack); - y1 = stackPopUNS(pVM->pStack); - x1 = stackPopUNS(pVM->pStack); - y0 = stackPopUNS(pVM->pStack); - x0 = stackPopUNS(pVM->pStack); - gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); -} - -void -ficl_fb_drawrect(FICL_VM *pVM) -{ - FICL_UNS x1, x2, y1, y2, fill; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 5, 0); -#endif - - fill = stackPopUNS(pVM->pStack); - y2 = stackPopUNS(pVM->pStack); - x2 = stackPopUNS(pVM->pStack); - y1 = stackPopUNS(pVM->pStack); - x1 = stackPopUNS(pVM->pStack); - gfx_fb_drawrect(x1, y1, x2, y2, fill); -} - -void -ficl_term_drawrect(FICL_VM *pVM) -{ - FICL_UNS x1, x2, y1, y2; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 4, 0); -#endif - - y2 = stackPopUNS(pVM->pStack); - x2 = stackPopUNS(pVM->pStack); - y1 = stackPopUNS(pVM->pStack); - x1 = stackPopUNS(pVM->pStack); - gfx_term_drawrect(x1, y1, x2, y2); -} -#endif /* TESTMAIN */ - void ficlSetenv(FICL_VM *pVM) { @@ -1042,16 +864,6 @@ void ficlCompilePlatform(FICL_SYSTEM *pSys) dictAppendWord(dp, "ccall", ficlCcall, FW_DEFAULT); dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT); dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT); -#ifndef TESTMAIN - dictAppendWord(dp, "fb-setpixel", ficl_fb_setpixel, FW_DEFAULT); - dictAppendWord(dp, "fb-line", ficl_fb_line, FW_DEFAULT); - dictAppendWord(dp, "fb-bezier", ficl_fb_bezier, FW_DEFAULT); - dictAppendWord(dp, "fb-drawrect", ficl_fb_drawrect, FW_DEFAULT); - dictAppendWord(dp, "fb-putimage", ficl_fb_putimage, FW_DEFAULT); - dictAppendWord(dp, "term-drawrect", ficl_term_drawrect, FW_DEFAULT); - dictAppendWord(dp, "term-putimage", ficl_term_putimage, FW_DEFAULT); - dictAppendWord(dp, "isvirtualized?",ficlIsvirtualizedQ, FW_DEFAULT); -#endif SET_FOREACH(fnpp, Xficl_compile_set) (*fnpp)(pSys);