Gui: Direct Draw API (#2215)
* Furi: allow on-fly thread priority change. Gui: Direct Draw API. DirectDraw debug app. * Gui: drop input in direct draw * Furi: handle priority change for starting threads * DirectDraw: rollback to FreeRTOS primitives for priority change
This commit is contained in:
10
applications/debug/direct_draw/application.fam
Normal file
10
applications/debug/direct_draw/application.fam
Normal file
@@ -0,0 +1,10 @@
|
||||
App(
|
||||
appid="direct_draw",
|
||||
name="Direct Draw",
|
||||
apptype=FlipperAppType.DEBUG,
|
||||
entry_point="direct_draw_app",
|
||||
requires=["gui", "input"],
|
||||
stack_size=2 * 1024,
|
||||
order=70,
|
||||
fap_category="Debug",
|
||||
)
|
112
applications/debug/direct_draw/direct_draw.c
Normal file
112
applications/debug/direct_draw/direct_draw.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#include <furi.h>
|
||||
#include <gui/gui.h>
|
||||
#include <gui/canvas_i.h>
|
||||
#include <input/input.h>
|
||||
|
||||
#define BUFFER_SIZE (32U)
|
||||
|
||||
typedef struct {
|
||||
FuriPubSub* input;
|
||||
FuriPubSubSubscription* input_subscription;
|
||||
Gui* gui;
|
||||
Canvas* canvas;
|
||||
bool stop;
|
||||
uint32_t counter;
|
||||
} DirectDraw;
|
||||
|
||||
static void gui_input_events_callback(const void* value, void* ctx) {
|
||||
furi_assert(value);
|
||||
furi_assert(ctx);
|
||||
|
||||
DirectDraw* instance = ctx;
|
||||
const InputEvent* event = value;
|
||||
|
||||
if(event->key == InputKeyBack && event->type == InputTypeShort) {
|
||||
instance->stop = true;
|
||||
}
|
||||
}
|
||||
|
||||
static DirectDraw* direct_draw_alloc() {
|
||||
DirectDraw* instance = malloc(sizeof(DirectDraw));
|
||||
|
||||
instance->input = furi_record_open(RECORD_INPUT_EVENTS);
|
||||
instance->gui = furi_record_open(RECORD_GUI);
|
||||
instance->canvas = gui_direct_draw_acquire(instance->gui);
|
||||
|
||||
instance->input_subscription =
|
||||
furi_pubsub_subscribe(instance->input, gui_input_events_callback, instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void direct_draw_free(DirectDraw* instance) {
|
||||
furi_pubsub_unsubscribe(instance->input, instance->input_subscription);
|
||||
|
||||
instance->canvas = NULL;
|
||||
gui_direct_draw_release(instance->gui);
|
||||
furi_record_close(RECORD_GUI);
|
||||
furi_record_close(RECORD_INPUT_EVENTS);
|
||||
}
|
||||
|
||||
static void direct_draw_block(Canvas* canvas, uint32_t size, uint32_t counter) {
|
||||
size += 16;
|
||||
uint8_t width = canvas_width(canvas) - size;
|
||||
uint8_t height = canvas_height(canvas) - size;
|
||||
|
||||
uint8_t x = counter % width;
|
||||
if((counter / width) % 2) {
|
||||
x = width - x;
|
||||
}
|
||||
|
||||
uint8_t y = counter % height;
|
||||
if((counter / height) % 2) {
|
||||
y = height - y;
|
||||
}
|
||||
|
||||
canvas_draw_box(canvas, x, y, size, size);
|
||||
}
|
||||
|
||||
static void direct_draw_run(DirectDraw* instance) {
|
||||
size_t start = DWT->CYCCNT;
|
||||
size_t counter = 0;
|
||||
float fps = 0;
|
||||
|
||||
vTaskPrioritySet(furi_thread_get_current_id(), FuriThreadPriorityIdle);
|
||||
|
||||
do {
|
||||
size_t elapsed = DWT->CYCCNT - start;
|
||||
char buffer[BUFFER_SIZE] = {0};
|
||||
|
||||
if(elapsed >= 64000000) {
|
||||
fps = (float)counter / ((float)elapsed / 64000000.0f);
|
||||
|
||||
start = DWT->CYCCNT;
|
||||
counter = 0;
|
||||
}
|
||||
snprintf(buffer, BUFFER_SIZE, "FPS: %.1f", (double)fps);
|
||||
|
||||
canvas_reset(instance->canvas);
|
||||
canvas_set_color(instance->canvas, ColorXOR);
|
||||
direct_draw_block(instance->canvas, instance->counter % 16, instance->counter);
|
||||
direct_draw_block(instance->canvas, instance->counter * 2 % 16, instance->counter * 2);
|
||||
direct_draw_block(instance->canvas, instance->counter * 3 % 16, instance->counter * 3);
|
||||
direct_draw_block(instance->canvas, instance->counter * 4 % 16, instance->counter * 4);
|
||||
direct_draw_block(instance->canvas, instance->counter * 5 % 16, instance->counter * 5);
|
||||
canvas_draw_str(instance->canvas, 10, 10, buffer);
|
||||
canvas_commit(instance->canvas);
|
||||
|
||||
counter++;
|
||||
instance->counter++;
|
||||
furi_thread_yield();
|
||||
} while(!instance->stop);
|
||||
}
|
||||
|
||||
int32_t direct_draw_app(void* p) {
|
||||
UNUSED(p);
|
||||
|
||||
DirectDraw* instance = direct_draw_alloc();
|
||||
direct_draw_run(instance);
|
||||
direct_draw_free(instance);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user