Skip to content

Commit

Permalink
Merge pull request #52 from gridpoint-com/jringle/cairo-gtk
Browse files Browse the repository at this point in the history
Cairo support, part 3 of 3.
  • Loading branch information
crertel authored Oct 7, 2023
2 parents 653bd98 + e0a9e7b commit fa19761
Show file tree
Hide file tree
Showing 11 changed files with 625 additions and 150 deletions.
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ NVG_COMMON_SRCS = \
c_src/device/nvg/nvg_script_ops.c

CAIRO_COMMON_SRCS = \
c_src/device/cairo/cairo_common.c \
c_src/device/cairo/cairo_font_ops.c \
c_src/device/cairo/cairo_image_ops.c \
c_src/device/cairo/cairo_script_ops.c
Expand Down Expand Up @@ -143,6 +144,16 @@ else ifeq ($(SCENIC_LOCAL_TARGET),cairo-fb)
$(CAIRO_COMMON_SRCS) \
c_src/device/cairo/cairo_fb.c

else ifeq ($(SCENIC_LOCAL_TARGET),cairo-gtk)
LDFLAGS += `pkg-config --static --libs freetype2 cairo gtk+-3.0`
CFLAGS += `pkg-config --static --cflags freetype2 cairo gtk+-3.0`
LDFLAGS += -lm
CFLAGS ?= -O2 -Wall -Wextra -Wno-unused-parameter -pedantic
CFLAGS += -std=gnu99

DEVICE_SRCS += \
$(CAIRO_COMMON_SRCS) \
c_src/device/cairo/cairo_gtk.c
else
$(info ------ no SCENIC_LOCAL_TARGET set ------)
$(info If you get here, then you are probably using a custom Nerves system)
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,18 @@ For example, for apps running on a Mac/PC/Linux, it is usually set to `host`, wh

If you are building for Nerves, it will use `bcm` (Broadcom Manager) for any of `rpi`, `rpi0`, `rip2`, `rpi3`, and `rpi3a`.

### Cairo
There is now a rendering backend to use `cairo`. You can set SCENIC_LOCAL_TARGET to `cairo-fb` which renders to `/dev/fb0` on an embedded device or `cairo-gtk` which renders to a window on a host (as an alternative to `glfw`).

`cairo-fb` will require that your `nerves_system_*` has the `cairo` library selected.

### Nerves rpi4 & bbb Need Work / Help
`Scenic.Driver.Local` uses `drm` (Direct Render Manager) for the `rpi4` and `bbb`. It currently renders on the rpi4, but is __very slow__. I haven't figured out why yet and if anyone wants to dig in, that would be appreciated. It should be really fast, so is probably a hardware configuration issue.

The `bbb` doesn't work (is close in theory??) as the Nerves `bbb` system doesn't have the needed graphics support in it yet. There are others who have gotten SGX support working for the `bbb` and I could use some help from them.

Please try using `cairo-fb` to see if it will work for you on `rpi4` or `bbb`.

### Custom Nerves Targets
For custom systems (example - figuring out how to add SGX support to the `bbb`) You will need to set SCENIC_LOCAL_TARGET manually. You may also need to set the SCENIC_LOCAL_GL as well.

Expand Down Expand Up @@ -92,11 +99,18 @@ Once these components have been installed, you should be able to build the `scen

The easiest way to install on Ubuntu is to use apt-get. Just run the following:

For `glfw`:
```bash
apt-get update
apt-get install pkgconf libglfw3 libglfw3-dev libglew2.1 libglew-dev
```

For `cairo-gtk`:
```bash
apt-get update
apt-get install pkgconf libgtk-3-0 libgtk-3-dev libsystemd-dev libwebp-dev libzstd-dev
```

Once these components have been installed, you should be able to build the `scenic_driver_local` driver.

### Installing on Arch Linux
Expand Down
99 changes: 99 additions & 0 deletions c_src/device/cairo/cairo_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "cairo_ctx.h"
#include "device.h"

extern device_info_t g_device_info;

scenic_cairo_ctx_t* scenic_cairo_init(const device_opts_t* p_opts,
device_info_t* p_info)
{
scenic_cairo_ctx_t* p_ctx = calloc(1, sizeof(scenic_cairo_ctx_t));

FT_Error status = FT_Init_FreeType(&p_ctx->ft_library);
if (status != 0) {
log_error("cairo: FT_Init_FreeType: Error: %d", status);
free(p_ctx);

return NULL;
}

p_ctx->ratio = 1.0f;
p_ctx->dist_tolerance = 0.1f * p_ctx->ratio;

p_info->width = p_opts->width;
p_info->height = p_opts->height;

p_ctx->font_size = 10.0; // Cairo default
p_ctx->text_align = TEXT_ALIGN_LEFT;
p_ctx->text_base = TEXT_BASE_ALPHABETIC;

p_ctx->clear_color = (color_rgba_t){
// black opaque
.red = 0.0,
.green = 0.0,
.blue = 0.0,
.alpha = 1.0
};

p_info->v_ctx = p_ctx;

p_ctx->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
p_info->width, p_info->height);

return p_ctx;
}

void scenic_cairo_fini(scenic_cairo_ctx_t* p_ctx)
{
cairo_surface_destroy(p_ctx->surface);
free(p_ctx);
}

void device_begin_cursor_render(driver_data_t* p_data)
{
scenic_cairo_ctx_t* p_ctx = (scenic_cairo_ctx_t*)p_data->v_ctx;
cairo_translate(p_ctx->cr, p_data->cursor_pos[0], p_data->cursor_pos[1]);
}

void device_clear_color(float red, float green, float blue, float alpha)
{
scenic_cairo_ctx_t* p_ctx = (scenic_cairo_ctx_t*)g_device_info.v_ctx;
p_ctx->clear_color = (color_rgba_t){
.red = red,
.green = green,
.blue = blue,
.alpha = alpha
};
}

char* device_gl_error()
{
return NULL;
}

void pattern_stack_push(scenic_cairo_ctx_t* p_ctx)
{
pattern_stack_t* ptr = (pattern_stack_t*)malloc(sizeof(pattern_stack_t));

ptr->pattern = p_ctx->pattern;

if (!p_ctx->pattern_stack_head) {
ptr->next = NULL;
p_ctx->pattern_stack_head = ptr;
} else {
ptr->next = p_ctx->pattern_stack_head;
p_ctx->pattern_stack_head = ptr;
}
}

void pattern_stack_pop(scenic_cairo_ctx_t* p_ctx)
{
pattern_stack_t* ptr = p_ctx->pattern_stack_head;

if (!ptr) {
log_error("pattern stack underflow");
} else {
p_ctx->pattern = ptr->pattern;
p_ctx->pattern_stack_head = p_ctx->pattern_stack_head->next;
free(ptr);
}
}
9 changes: 4 additions & 5 deletions c_src/device/cairo/cairo_ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ typedef struct {
float font_size;
text_align_t text_align;
text_base_t text_base;
union {
u_int8_t *c;
u_int16_t *s;
u_int32_t *i;
} fbbuff;
cairo_surface_t* surface;
cairo_t* cr;
pattern_stack_t* pattern_stack_head;
Expand All @@ -53,6 +48,10 @@ typedef struct {
float ratio;
} scenic_cairo_ctx_t;

scenic_cairo_ctx_t* scenic_cairo_init(const device_opts_t* p_opts,
device_info_t* p_info);
void scenic_cairo_fini(scenic_cairo_ctx_t* p_ctx);

void pattern_stack_push(scenic_cairo_ctx_t* p_ctx);
void pattern_stack_pop(scenic_cairo_ctx_t* p_ctx);

Expand Down
Loading

0 comments on commit fa19761

Please sign in to comment.