186 lines
3.6 KiB
C
186 lines
3.6 KiB
C
|
#ifndef _VNC_GFX_H_
|
||
|
#define _VNC_GFX_H_
|
||
|
|
||
|
#include "Arduino_GFX_Library.h"
|
||
|
#include "VNC.h"
|
||
|
#include "VNC_config.h"
|
||
|
|
||
|
#ifdef ESP32
|
||
|
// #define SEPARATE_DRAW_TASK
|
||
|
#endif
|
||
|
|
||
|
#ifdef SEPARATE_DRAW_TASK
|
||
|
|
||
|
#define NUMBER_OF_DRAW_BUFFER 64
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
xQueueHandle xqh;
|
||
|
Arduino_GFX *gfx;
|
||
|
} ParamDrawTask;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int16_t x;
|
||
|
int16_t y;
|
||
|
int16_t w;
|
||
|
int16_t h;
|
||
|
bool isBitmap;
|
||
|
uint16_t *buf;
|
||
|
} DrawData;
|
||
|
|
||
|
static xQueueHandle _xqh;
|
||
|
static ParamDrawTask _pDrawTask;
|
||
|
static TaskHandle_t _draw_task_handle;
|
||
|
|
||
|
static DrawData drawDatas[NUMBER_OF_DRAW_BUFFER];
|
||
|
static int draw_queue_cnt = 0;
|
||
|
|
||
|
static void queueDrawTask(uint32_t x, uint32_t y, uint32_t w, uint32_t h, bool isBitmap, uint16_t *d)
|
||
|
{
|
||
|
log_i("queueDrawTask start.");
|
||
|
DrawData *dd = &drawDatas[draw_queue_cnt % NUMBER_OF_DRAW_BUFFER];
|
||
|
dd->x = x;
|
||
|
dd->y = y;
|
||
|
dd->w = w;
|
||
|
dd->h = h;
|
||
|
dd->isBitmap = isBitmap;
|
||
|
log_i("copy data start.");
|
||
|
uint16_t *p = &dd->buf[0];
|
||
|
if (isBitmap)
|
||
|
{
|
||
|
log_i("copy bitmap.");
|
||
|
int i = w * h;
|
||
|
while (i--)
|
||
|
{
|
||
|
*p++ = *d++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*p = *d;
|
||
|
}
|
||
|
log_i("copy data end.");
|
||
|
|
||
|
++draw_queue_cnt;
|
||
|
|
||
|
log_i("xQueueSend start.");
|
||
|
xQueueSend(_xqh, &dd, portMAX_DELAY);
|
||
|
log_i("xQueueSend end.");
|
||
|
|
||
|
log_i("queueDrawTask end.");
|
||
|
}
|
||
|
|
||
|
static void draw_task(void *arg)
|
||
|
{
|
||
|
DrawData *dd;
|
||
|
log_i("draw_task start.");
|
||
|
while (xQueueReceive(_xqh, &dd, portMAX_DELAY))
|
||
|
{
|
||
|
log_i("draw_task work start: x: %d, y: %d, w: %d, h: %d.", dd->x, dd->y, dd->w, dd->h);
|
||
|
if (dd->isBitmap)
|
||
|
{
|
||
|
gfx->draw16bitBeRGBBitmap(dd->x, dd->y, &dd->buf[0], dd->w, dd->h);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gfx->fillRect(dd->x, dd->y, dd->w, dd->h, dd->buf[0]);
|
||
|
}
|
||
|
log_i("draw_task work end.");
|
||
|
}
|
||
|
vQueueDelete(_xqh);
|
||
|
log_i("draw_task end.");
|
||
|
vTaskDelete(NULL);
|
||
|
}
|
||
|
|
||
|
void draw_task_setup()
|
||
|
{
|
||
|
_xqh = xQueueCreate(NUMBER_OF_DRAW_BUFFER, sizeof(DrawData));
|
||
|
_pDrawTask.xqh = _xqh;
|
||
|
_pDrawTask.gfx = gfx;
|
||
|
|
||
|
log_i("xTaskCreatePinnedToCore start");
|
||
|
xTaskCreatePinnedToCore(
|
||
|
(TaskFunction_t)draw_task,
|
||
|
(const char *const)"Draw Task",
|
||
|
(const uint32_t)1600,
|
||
|
(void *const)&_pDrawTask,
|
||
|
(UBaseType_t)configMAX_PRIORITIES - 1,
|
||
|
(TaskHandle_t *const)&_draw_task_handle,
|
||
|
(const BaseType_t)0);
|
||
|
log_i("xTaskCreatePinnedToCore end");
|
||
|
|
||
|
for (int i = 0; i < NUMBER_OF_DRAW_BUFFER; i++)
|
||
|
{
|
||
|
if (!drawDatas[i].buf)
|
||
|
{
|
||
|
drawDatas[i].buf = (uint16_t *)malloc(FB_SIZE * 2);
|
||
|
}
|
||
|
if (drawDatas[i].buf)
|
||
|
{
|
||
|
log_i("#%d draw buffer allocated.", i);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
log_e("#%d draw buffer allocat failed.", i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
class VNC_GFX : public VNCdisplay
|
||
|
{
|
||
|
public:
|
||
|
VNC_GFX(Arduino_GFX *gfx)
|
||
|
{
|
||
|
_gfx = gfx;
|
||
|
}
|
||
|
|
||
|
bool hasCopyRect(void)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
uint32_t getHeight(void)
|
||
|
{
|
||
|
return _gfx->height();
|
||
|
}
|
||
|
uint32_t getWidth(void)
|
||
|
{
|
||
|
return _gfx->width();
|
||
|
}
|
||
|
|
||
|
void draw_area(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t *data)
|
||
|
{
|
||
|
// DEBUG_VNC("draw_area(%d, %d, %d, %d, data)\n", x, y, w, h);
|
||
|
#ifdef SEPARATE_DRAW_TASK
|
||
|
queueDrawTask(x, y, w, h, true, (uint16_t *)data);
|
||
|
#else
|
||
|
// _gfx->draw16bitBeRGBBitmap(x, y, (uint16_t *)data, w, h);
|
||
|
_gfx->draw16bitRGBBitmap(x, y, (uint16_t *)data, w, h);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void draw_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint16_t color)
|
||
|
{
|
||
|
// DEBUG_VNC("draw_rect(%d, %d, %d, %d, color)\n", x, y, w, h);
|
||
|
// MSB_16_SET(color, color);
|
||
|
#ifdef SEPARATE_DRAW_TASK
|
||
|
queueDrawTask(x, y, w, h, false, &color);
|
||
|
#else
|
||
|
_gfx->fillRect(x, y, w, h, color);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void vnc_options_override(dfb_vnc_options *opt)
|
||
|
{
|
||
|
// opt->client.bigendian = 1;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
Arduino_GFX *_gfx;
|
||
|
};
|
||
|
|
||
|
#endif /* _VNC_GFX_H_ */
|