Skip to content

Commit

Permalink
GUI: canvas commit callback has been moved to canvas. Direct Draw app…
Browse files Browse the repository at this point in the history
…s can now be streamed via RPC. (flipperdevices#3397)

Co-authored-by: あく <alleteam@gmail.com>
  • Loading branch information
DrZlo13 and skotopes committed Feb 12, 2024
1 parent 9744fd8 commit 8b19d32
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 36 deletions.
55 changes: 55 additions & 0 deletions applications/services/gui/canvas.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ Canvas* canvas_init() {
Canvas* canvas = malloc(sizeof(Canvas));
canvas->compress_icon = compress_icon_alloc();

// Initialize mutex
canvas->mutex = furi_mutex_alloc(FuriMutexTypeNormal);

// Initialize callback array
CanvasCallbackPairArray_init(canvas->canvas_callback_pair);

// Setup u8g2
u8g2_Setup_st756x_flipper(&canvas->fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32);
canvas->orientation = CanvasOrientationHorizontal;
Expand All @@ -36,9 +42,21 @@ Canvas* canvas_init() {
void canvas_free(Canvas* canvas) {
furi_assert(canvas);
compress_icon_free(canvas->compress_icon);
CanvasCallbackPairArray_clear(canvas->canvas_callback_pair);
furi_mutex_free(canvas->mutex);
free(canvas);
}

static void canvas_lock(Canvas* canvas) {
furi_assert(canvas);
furi_check(furi_mutex_acquire(canvas->mutex, FuriWaitForever) == FuriStatusOk);
}

static void canvas_unlock(Canvas* canvas) {
furi_assert(canvas);
furi_check(furi_mutex_release(canvas->mutex) == FuriStatusOk);
}

void canvas_reset(Canvas* canvas) {
furi_assert(canvas);

Expand All @@ -52,6 +70,18 @@ void canvas_reset(Canvas* canvas) {
void canvas_commit(Canvas* canvas) {
furi_assert(canvas);
u8g2_SendBuffer(&canvas->fb);

// Iterate over callbacks
canvas_lock(canvas);
for
M_EACH(p, canvas->canvas_callback_pair, CanvasCallbackPairArray_t) {
p->callback(
canvas_get_buffer(canvas),
canvas_get_buffer_size(canvas),
canvas_get_orientation(canvas),
p->context);
}
canvas_unlock(canvas);
}

uint8_t* canvas_get_buffer(Canvas* canvas) {
Expand Down Expand Up @@ -542,3 +572,28 @@ void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation) {
CanvasOrientation canvas_get_orientation(const Canvas* canvas) {
return canvas->orientation;
}

void canvas_add_framebuffer_callback(Canvas* canvas, CanvasCommitCallback callback, void* context) {
furi_assert(canvas);

const CanvasCallbackPair p = {callback, context};

canvas_lock(canvas);
furi_assert(!CanvasCallbackPairArray_count(canvas->canvas_callback_pair, p));
CanvasCallbackPairArray_push_back(canvas->canvas_callback_pair, p);
canvas_unlock(canvas);
}

void canvas_remove_framebuffer_callback(
Canvas* canvas,
CanvasCommitCallback callback,
void* context) {
furi_assert(canvas);

const CanvasCallbackPair p = {callback, context};

canvas_lock(canvas);
furi_assert(CanvasCallbackPairArray_count(canvas->canvas_callback_pair, p) == 1);
CanvasCallbackPairArray_remove_val(canvas->canvas_callback_pair, p);
canvas_unlock(canvas);
}
51 changes: 51 additions & 0 deletions applications/services/gui/canvas_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,30 @@
#include "canvas.h"
#include <u8g2.h>
#include <toolbox/compress.h>
#include <m-array.h>
#include <m-algo.h>
#include <furi.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef void (*CanvasCommitCallback)(
uint8_t* data,
size_t size,
CanvasOrientation orientation,
void* context);

typedef struct {
CanvasCommitCallback callback;
void* context;
} CanvasCallbackPair;

ARRAY_DEF(CanvasCallbackPairArray, CanvasCallbackPair, M_POD_OPLIST);

#define M_OPL_CanvasCallbackPairArray_t() ARRAY_OPLIST(CanvasCallbackPairArray, M_POD_OPLIST)

ALGO_DEF(CanvasCallbackPairArray, CanvasCallbackPairArray_t);

/** Canvas structure
*/
Expand All @@ -19,6 +43,8 @@ struct Canvas {
uint8_t width;
uint8_t height;
CompressIcon* compress_icon;
CanvasCallbackPairArray_t canvas_callback_pair;
FuriMutex* mutex;
};

/** Allocate memory and initialize canvas
Expand Down Expand Up @@ -97,3 +123,28 @@ void canvas_draw_u8g2_bitmap(
uint8_t height,
const uint8_t* bitmap,
uint8_t rotation);

/** Add canvas commit callback.
*
* This callback will be called upon Canvas commit.
*
* @param canvas Canvas instance
* @param callback CanvasCommitCallback
* @param context CanvasCommitCallback context
*/
void canvas_add_framebuffer_callback(Canvas* canvas, CanvasCommitCallback callback, void* context);

/** Remove canvas commit callback.
*
* @param canvas Canvas instance
* @param callback CanvasCommitCallback
* @param context CanvasCommitCallback context
*/
void canvas_remove_framebuffer_callback(
Canvas* canvas,
CanvasCommitCallback callback,
void* context);

#ifdef __cplusplus
}
#endif
27 changes: 4 additions & 23 deletions applications/services/gui/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,6 @@ static void gui_redraw(Gui* gui) {
}

canvas_commit(gui->canvas);
for
M_EACH(p, gui->canvas_callback_pair, CanvasCallbackPairArray_t) {
p->callback(
canvas_get_buffer(gui->canvas),
canvas_get_buffer_size(gui->canvas),
canvas_get_orientation(gui->canvas),
p->context);
}
} while(false);

gui_unlock(gui);
Expand Down Expand Up @@ -473,12 +465,7 @@ void gui_view_port_send_to_back(Gui* gui, ViewPort* view_port) {
void gui_add_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback, void* context) {
furi_assert(gui);

const CanvasCallbackPair p = {callback, context};

gui_lock(gui);
furi_assert(!CanvasCallbackPairArray_count(gui->canvas_callback_pair, p));
CanvasCallbackPairArray_push_back(gui->canvas_callback_pair, p);
gui_unlock(gui);
canvas_add_framebuffer_callback(gui->canvas, callback, context);

// Request redraw
gui_update(gui);
Expand All @@ -487,12 +474,7 @@ void gui_add_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback, vo
void gui_remove_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback, void* context) {
furi_assert(gui);

const CanvasCallbackPair p = {callback, context};

gui_lock(gui);
furi_assert(CanvasCallbackPairArray_count(gui->canvas_callback_pair, p) == 1);
CanvasCallbackPairArray_remove_val(gui->canvas_callback_pair, p);
gui_unlock(gui);
canvas_remove_framebuffer_callback(gui->canvas, callback, context);
}

size_t gui_get_framebuffer_size(const Gui* gui) {
Expand Down Expand Up @@ -542,20 +524,19 @@ Gui* gui_alloc() {
gui->thread_id = furi_thread_get_current_id();
// Allocate mutex
gui->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
furi_check(gui->mutex);

// Layers
for(size_t i = 0; i < GuiLayerMAX; i++) {
ViewPortArray_init(gui->layers[i]);
}

// Drawing canvas
gui->canvas = canvas_init();
CanvasCallbackPairArray_init(gui->canvas_callback_pair);

// Input
gui->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
gui->input_events = furi_record_open(RECORD_INPUT_EVENTS);

furi_check(gui->input_events);
furi_pubsub_subscribe(gui->input_events, gui_input_events_callback, gui);

return gui;
Expand Down
13 changes: 0 additions & 13 deletions applications/services/gui/gui_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <furi.h>
#include <furi_hal_rtc.h>
#include <m-array.h>
#include <m-algo.h>
#include <stdio.h>

#include "canvas.h"
Expand Down Expand Up @@ -44,17 +43,6 @@

ARRAY_DEF(ViewPortArray, ViewPort*, M_PTR_OPLIST);

typedef struct {
GuiCanvasCommitCallback callback;
void* context;
} CanvasCallbackPair;

ARRAY_DEF(CanvasCallbackPairArray, CanvasCallbackPair, M_POD_OPLIST);

#define M_OPL_CanvasCallbackPairArray_t() ARRAY_OPLIST(CanvasCallbackPairArray, M_POD_OPLIST)

ALGO_DEF(CanvasCallbackPairArray, CanvasCallbackPairArray_t);

/** Gui structure */
struct Gui {
// Thread and lock
Expand All @@ -66,7 +54,6 @@ struct Gui {
bool direct_draw;
ViewPortArray_t layers[GuiLayerMAX];
Canvas* canvas;
CanvasCallbackPairArray_t canvas_callback_pair;

// Input
FuriMessageQueue* input_queue;
Expand Down

0 comments on commit 8b19d32

Please sign in to comment.