mirror of
https://git.sr.ht/~calebccff/pbsplash
synced 2026-01-13 04:58:39 -09:00
drm: make optional
Make DRM configurable at build time to avoid increasing the size of pbsplash. DRM support is not yet suitable to be enabled by default, but it's nice to have it merged in so the code doesn't bitrot. Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
This commit is contained in:
parent
96d181885e
commit
1a6bb17cb1
10 changed files with 129 additions and 68 deletions
|
|
@ -12,6 +12,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "pbsplash.h"
|
#include "pbsplash.h"
|
||||||
|
|
||||||
/// Convenience macro used to shorten the signatures. Undefined at the end.
|
/// Convenience macro used to shorten the signatures. Undefined at the end.
|
||||||
|
|
@ -85,7 +86,11 @@
|
||||||
*/
|
*/
|
||||||
int tfb_acquire_fb(u32 flags, const char *fb_device, const char *tty_device);
|
int tfb_acquire_fb(u32 flags, const char *fb_device, const char *tty_device);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRM_SUPPORT
|
||||||
int tfb_acquire_drm(uint32_t flags, const char *device);
|
int tfb_acquire_drm(uint32_t flags, const char *device);
|
||||||
|
#else
|
||||||
|
#define tfb_acquire_drm(f, d) ({ -1; })
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release the framebuffer device
|
* Release the framebuffer device
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
#ifndef _FRAMEBUFFER_H
|
#pragma once
|
||||||
#define _FRAMEBUFFER_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRM_SUPPORT
|
||||||
|
|
||||||
#include <libdrm/drm.h>
|
#include <libdrm/drm.h>
|
||||||
#include <libdrm/drm_mode.h>
|
#include <libdrm/drm_mode.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
|
||||||
|
|
||||||
struct modeset_buf {
|
struct modeset_buf {
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
|
|
@ -32,6 +36,8 @@ struct drm_framebuffer {
|
||||||
|
|
||||||
extern struct drm_framebuffer *drm;
|
extern struct drm_framebuffer *drm;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
int drm_framebuffer_init(int *handle, const char *card);
|
int drm_framebuffer_init(int *handle, const char *card);
|
||||||
void drm_framebuffer_close(int handle);
|
void drm_framebuffer_close(int handle);
|
||||||
#endif
|
|
||||||
35
meson.build
35
meson.build
|
|
@ -3,12 +3,39 @@ cc = meson.get_compiler('c')
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
cc.find_library('m', required : false),
|
cc.find_library('m', required : false),
|
||||||
dependency('libdrm'),
|
|
||||||
dependency('libudev'),
|
dependency('libudev'),
|
||||||
]
|
]
|
||||||
|
|
||||||
inc = [
|
conf_data = configuration_data()
|
||||||
include_directories('include'),
|
use_drm = get_option('drm')
|
||||||
|
|
||||||
|
src = [
|
||||||
|
'src/animate.c',
|
||||||
|
'src/nanosvg.c',
|
||||||
|
'src/timespec.c',
|
||||||
|
'src/pbsplash.c',
|
||||||
|
'src/fb.c',
|
||||||
|
'src/drawing.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
subdir('src')
|
if use_drm.enabled()
|
||||||
|
deps += dependency('libdrm')
|
||||||
|
src += 'src/drm.c'
|
||||||
|
conf_data.set('CONFIG_DRM_SUPPORT', true)
|
||||||
|
else
|
||||||
|
src += 'src/drm_stub.c'
|
||||||
|
conf_data.set('CONFIG_DRM_SUPPORT', false)
|
||||||
|
endif
|
||||||
|
|
||||||
|
configure_file(output : 'config.h',
|
||||||
|
configuration : conf_data)
|
||||||
|
|
||||||
|
inc = [
|
||||||
|
include_directories('include'),
|
||||||
|
include_directories('.')
|
||||||
|
]
|
||||||
|
|
||||||
|
executable('pbsplash', src,
|
||||||
|
include_directories: inc,
|
||||||
|
dependencies: deps,
|
||||||
|
install: true)
|
||||||
|
|
|
||||||
1
meson_options.txt
Normal file
1
meson_options.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
option('drm', type : 'feature', value : 'disabled')
|
||||||
|
|
@ -8,9 +8,10 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "pbsplash.h"
|
#include "pbsplash.h"
|
||||||
#include "framebuffer.h"
|
|
||||||
#include "tfblib.h"
|
#include "tfblib.h"
|
||||||
|
|
||||||
|
#include "tfblib_drm.h"
|
||||||
|
|
||||||
#define DEBUGRENDER 0
|
#define DEBUGRENDER 0
|
||||||
|
|
||||||
extern inline uint32_t tfb_make_color(uint8_t red, uint8_t green, uint8_t blue);
|
extern inline uint32_t tfb_make_color(uint8_t red, uint8_t green, uint8_t blue);
|
||||||
|
|
@ -145,8 +146,10 @@ void tfb_fill_rect(int x, int y, int w, int h, uint32_t color)
|
||||||
dest = __fb_buffer + y * __fb_pitch + (x * 4);
|
dest = __fb_buffer + y * __fb_pitch + (x * 4);
|
||||||
|
|
||||||
/* drm alignment weirdness */
|
/* drm alignment weirdness */
|
||||||
|
#ifdef CONFIG_DRM_SUPPORT
|
||||||
if (drm)
|
if (drm)
|
||||||
w *= 4;
|
w *= 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (uint32_t cy = y; cy < yend; cy++, dest += __fb_pitch)
|
for (uint32_t cy = y; cy < yend; cy++, dest += __fb_pitch)
|
||||||
memset(dest, color, w);
|
memset(dest, color, w);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
|
||||||
#include "framebuffer.h"
|
#include "tfblib_drm.h"
|
||||||
|
|
||||||
struct modeset_buf;
|
struct modeset_buf;
|
||||||
struct drm_framebuffer;
|
struct drm_framebuffer;
|
||||||
|
|
|
||||||
7
src/drm_stub.c
Normal file
7
src/drm_stub.c
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
int drm_framebuffer_init(int *handle, const char *card) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drm_framebuffer_close(int handle) {
|
||||||
|
}
|
||||||
11
src/fb.c
11
src/fb.c
|
|
@ -15,10 +15,11 @@
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "framebuffer.h"
|
|
||||||
#include "pbsplash.h"
|
#include "pbsplash.h"
|
||||||
#include "tfblib.h"
|
#include "tfblib.h"
|
||||||
|
|
||||||
|
#include "tfblib_drm.h"
|
||||||
|
|
||||||
#define DEFAULT_FB_DEVICE "/dev/fb0"
|
#define DEFAULT_FB_DEVICE "/dev/fb0"
|
||||||
#define DEFAULT_TTY_DEVICE "/dev/tty"
|
#define DEFAULT_TTY_DEVICE "/dev/tty"
|
||||||
|
|
||||||
|
|
@ -51,6 +52,7 @@ static int tfb_set_window(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRM_SUPPORT
|
||||||
int tfb_acquire_drm(uint32_t flags, const char *device)
|
int tfb_acquire_drm(uint32_t flags, const char *device)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -86,6 +88,7 @@ int tfb_acquire_drm(uint32_t flags, const char *device)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int tfb_acquire_fb(uint32_t flags, const char *fb_device, const char *tty_device)
|
int tfb_acquire_fb(uint32_t flags, const char *fb_device, const char *tty_device)
|
||||||
{
|
{
|
||||||
|
|
@ -259,6 +262,7 @@ void tfb_flush_window(void)
|
||||||
|
|
||||||
int tfb_flush_fb(void)
|
int tfb_flush_fb(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_DRM_SUPPORT
|
||||||
int ret;
|
int ret;
|
||||||
struct modeset_buf *buf;
|
struct modeset_buf *buf;
|
||||||
if (drmfd >= 0) {
|
if (drmfd >= 0) {
|
||||||
|
|
@ -276,6 +280,7 @@ int tfb_flush_fb(void)
|
||||||
__fb_buffer = buf->map; //drm->bufs[drm->front_buf ^ 1].map;
|
__fb_buffer = buf->map; //drm->bufs[drm->front_buf ^ 1].map;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
__fbi.activate |= FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
|
__fbi.activate |= FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
|
||||||
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &__fbi) < 0) {
|
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &__fbi) < 0) {
|
||||||
perror("Couldn't flush framebuffer");
|
perror("Couldn't flush framebuffer");
|
||||||
|
|
@ -287,15 +292,19 @@ int tfb_flush_fb(void)
|
||||||
|
|
||||||
uint32_t tfb_screen_width_mm(void)
|
uint32_t tfb_screen_width_mm(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_DRM_SUPPORT
|
||||||
if (drmfd >= 0)
|
if (drmfd >= 0)
|
||||||
return drm->mm_width;
|
return drm->mm_width;
|
||||||
|
#endif
|
||||||
|
|
||||||
return __fbi.width;
|
return __fbi.width;
|
||||||
}
|
}
|
||||||
uint32_t tfb_screen_height_mm(void)
|
uint32_t tfb_screen_height_mm(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_DRM_SUPPORT
|
||||||
if (drmfd >= 0)
|
if (drmfd >= 0)
|
||||||
return drm->mm_height;
|
return drm->mm_height;
|
||||||
|
#endif
|
||||||
|
|
||||||
return __fbi.height;
|
return __fbi.height;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
src = [
|
|
||||||
'animate.c',
|
|
||||||
'nanosvg.c',
|
|
||||||
'timespec.c',
|
|
||||||
'pbsplash.c',
|
|
||||||
'fb.c',
|
|
||||||
'drm.c',
|
|
||||||
'drawing.c',
|
|
||||||
]
|
|
||||||
|
|
||||||
executable('pbsplash', src,
|
|
||||||
include_directories: inc,
|
|
||||||
dependencies: deps,
|
|
||||||
install: true)
|
|
||||||
105
src/pbsplash.c
105
src/pbsplash.c
|
|
@ -9,12 +9,13 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <math.h>
|
#include "config.h"
|
||||||
#include <string.h>
|
|
||||||
#include "nanosvg.h"
|
#include "nanosvg.h"
|
||||||
#include "pbsplash.h"
|
#include "pbsplash.h"
|
||||||
#include "tfblib.h"
|
#include "tfblib.h"
|
||||||
#include "timespec.h"
|
#include "timespec.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define MSG_MAX_LEN 4096
|
#define MSG_MAX_LEN 4096
|
||||||
#define DEFAULT_FONT_PATH "/usr/share/pbsplash/OpenSans-Regular.svg"
|
#define DEFAULT_FONT_PATH "/usr/share/pbsplash/OpenSans-Regular.svg"
|
||||||
|
|
@ -48,17 +49,20 @@ static int usage()
|
||||||
fprintf(stderr, "pbsplash [-v] [-h] [-f font] [-s splash image] [-m message]\n");
|
fprintf(stderr, "pbsplash [-v] [-h] [-f font] [-s splash image] [-m message]\n");
|
||||||
fprintf(stderr, " [-b message bottom] [-o font size bottom]\n");
|
fprintf(stderr, " [-b message bottom] [-o font size bottom]\n");
|
||||||
fprintf(stderr, " [-p font size] [-q max logo size] [-d] [-e]\n\n");
|
fprintf(stderr, " [-p font size] [-q max logo size] [-d] [-e]\n\n");
|
||||||
fprintf(stderr, " -v enable verbose logging\n");
|
|
||||||
fprintf(stderr, " -h show this help\n");
|
|
||||||
fprintf(stderr, " -f path to SVG font file (default: %s)\n", DEFAULT_FONT_PATH);
|
|
||||||
fprintf(stderr, " -s path to splash image to display\n");
|
|
||||||
fprintf(stderr, " -m message to show under the splash image\n");
|
|
||||||
fprintf(stderr, " -b message to show at the bottom\n");
|
fprintf(stderr, " -b message to show at the bottom\n");
|
||||||
|
fprintf(stderr, " -d custom DPI (for testing)\n");
|
||||||
|
fprintf(stderr, " -e error (no loading animation)\n");
|
||||||
|
fprintf(stderr, " -f path to SVG font file (default: %s)\n", DEFAULT_FONT_PATH);
|
||||||
|
fprintf(stderr, " -h show this help\n");
|
||||||
|
fprintf(stderr, " -m message to show under the splash image\n");
|
||||||
fprintf(stderr, " -o font size bottom in pt (default: %d)\n", FONT_SIZE_B_PT);
|
fprintf(stderr, " -o font size bottom in pt (default: %d)\n", FONT_SIZE_B_PT);
|
||||||
fprintf(stderr, " -p font size in pt (default: %d)\n", FONT_SIZE_PT);
|
fprintf(stderr, " -p font size in pt (default: %d)\n", FONT_SIZE_PT);
|
||||||
fprintf(stderr, " -q max logo size in mm (default: %d)\n", LOGO_SIZE_MAX_MM);
|
fprintf(stderr, " -q max logo size in mm (default: %d)\n", LOGO_SIZE_MAX_MM);
|
||||||
fprintf(stderr, " -d custom DPI (for testing)\n");
|
#ifdef CONFIG_DRM_SUPPORT
|
||||||
fprintf(stderr, " -e error (no loading animation)\n");
|
fprintf(stderr, " -r use DRM for rendering instead of framebuffer");
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, " -s path to splash image to display\n");
|
||||||
|
fprintf(stderr, " -v enable verbose logging\n");
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -108,7 +112,7 @@ static inline float getShapeWidth(const NSVGimage *font, const NSVGshape *shape)
|
||||||
if (shape) {
|
if (shape) {
|
||||||
return shape->horizAdvX;
|
return shape->horizAdvX;
|
||||||
} else {
|
} else {
|
||||||
//printf("WARNING: Shape for '%s' is NULL!\n", shape->unicode ?: "");
|
// printf("WARNING: Shape for '%s' is NULL!\n", shape->unicode ?: "");
|
||||||
return font->defaultHorizAdv;
|
return font->defaultHorizAdv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -400,6 +404,7 @@ int main(int argc, char **argv)
|
||||||
};
|
};
|
||||||
int optflag;
|
int optflag;
|
||||||
bool animation = true;
|
bool animation = true;
|
||||||
|
bool use_drm = false;
|
||||||
|
|
||||||
memset(active_tty, '\0', TTY_PATH_LEN);
|
memset(active_tty, '\0', TTY_PATH_LEN);
|
||||||
strcat(active_tty, "/dev/");
|
strcat(active_tty, "/dev/");
|
||||||
|
|
@ -409,7 +414,7 @@ int main(int argc, char **argv)
|
||||||
sigaction(SIGTERM, &action, NULL);
|
sigaction(SIGTERM, &action, NULL);
|
||||||
sigaction(SIGINT, &action, NULL);
|
sigaction(SIGINT, &action, NULL);
|
||||||
|
|
||||||
while ((optflag = getopt(argc, argv, "hvf:s:m:b:o:p:q:d:e")) != -1) {
|
while ((optflag = getopt(argc, argv, "hvf:s:m:b:o:p:q:d:er")) != -1) {
|
||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
switch (optflag) {
|
switch (optflag) {
|
||||||
case 'h':
|
case 'h':
|
||||||
|
|
@ -452,6 +457,13 @@ int main(int argc, char **argv)
|
||||||
return usage();
|
return usage();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
#ifndef CONFIG_DRM_SUPPORT
|
||||||
|
fprintf(stderr, "DRM support not compiled in\n");
|
||||||
|
return usage();
|
||||||
|
#endif
|
||||||
|
use_drm = true;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
dpi_info.dpi = strtol(optarg, &end, 10);
|
dpi_info.dpi = strtol(optarg, &end, 10);
|
||||||
if (end == optarg || dpi_info.dpi < 0) {
|
if (end == optarg || dpi_info.dpi < 0) {
|
||||||
|
|
@ -467,27 +479,25 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
/* Framebuffer */
|
||||||
// FILE *fp = fopen("/sys/devices/virtual/tty/tty0/active", "r");
|
if (!use_drm) {
|
||||||
// int len = strlen(active_tty);
|
FILE *fp = fopen("/sys/devices/virtual/tty/tty0/active", "r");
|
||||||
// char *ptr = active_tty + len;
|
int len = strlen(active_tty);
|
||||||
// if (fp != NULL) {
|
char *ptr = active_tty + len;
|
||||||
// fgets(ptr, TTY_PATH_LEN - len, fp);
|
if (fp != NULL) {
|
||||||
// *(ptr + strlen(ptr) - 1) = '\0';
|
fgets(ptr, TTY_PATH_LEN - len, fp);
|
||||||
// fclose(fp);
|
*(ptr + strlen(ptr) - 1) = '\0';
|
||||||
// }
|
fclose(fp);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// LOG("active tty: '%s'\n", active_tty);
|
LOG("active tty: '%s'\n", active_tty);
|
||||||
|
|
||||||
// if ((rc = tfb_acquire_fb(/*TFB_FL_NO_TTY_KD_GRAPHICS */ 0, "/dev/fb0", active_tty)) !=
|
if ((rc = tfb_acquire_fb(0, "/dev/fb0", active_tty)) != 0) {
|
||||||
// TFB_SUCCESS) {
|
fprintf(stderr, "tfb_acquire_fb() failed with error code: %d\n", rc);
|
||||||
// fprintf(stderr, "tfb_acquire_fb() failed with error code: %d\n", rc);
|
rc = 1;
|
||||||
// rc = 1;
|
return rc;
|
||||||
// return rc;
|
}
|
||||||
// }
|
} else if ((rc = tfb_acquire_drm(0, "/dev/dri/card0")) != 0) {
|
||||||
|
|
||||||
if ((rc = tfb_acquire_drm(0, "/dev/dri/card0")) != 0) {
|
|
||||||
fprintf(stderr, "tfb_acquire_drm() failed with error code: %d\n", rc);
|
fprintf(stderr, "tfb_acquire_drm() failed with error code: %d\n", rc);
|
||||||
rc = 1;
|
rc = 1;
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -532,11 +542,15 @@ no_messages:
|
||||||
tfb_flush_fb();
|
tfb_flush_fb();
|
||||||
|
|
||||||
int tick = 0;
|
int tick = 0;
|
||||||
// int tty = open(active_tty, O_RDWR);
|
int tty = 0;
|
||||||
// if (!tty) {
|
|
||||||
// fprintf(stderr, "Failed to open tty %s (%d)\n", active_tty, errno);
|
if (!use_drm) {
|
||||||
// goto out;
|
open(active_tty, O_RDWR);
|
||||||
// }
|
if (!tty) {
|
||||||
|
fprintf(stderr, "Failed to open tty %s (%d)\n", active_tty, errno);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct timespec epoch, start, end, diff;
|
struct timespec epoch, start, end, diff;
|
||||||
int target_fps = 60;
|
int target_fps = 60;
|
||||||
|
|
@ -553,7 +567,7 @@ no_messages:
|
||||||
tfb_flush_fb();
|
tfb_flush_fb();
|
||||||
clock_gettime(CLOCK_REALTIME, &end);
|
clock_gettime(CLOCK_REALTIME, &end);
|
||||||
diff = timespec_sub(end, start);
|
diff = timespec_sub(end, start);
|
||||||
//printf("%05d: %09ld\n", tick, diff.tv_nsec);
|
// printf("%05d: %09ld\n", tick, diff.tv_nsec);
|
||||||
if (diff.tv_nsec < 1000000000 / target_fps) {
|
if (diff.tv_nsec < 1000000000 / target_fps) {
|
||||||
struct timespec sleep_time = {
|
struct timespec sleep_time = {
|
||||||
.tv_sec = 0,
|
.tv_sec = 0,
|
||||||
|
|
@ -564,15 +578,18 @@ no_messages:
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
// Before we exit print the logo so it will persist
|
/* Currently DRM doesn't persist the framebuffer after exiting */
|
||||||
if (image_info.image) {
|
if (!use_drm) {
|
||||||
//ioctl(tty, KDSETMODE, KD_TEXT);
|
// Before we exit print the logo so it will persist
|
||||||
draw_svg(image_info.image, image_info.x, image_info.y, image_info.width,
|
if (image_info.image) {
|
||||||
image_info.height);
|
ioctl(tty, KDSETMODE, KD_TEXT);
|
||||||
}
|
draw_svg(image_info.image, image_info.x, image_info.y, image_info.width,
|
||||||
|
image_info.height);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw the messages again so they will persist
|
// Draw the messages again so they will persist
|
||||||
show_messages(&msgs, &dpi_info);
|
show_messages(&msgs, &dpi_info);
|
||||||
|
}
|
||||||
|
|
||||||
nsvgDelete(image_info.image);
|
nsvgDelete(image_info.image);
|
||||||
nsvgDelete(msgs.font);
|
nsvgDelete(msgs.font);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue