[FL-878] Gui: screen streaming (#337)

* GUI: canvas streaming
* Fix right status bar icon alignment
This commit is contained in:
あく
2021-02-13 14:40:20 +03:00
committed by GitHub
parent b835d7a451
commit 23f66c2cdd
9 changed files with 134 additions and 21 deletions

View File

@@ -39,6 +39,16 @@ void canvas_commit(Canvas* canvas) {
u8g2_SendBuffer(&canvas->fb);
}
uint8_t* canvas_get_buffer(Canvas* canvas) {
furi_assert(canvas);
return u8g2_GetBufferPtr(&canvas->fb);
}
size_t canvas_get_buffer_size(Canvas* canvas) {
furi_assert(canvas);
return u8g2_GetBufferTileWidth(&canvas->fb) * u8g2_GetBufferTileHeight(&canvas->fb) * 8;
}
void canvas_frame_set(
Canvas* canvas,
uint8_t offset_x,
@@ -219,4 +229,4 @@ void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch) {
x += canvas->offset_x;
y += canvas->offset_y;
u8g2_DrawGlyph(&canvas->fb, x, y, ch);
}
}

View File

@@ -31,6 +31,18 @@ void canvas_reset(Canvas* canvas);
*/
void canvas_commit(Canvas* canvas);
/*
* Get canvas buffer.
* @return pointer to buffer
*/
uint8_t* canvas_get_buffer(Canvas* canvas);
/*
* Get canvas buffer size.
* @return size of canvas in bytes
*/
size_t canvas_get_buffer_size(Canvas* canvas);
/*
* Set drawing region relative to real screen buffer
*/

View File

@@ -59,7 +59,7 @@ void gui_redraw_status_bar(Gui* gui) {
uint8_t width;
ViewPort* view_port;
// Right side
x = 128;
x = GUI_DISPLAY_WIDTH + 2;
ViewPortArray_it(it, gui->layers[GuiLayerStatusBarRight]);
while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) {
// Render view_port;
@@ -127,6 +127,12 @@ void gui_redraw(Gui* gui) {
}
canvas_commit(gui->canvas);
if(gui->canvas_callback) {
gui->canvas_callback(
canvas_get_buffer(gui->canvas),
canvas_get_buffer_size(gui->canvas),
gui->canvas_callback_context);
}
gui_unlock(gui);
}
@@ -159,6 +165,27 @@ void gui_unlock(Gui* gui) {
furi_check(osMutexRelease(gui->mutex) == osOK);
}
void gui_cli_screen_stream_callback(uint8_t* data, size_t size, void* context) {
furi_assert(data);
furi_assert(size == 1024);
furi_assert(context);
Gui* gui = context;
uint8_t magic[] = {0xF0, 0xE1, 0xD2, 0xC3};
cli_write(gui->cli, magic, sizeof(magic));
cli_write(gui->cli, data, size);
}
void gui_cli_screen_stream(string_t args, void* context) {
furi_assert(context);
Gui* gui = context;
gui_set_framebuffer_callback_context(gui, gui);
gui_set_framebuffer_callback(gui, gui_cli_screen_stream_callback);
cli_getc(gui->cli);
gui_set_framebuffer_callback(gui, NULL);
gui_set_framebuffer_callback_context(gui, NULL);
}
void gui_add_view_port(Gui* gui, ViewPort* view_port, GuiLayer layer) {
furi_assert(gui);
furi_assert(view_port);
@@ -256,6 +283,16 @@ void gui_send_view_port_back(Gui* gui, ViewPort* view_port) {
gui_unlock(gui);
}
void gui_set_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback) {
furi_assert(gui);
gui->canvas_callback = callback;
}
void gui_set_framebuffer_callback_context(Gui* gui, void* context) {
furi_assert(gui);
gui->canvas_callback_context = context;
}
Gui* gui_alloc() {
Gui* gui = furi_alloc(sizeof(Gui));
// Thread ID
@@ -276,6 +313,9 @@ Gui* gui_alloc() {
gui->input_events = furi_record_open("input_events");
furi_check(gui->input_events);
subscribe_pubsub(gui->input_events, gui_input_events_callback, gui);
// Cli
gui->cli = furi_record_open("cli");
cli_add_command(gui->cli, "screen_stream", gui_cli_screen_stream, gui);
return gui;
}

View File

@@ -7,6 +7,7 @@
extern "C" {
#endif
/* Gui layers */
typedef enum {
GuiLayerNone, /* Special layer for internal use only */
@@ -18,6 +19,9 @@ typedef enum {
GuiLayerMAX /* Don't use or move, special value */
} GuiLayer;
/* Gui frame buffer callback */
typedef void (*GuiCanvasCommitCallback)(uint8_t* data, size_t size, void* context);
typedef struct Gui Gui;
/*
@@ -34,18 +38,32 @@ void gui_remove_view_port(Gui* gui, ViewPort* view_port);
/* Send ViewPort to the front
* Places selected ViewPort to the top of the drawing stack
* @param gui, Gui instance
* @param view_port, ViewPort instance
* @param gui - Gui instance
* @param view_port - ViewPort instance
*/
void gui_send_view_port_front(Gui* gui, ViewPort* view_port);
/* Send ViewPort to the back
* Places selected ViewPort to the bottom of the drawing stack
* @param gui, Gui instance
* @param view_port, ViewPort instance
* @param gui - Gui instance
* @param view_port - ViewPort instance
*/
void gui_send_view_port_back(Gui* gui, ViewPort* view_port);
/* Set gui canvas commit callback
* This callback will be called upon Canvas commit
* Callback dispatched from GUI thread and is time critical
* @param gui - Gui instance
* @param callback - GuiCanvasCommitCallback
*/
void gui_set_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback);
/* Set gui canvas commit callback context
* @param gui - Gui instance
* @param context - pointer to context
*/
void gui_set_framebuffer_callback_context(Gui* gui, void* context);
#ifdef __cplusplus
}
#endif

View File

@@ -6,6 +6,7 @@
#include <m-array.h>
#include <stdio.h>
#include <cli/cli.h>
#include "canvas.h"
#include "canvas_i.h"
#include "view_port.h"
@@ -38,9 +39,13 @@ struct Gui {
// Layers and Canvas
ViewPortArray_t layers[GuiLayerMAX];
Canvas* canvas;
GuiCanvasCommitCallback canvas_callback;
void* canvas_callback_context;
// Input
osMessageQueueId_t input_queue;
PubSub* input_events;
// Cli
Cli* cli;
};
ViewPort* gui_view_port_find_enabled(ViewPortArray_t array);
@@ -57,4 +62,8 @@ void gui_input_events_callback(const void* value, void* ctx);
void gui_lock(Gui* gui);
void gui_unlock(Gui* gui);
void gui_unlock(Gui* gui);
void gui_cli_screen_stream_callback(uint8_t* data, size_t size, void* context);
void gui_cli_screen_stream(string_t args, void* context);