1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(gpu): add renesas dav2d GPU support

This commit is contained in:
Gabor Kiss-Vamosi 2023-12-12 11:43:21 +01:00
parent 6a0db1fd59
commit 710e134abf
15 changed files with 2871 additions and 0 deletions

View File

@ -122,6 +122,9 @@
/* Use NXP's PXP on iMX RTxxx platforms. */
#define LV_USE_DRAW_PXP 0
/* Use Renesas Dave2D on RA platforms. */
#define LV_USE_DRAW_DAVE2D 0
/* Draw using cached SDL textures*/
#define LV_USE_DRAW_SDL 0

View File

@ -0,0 +1,637 @@
/**
* @file lv_draw_dave2d.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
/*********************
* DEFINES
*********************/
#define DRAW_UNIT_ID_DAVE2D 4
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
#if LV_USE_OS
static void _dave2d_render_thread_cb(void * ptr);
#endif
static void execute_drawing(lv_draw_dave2d_unit_t * u);
#if defined(RENESAS_CORTEX_M85)
#if (BSP_CFG_DCACHE_ENABLED)
static void _dave2d_buf_invalidate_cache_cb(void * buf, uint32_t stride, lv_color_format_t color_format,
const lv_area_t * area);
#endif
#endif
static void _dave2d_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const lv_area_t * dest_area,
void * src_buf, uint32_t src_w, uint32_t src_h, const lv_area_t * src_area, lv_color_format_t color_format);
static int32_t _dave2d_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
static d2_s32 lv_dave2d_init(void);
static void lv_draw_buf_dave2d_init_handlers(void);
void dave2d_execute_dlist_and_flush(void);
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
d2_device * _d2_handle;
d2_renderbuffer * _renderbuffer;
d2_renderbuffer * _blit_renderbuffer;
lv_ll_t _ll_Dave2D_Tasks;
#if LV_USE_OS
lv_mutex_t xd2Semaphore;
#endif
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_draw_dave2d_init(void)
{
d2_s32 result = D2_OK;
lv_draw_buf_dave2d_init_handlers();
lv_draw_dave2d_unit_t * draw_dave2d_unit = lv_draw_create_unit(sizeof(lv_draw_dave2d_unit_t));
draw_dave2d_unit->base_unit.dispatch_cb = lv_draw_dave2d_dispatch;
draw_dave2d_unit->base_unit.evaluate_cb = _dave2d_evaluate;
draw_dave2d_unit->idx = DRAW_UNIT_ID_DAVE2D;
result = lv_dave2d_init();
if(D2_OK != result) {
__BKPT(0);
}
#if LV_USE_OS
lv_result_t res;
res = lv_mutex_init(&xd2Semaphore);
if(LV_RESULT_OK != res) {
__BKPT(0);
}
draw_dave2d_unit->pd2Mutex = &xd2Semaphore;
#endif
draw_dave2d_unit->d2_handle = _d2_handle;
draw_dave2d_unit->renderbuffer = _renderbuffer;
_lv_ll_init(&_ll_Dave2D_Tasks, 4);
#if LV_USE_OS
lv_thread_init(&draw_dave2d_unit->thread, LV_THREAD_PRIO_HIGH, _dave2d_render_thread_cb, 8 * 1024, draw_dave2d_unit);
#endif
}
/**********************
* STATIC FUNCTIONS
**********************/
static void lv_draw_buf_dave2d_init_handlers(void)
{
lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers();
#if defined(RENESAS_CORTEX_M85)
#if (BSP_CFG_DCACHE_ENABLED)
handlers->invalidate_cache_cb = _dave2d_buf_invalidate_cache_cb;
#endif
#endif
handlers->buf_copy_cb = _dave2d_buf_copy;
}
#if defined(RENESAS_CORTEX_M85)
#if (BSP_CFG_DCACHE_ENABLED)
static void _dave2d_buf_invalidate_cache_cb(void * buf, uint32_t stride, lv_color_format_t color_format,
const lv_area_t * area)
{
uint8_t * address = buf;
int32_t i = 0;
uint32_t bytes_per_pixel = lv_color_format_get_size(color_format);
int32_t width = lv_area_get_width(area);
int32_t lines = lv_area_get_height(area);
int32_t bytes_to_flush_per_line = (int32_t)width * (int32_t)bytes_per_pixel;
/* Stride is in bytes, not pixels */
address = address + (area->x1 * (int32_t)bytes_per_pixel) + (stride * (uint32_t)area->y1);
for(i = 0; i < lines; i++) {
SCB_CleanInvalidateDCache_by_Addr(address, bytes_to_flush_per_line);
address += stride;
}
}
#endif
#endif
static void _dave2d_buf_copy(void * dest_buf, uint32_t dest_w, uint32_t dest_h, const lv_area_t * dest_area,
void * src_buf, uint32_t src_w, uint32_t src_h, const lv_area_t * src_area, lv_color_format_t color_format)
{
d2_s32 result;
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(&xd2Semaphore);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
d2_u32 src_blend_mode = d2_getblendmodesrc(_d2_handle);
d2_u32 dst_blend_mode = d2_getblendmodedst(_d2_handle);
result = d2_selectrenderbuffer(_d2_handle, _blit_renderbuffer);
if(D2_OK != result) {
__BKPT(0);
}
result = d2_setblendmode(_d2_handle, d2_bm_one, d2_bm_zero);
if(D2_OK != result) {
__BKPT(0);
}
// Generate render operations
result = d2_framebuffer(_d2_handle, (uint16_t *)dest_buf, DISPLAY_HSIZE_INPUT0, DISPLAY_BUFFER_STRIDE_PIXELS_INPUT0,
DISPLAY_VSIZE_INPUT0, lv_draw_dave2d_cf_fb_get());
if(D2_OK != result) {
__BKPT(0);
}
result = d2_cliprect(_d2_handle, (d2_border)dest_area->x1, (d2_border)dest_area->y1, (d2_border)dest_area->x2,
(d2_border)dest_area->y2);
if(D2_OK != result) {
__BKPT(0);
}
result = d2_setblitsrc(_d2_handle, (void *) src_buf, (d2_s32)src_w, (d2_s32)src_w, (d2_s32)src_h,
lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(color_format));
if(D2_OK != result) {
__BKPT(0);
}
result = d2_blitcopy(_d2_handle, (d2_s32)src_w, (d2_s32)src_h, (d2_blitpos)src_area->x1, (d2_blitpos)src_area->y1,
D2_FIX4(dest_w), D2_FIX4(dest_h),
D2_FIX4(dest_area->x1), D2_FIX4(dest_area->y1), 0);
if(D2_OK != result) {
__BKPT(0);
}
// Execute render operations
result = d2_executerenderbuffer(_d2_handle, _blit_renderbuffer, 0);
if(D2_OK != result) {
__BKPT(0);
}
result = d2_flushframe(_d2_handle);
if(D2_OK != result) {
__BKPT(0);
}
result = d2_selectrenderbuffer(_d2_handle, _renderbuffer);
if(D2_OK != result) {
__BKPT(0);
}
result = d2_setblendmode(_d2_handle, src_blend_mode, dst_blend_mode);
if(D2_OK != result) {
__BKPT(0);
}
#if LV_USE_OS
status = lv_mutex_unlock(&xd2Semaphore);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
#define USE_D2 (1)
static int32_t _dave2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t)
{
LV_UNUSED(u);
int32_t ret = 0;
switch(t->type) {
case LV_DRAW_TASK_TYPE_FILL: {
#if USE_D2
lv_draw_fill_dsc_t * dsc = t->draw_dsc;
if(dsc->grad.dir == LV_GRAD_DIR_NONE
|| ((dsc->grad.dir != LV_GRAD_DIR_NONE)
&& ((dsc->grad.stops[0].color.blue == dsc->grad.stops[dsc->grad.stops_count - 1].color.blue)
&& (dsc->grad.stops[0].color.red == dsc->grad.stops[dsc->grad.stops_count - 1].color.red)
&& (dsc->grad.stops[0].color.green == dsc->grad.stops[dsc->grad.stops_count - 1].color.green)))) {
t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D;
t->preference_score = 0;
}
else
#endif
{
__NOP();
}
ret = 0;
break;
}
#if 0
case LV_DRAW_TASK_TYPE_BG_IMG: {
ret = 0;
break;
}
#endif
case LV_DRAW_TASK_TYPE_LAYER: {
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_IMAGE: {
#if USE_D2
t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D;
t->preference_score = 0;
#endif
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_BORDER: {
#if USE_D2
t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D;
t->preference_score = 0;
#endif
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_BOX_SHADOW: {
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_LABEL: {
#if USE_D2
t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D;
t->preference_score = 0;
#endif
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_LINE: {
#if USE_D2
t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D;
t->preference_score = 0;
#endif
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_ARC: {
#if USE_D2
t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D;
t->preference_score = 0;
#endif
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_TRIANGLE: {
#if USE_D2
lv_draw_fill_dsc_t * dsc = t->draw_dsc;
if(dsc->grad.dir == LV_GRAD_DIR_NONE
|| ((dsc->grad.dir != LV_GRAD_DIR_NONE)
&& ((dsc->grad.stops[0].color.blue == dsc->grad.stops[dsc->grad.stops_count - 1].color.blue)
&& (dsc->grad.stops[0].color.red == dsc->grad.stops[dsc->grad.stops_count - 1].color.red)
&& (dsc->grad.stops[0].color.green == dsc->grad.stops[dsc->grad.stops_count - 1].color.green)))) {
t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D;
t->preference_score = 0;
}
else {
}
#endif
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_MASK_RECTANGLE: {
#if 0//USE_D2
t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D;
t->preference_score = 0;
#endif
ret = 0;
break;
}
case LV_DRAW_TASK_TYPE_MASK_BITMAP: {
ret = 0;
break;
}
default:
ret = 0;
break;
}
return ret;
}
#define DAVE2D_REFFERING_WATERMARK 10
static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
{
lv_draw_dave2d_unit_t * draw_dave2d_unit = (lv_draw_dave2d_unit_t *) draw_unit;
#if (0 == D2_RENDER_EACH_OPERATION)
static uint32_t ref_count = 0;
#endif
/*Return immediately if it's busy with draw task*/
if(draw_dave2d_unit->task_act) return 0;
lv_draw_task_t * t = NULL;
t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_DAVE2D);
/* Return 0 is no selection, some tasks can be supported by other units. */
if(t == NULL) {
#if (0 == D2_RENDER_EACH_OPERATION)
if(false == _lv_ll_is_empty(&_ll_Dave2D_Tasks)) {
ref_count = 0;
dave2d_execute_dlist_and_flush();
}
#endif
return 0;
}
if(t->preferred_draw_unit_id != DRAW_UNIT_ID_DAVE2D) {
return 0;
}
#if (0 == D2_RENDER_EACH_OPERATION)
ref_count += lv_draw_get_dependent_count(t);
if(DAVE2D_REFFERING_WATERMARK < ref_count) {
ref_count = 0;
dave2d_execute_dlist_and_flush();
}
struct _lv_draw_task_t ** p_new_list_entry;
p_new_list_entry = _lv_ll_ins_tail(&_ll_Dave2D_Tasks);
*p_new_list_entry = t;
#endif
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
draw_dave2d_unit->base_unit.target_layer = layer;
draw_dave2d_unit->base_unit.clip_area = &t->clip_area;
draw_dave2d_unit->task_act = t;
#if LV_USE_OS
/*Let the render thread work*/
lv_thread_sync_signal(&draw_dave2d_unit->sync);
#else
execute_drawing(draw_dave2d_unit);
#if (D2_RENDER_EACH_OPERATION)
draw_dave2d_unit->task_act->state = LV_DRAW_TASK_STATE_READY;
#endif
draw_dave2d_unit->task_act = NULL;
/*The draw unit is free now. Request a new dispatching as it can get a new task*/
lv_draw_dispatch_request();
#endif
return 1;
}
#if LV_USE_OS
static void _dave2d_render_thread_cb(void * ptr)
{
lv_draw_dave2d_unit_t * u = ptr;
lv_thread_sync_init(&u->sync);
while(1) {
while(u->task_act == NULL) {
lv_thread_sync_wait(&u->sync);
}
execute_drawing(u);
/*Cleanup*/
#if (D2_RENDER_EACH_OPERATION)
u->task_act->state = LV_DRAW_TASK_STATE_READY;
#endif
u->task_act = NULL;
/*The draw unit is free now. Request a new dispatching as it can get a new task*/
lv_draw_dispatch_request();
}
}
#endif
static void execute_drawing(lv_draw_dave2d_unit_t * u)
{
/*Render the draw task*/
lv_draw_task_t * t = u->task_act;
lv_layer_t * layer = u->base_unit.target_layer;
#if defined(RENESAS_CORTEX_M85)
#if (BSP_CFG_DCACHE_ENABLED)
lv_area_t clipped_area;
int32_t x;
int32_t y;
_lv_area_intersect(&clipped_area, &t->area, u->base_unit.clip_area);
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
lv_area_move(&clipped_area, x, y);
/* Invalidate cache */
lv_draw_buf_invalidate_cache(layer->buf, layer->buf_stride, layer->color_format, &clipped_area);
#endif
#endif
switch(t->type) {
case LV_DRAW_TASK_TYPE_FILL:
lv_draw_dave2d_fill(u, t->draw_dsc, &t->area);
break;
case LV_DRAW_TASK_TYPE_BORDER:
lv_draw_dave2d_border(u, t->draw_dsc, &t->area);
break;
case LV_DRAW_TASK_TYPE_BOX_SHADOW:
//lv_draw_dave2d_box_shadow(u, t->draw_dsc, &t->area);
break;
#if 0
case LV_DRAW_TASK_TYPE_BG_IMG:
//lv_draw_dave2d_bg_image(u, t->draw_dsc, &t->area);
break;
#endif
case LV_DRAW_TASK_TYPE_LABEL:
lv_draw_dave2d_label(u, t->draw_dsc, &t->area);
break;
case LV_DRAW_TASK_TYPE_IMAGE:
lv_draw_dave2d_image(u, t->draw_dsc, &t->area);
break;
case LV_DRAW_TASK_TYPE_LINE:
lv_draw_dave2d_line(u, t->draw_dsc);
break;
case LV_DRAW_TASK_TYPE_ARC:
lv_draw_dave2d_arc(u, t->draw_dsc, &t->area);
break;
case LV_DRAW_TASK_TYPE_TRIANGLE:
lv_draw_dave2d_triangle(u, t->draw_dsc);
break;
case LV_DRAW_TASK_TYPE_LAYER:
//lv_draw_dave2d_layer(u, t->draw_dsc, &t->area);
break;
case LV_DRAW_TASK_TYPE_MASK_RECTANGLE:
//lv_draw_dave2d_mask_rect(u, t->draw_dsc, &t->area);
break;
default:
break;
}
}
static d2_s32 lv_dave2d_init(void)
{
d2_s32 result = D2_OK;
if(_d2_handle != NULL) {
return D2_NOMEMORY;
}
_d2_handle = d2_opendevice(0);
if(_d2_handle == NULL) {
return D2_NOMEMORY;
}
/* bind the hardware */
result = d2_inithw(_d2_handle, 0);
if(result != D2_OK) {
LV_LOG_ERROR("Could NOT d2_inithw\n");
d2_closedevice(_d2_handle);
return result;
}
//
// Set various D2 parameters
//
result = d2_setblendmode(_d2_handle, d2_bm_alpha, d2_bm_one_minus_alpha);
result = d2_setalphamode(_d2_handle, d2_am_constant);
result = d2_setalpha(_d2_handle, UINT8_MAX);
result = d2_setantialiasing(_d2_handle, 1);
result = d2_setlinecap(_d2_handle, d2_lc_butt);
result = d2_setlinejoin(_d2_handle, d2_lj_miter);
/* set blocksize for default displaylist */
result = d2_setdlistblocksize(_d2_handle, 25);
if(D2_OK != result) {
LV_LOG_ERROR("Could NOT d2_setdlistblocksize\n");
d2_closedevice(_d2_handle);
return result;
}
_blit_renderbuffer = d2_newrenderbuffer(_d2_handle, 20, 20);
if(!_blit_renderbuffer) {
LV_LOG_ERROR("NO renderbuffer\n");
d2_closedevice(_d2_handle);
return D2_NOMEMORY;
}
_renderbuffer = d2_newrenderbuffer(_d2_handle, 20, 20);
if(!_renderbuffer) {
LV_LOG_ERROR("NO renderbuffer\n");
d2_closedevice(_d2_handle);
return D2_NOMEMORY;
}
result = d2_selectrenderbuffer(_d2_handle, _renderbuffer);
if(D2_OK != result) {
LV_LOG_ERROR("Could NOT d2_selectrenderbuffer\n");
d2_closedevice(_d2_handle);
}
return result;
}
void dave2d_execute_dlist_and_flush(void)
{
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(&xd2Semaphore);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
d2_s32 result;
struct _lv_draw_task_t ** p_list_entry;
struct _lv_draw_task_t * p_list_entry1;
// Execute render operations
result = d2_executerenderbuffer(_d2_handle, _renderbuffer, 0);
if(D2_OK != result) {
__BKPT(0);
}
result = d2_flushframe(_d2_handle);
if(D2_OK != result) {
__BKPT(0);
}
result = d2_selectrenderbuffer(_d2_handle, _renderbuffer);
if(D2_OK != result) {
__BKPT(0);
}
while(false == _lv_ll_is_empty(&_ll_Dave2D_Tasks)) {
p_list_entry = _lv_ll_get_tail(&_ll_Dave2D_Tasks);
p_list_entry1 = *p_list_entry;
p_list_entry1->state = LV_DRAW_TASK_STATE_READY;
_lv_ll_remove(&_ll_Dave2D_Tasks, p_list_entry);
lv_free(p_list_entry);
}
#if LV_USE_OS
status = lv_mutex_unlock(&xd2Semaphore);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,94 @@
#ifndef LV_DRAW_DAVE2D_H
#define LV_DRAW_DAVE2D_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../../lv_conf_internal.h"
#if LV_USE_DRAW_DAVE2D
#include "../../lv_draw.h"
#include "hal_data.h"
#include "lv_draw_dave2d_utils.h"
/*********************
* DEFINES
*********************/
#define D2_RENDER_EACH_OPERATION (1)
/**********************
* TYPEDEFS
**********************/
typedef struct {
lv_draw_unit_t base_unit;
struct _lv_draw_task_t * task_act;
#if LV_USE_OS
lv_thread_sync_t sync;
lv_thread_t thread;
#endif
uint32_t idx;
d2_device * d2_handle;
d2_renderbuffer * renderbuffer;
#if LV_USE_OS
lv_mutex_t * pd2Mutex;
#endif
} lv_draw_dave2d_unit_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_draw_dave2d_init(void);
void lv_draw_dave2d_image(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_area_t * coords);
void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords);
void lv_draw_dave2d_border(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc,
const lv_area_t * coords);
void lv_draw_dave2d_box_shadow(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc,
const lv_area_t * coords);
//void lv_draw_dave2d_bg_image(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_bg_image_dsc_t * dsc, const lv_area_t * coords);
void lv_draw_dave2d_label(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords);
void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords);
void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc);
void lv_draw_dave2d_layer(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_area_t * coords);
void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc);
void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc,
const lv_area_t * coords);
void lv_draw_dave2d_transform(lv_draw_dave2d_unit_t * draw_unit, const lv_area_t * dest_area, const void * src_buf,
int32_t src_w, int32_t src_h, int32_t src_stride,
const lv_draw_image_dsc_t * draw_dsc, const lv_draw_image_sup_t * sup, lv_color_format_t cf, void * dest_buf);
/***********************
* GLOBAL VARIABLES
***********************/
/**********************
* MACROS
**********************/
#endif /*LV_USE_DRAW_DAVE2D*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,156 @@
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords)
{
uint32_t flags = 0;
int32_t sin_start;
int32_t cos_start;
int32_t sin_end;
int32_t cos_end;
d2_s32 result;
lv_area_t clipped_area;
lv_area_t buffer_area;
lv_point_t arc_centre;
int32_t x;
int32_t y;
if(!_lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return;
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
buffer_area = u->base_unit.target_layer->buf_area;
arc_centre = dsc->center;
arc_centre.x = arc_centre.x - buffer_area.x1;
arc_centre.y = arc_centre.y - buffer_area.y1;
lv_area_move(&clipped_area, x, y);
lv_area_move(&buffer_area, x, y);
//
// If both angles are equal (e.g. 0 and 0 or 180 and 180) nothing has to be done
//
if(dsc->start_angle == dsc->end_angle) {
return; // Nothing to do, no angle - no arc
}
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
#if D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
#endif
//
// Generate render operations
//
d2_framebuffer(u->d2_handle,
u->base_unit.target_layer->buf,
(d2_s32)u->base_unit.target_layer->buf_stride / lv_color_format_get_size(u->base_unit.target_layer->color_format),
(d2_u32)lv_area_get_width(&buffer_area),
(d2_u32)lv_area_get_height(&buffer_area),
lv_draw_dave2d_cf_fb_get());
d2_setalpha(u->d2_handle, dsc->opa);
d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->color));
result = d2_cliprect(u->d2_handle, (d2_border)clipped_area.x1, (d2_border)clipped_area.y1, (d2_border)clipped_area.x2,
(d2_border)clipped_area.y2);
if(D2_OK != result) {
__BKPT(0);
}
if(360 <= LV_ABS(dsc->start_angle - dsc->end_angle)) {
d2_rendercircle(u->d2_handle,
(d2_point)D2_FIX4(arc_centre.x),
(d2_point) D2_FIX4(arc_centre.y),
(d2_width) D2_FIX4(dsc->radius - dsc->width / 2),
(d2_width) D2_FIX4(dsc->width));
}
else { //An ARC, not a full circle
//
// If the difference between both is larger than 180 degrees we must use the concave flag
//
/** Set d2_wf_concave flag if the pie object to draw is concave shape. */
if((LV_ABS(dsc->start_angle - dsc->end_angle) > 180) || ((dsc->end_angle < dsc->start_angle) &&
(LV_ABS(dsc->start_angle - (dsc->end_angle + 360)) > 180))) {
flags = d2_wf_concave;
}
else {
flags = 0;
}
sin_start = lv_trigo_sin((int16_t)dsc->start_angle);
cos_start = lv_trigo_cos((int16_t)dsc->start_angle);
sin_end = lv_trigo_sin((int16_t)dsc->end_angle);
cos_end = lv_trigo_cos((int16_t)dsc->end_angle);
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(arc_centre.x),
(d2_point) D2_FIX4(arc_centre.y),
(d2_width) D2_FIX4(dsc->radius - dsc->width / 2),
(d2_width) D2_FIX4(dsc->width),
-(d2_s32)(sin_start << 1),
(d2_s32)(cos_start << 1),
(d2_s32)(sin_end << 1),
-(d2_s32)(cos_end << 1),
flags);
if(D2_OK != result) {
__BKPT(0);
}
if(dsc->rounded) {
lv_point_t start_coord;
lv_point_t end_coord;
start_coord.x = arc_centre.x + (int16_t)(((dsc->radius - dsc->width / 2) * cos_start) >> LV_TRIGO_SHIFT);
start_coord.y = arc_centre.y + (int16_t)(((dsc->radius - dsc->width / 2) * sin_start) >> LV_TRIGO_SHIFT);
/** Render a circle. */
d2_rendercircle(u->d2_handle,
(d2_point) D2_FIX4((uint16_t)(start_coord.x)),
(d2_point) D2_FIX4((uint16_t)(start_coord.y)),
(d2_width) D2_FIX4(dsc->width / 2), 0);
end_coord.x = arc_centre.x + (int16_t)(((dsc->radius - dsc->width / 2) * cos_end) >> LV_TRIGO_SHIFT);
end_coord.y = arc_centre.y + (int16_t)(((dsc->radius - dsc->width / 2) * sin_end) >> LV_TRIGO_SHIFT);
/** Render a circle. */
d2_rendercircle(u->d2_handle,
(d2_point) D2_FIX4((uint16_t)(end_coord.x)),
(d2_point) D2_FIX4((uint16_t)(end_coord.y)),
(d2_width) D2_FIX4(dsc->width / 2), 0);
}
}
//
// Execute render operations
//
#if D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
d2_flushframe(u->d2_handle);
#endif
#if LV_USE_OS
status = lv_mutex_unlock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,396 @@
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * draw_unit, const lv_area_t * outer_area,
const lv_area_t * inner_area,
int32_t rout, int32_t rin, lv_color_t color, lv_opa_t opa);
static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * draw_unit, const lv_area_t * outer_area,
const lv_area_t * inner_area,
lv_color_t color, lv_opa_t opa);
void lv_draw_dave2d_border(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc,
const lv_area_t * coords)
{
if(dsc->opa <= LV_OPA_MIN) return;
if(dsc->width == 0) return;
if(dsc->side == LV_BORDER_SIDE_NONE) return;
int32_t coords_w = lv_area_get_width(coords);
int32_t coords_h = lv_area_get_height(coords);
int32_t rout = dsc->radius;
int32_t short_side = LV_MIN(coords_w, coords_h);
if(rout > short_side >> 1) rout = short_side >> 1;
/*Get the inner area*/
lv_area_t area_inner;
lv_area_copy(&area_inner, coords);
area_inner.x1 += ((dsc->side & LV_BORDER_SIDE_LEFT) ? dsc->width : - (dsc->width + rout));
area_inner.x2 -= ((dsc->side & LV_BORDER_SIDE_RIGHT) ? dsc->width : - (dsc->width + rout));
area_inner.y1 += ((dsc->side & LV_BORDER_SIDE_TOP) ? dsc->width : - (dsc->width + rout));
area_inner.y2 -= ((dsc->side & LV_BORDER_SIDE_BOTTOM) ? dsc->width : - (dsc->width + rout));
int32_t rin = rout - dsc->width;
if(rin < 0) rin = 0;
if(rout == 0 && rin == 0) {
dave2d_draw_border_simple(draw_unit, coords, &area_inner, dsc->color, dsc->opa);
}
else {
dave2d_draw_border_complex(draw_unit, coords, &area_inner, rout, rin, dsc->color, dsc->opa);
}
}
static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * u, const lv_area_t * outer_area,
const lv_area_t * inner_area,
lv_color_t color, lv_opa_t opa)
{
lv_area_t clip_area;
lv_area_t local_outer_area;
lv_area_t local_inner_area;
lv_area_t buffer_area;
int32_t x;
int32_t y;
bool is_common;
is_common = _lv_area_intersect(&clip_area, outer_area, u->base_unit.clip_area);
if(!is_common) return;
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
buffer_area = u->base_unit.target_layer->buf_area;
local_outer_area = *outer_area;
local_inner_area = *inner_area;
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
lv_area_move(&clip_area, x, y);
lv_area_move(&buffer_area, x, y);
lv_area_move(&local_outer_area, x, y);
lv_area_move(&local_inner_area, x, y);
#if D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
#endif
//
// Generate render operations
//
d2_framebuffer(u->d2_handle,
u->base_unit.target_layer->buf,
(d2_s32)u->base_unit.target_layer->buf_stride / lv_color_format_get_size(u->base_unit.target_layer->color_format),
(d2_u32)lv_area_get_width(&buffer_area),
(d2_u32)lv_area_get_height(&buffer_area),
lv_draw_dave2d_cf_fb_get());
d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(color));
d2_setalpha(u->d2_handle, opa);
d2_cliprect(u->d2_handle, (d2_border)clip_area.x1, (d2_border)clip_area.y1, (d2_border)clip_area.x2,
(d2_border)clip_area.y2);
lv_area_t a;
bool top_side = local_outer_area.y1 <= local_inner_area.y1;
bool bottom_side = local_outer_area.y2 >= local_inner_area.y2;
bool left_side = local_outer_area.x1 <= local_inner_area.x1;
bool right_side = local_outer_area.x2 >= local_inner_area.x2;
/*Top*/
a.x1 = local_outer_area.x1;
a.x2 = local_outer_area.x2;
a.y1 = local_outer_area.y1;
a.y2 = local_inner_area.y1 - 1;
if(top_side) {
d2_renderbox(u->d2_handle, (d2_point)D2_FIX4(a.x1),
(d2_point)D2_FIX4(a.y1),
(d2_point)D2_FIX4(lv_area_get_width(&a)),
(d2_point)D2_FIX4(lv_area_get_height(&a)));
}
/*Bottom*/
a.y1 = local_inner_area.y2 + 1;
a.y2 = local_outer_area.y2;
if(bottom_side) {
d2_renderbox(u->d2_handle, (d2_point)D2_FIX4(a.x1),
(d2_point)D2_FIX4(a.y1),
(d2_point)D2_FIX4(lv_area_get_width(&a)),
(d2_point)D2_FIX4(lv_area_get_height(&a)));
}
/*Left*/
a.x1 = local_outer_area.x1;
a.x2 = local_inner_area.x1 - 1;
a.y1 = (top_side) ? local_inner_area.y1 : local_outer_area.y1;
a.y2 = (bottom_side) ? local_inner_area.y2 : local_outer_area.y2;
if(left_side) {
d2_renderbox(u->d2_handle, (d2_point)D2_FIX4(a.x1),
(d2_point)D2_FIX4(a.y1),
(d2_point)D2_FIX4(lv_area_get_width(&a)),
(d2_point)D2_FIX4(lv_area_get_height(&a)));
}
/*Right*/
a.x1 = local_inner_area.x2 + 1;
a.x2 = local_outer_area.x2;
if(right_side) {
d2_renderbox(u->d2_handle, (d2_point)D2_FIX4(a.x1),
(d2_point)D2_FIX4(a.y1),
(d2_point)D2_FIX4(lv_area_get_width(&a)),
(d2_point)D2_FIX4(lv_area_get_height(&a)));
}
//
// Execute render operations
//
#if D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
d2_flushframe(u->d2_handle);
#endif
#if LV_USE_OS
status = lv_mutex_unlock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_t * orig_outer_area,
const lv_area_t * orig_inner_area,
int32_t rout, int32_t rin, lv_color_t color, lv_opa_t opa)
{
#if LV_DRAW_SW_COMPLEX
/*Get clipped draw area which is the real draw area.
*It is always the same or inside `coords`*/
lv_area_t draw_area;
lv_area_t outer_area;
lv_area_t inner_area;
lv_area_t buffer_area;
int32_t x;
int32_t y;
d2_s32 result;
d2_u32 flags = 0;
outer_area = *orig_outer_area;
inner_area = *orig_inner_area;
if(!_lv_area_intersect(&draw_area, &outer_area, u->base_unit.clip_area)) return;
int32_t draw_area_w = lv_area_get_width(&draw_area);
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
buffer_area = u->base_unit.target_layer->buf_area;
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
lv_area_move(&draw_area, x, y);
lv_area_move(&buffer_area, x, y);
lv_area_move(&outer_area, x, y);
lv_area_move(&inner_area, x, y);
#if D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
#endif
//
// Generate render operations
//
d2_framebuffer(u->d2_handle,
u->base_unit.target_layer->buf,
(d2_s32)u->base_unit.target_layer->buf_stride / lv_color_format_get_size(u->base_unit.target_layer->color_format),
(d2_u32)lv_area_get_width(&buffer_area),
(d2_u32)lv_area_get_height(&buffer_area),
lv_draw_dave2d_cf_fb_get());
d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(color));
d2_setalpha(u->d2_handle, opa);
d2_cliprect(u->d2_handle, (d2_border)draw_area.x1, (d2_border)draw_area.y1, (d2_border)draw_area.x2,
(d2_border)draw_area.y2);
lv_area_t blend_area;
/*Calculate the x and y coordinates where the straight parts area are */
lv_area_t core_area;
core_area.x1 = LV_MAX(outer_area.x1 + rout, inner_area.x1);
core_area.x2 = LV_MIN(outer_area.x2 - rout, inner_area.x2);
core_area.y1 = LV_MAX(outer_area.y1 + rout, inner_area.y1);
core_area.y2 = LV_MIN(outer_area.y2 - rout, inner_area.y2);
bool top_side = outer_area.y1 <= inner_area.y1;
bool bottom_side = outer_area.y2 >= inner_area.y2;
/*No masks*/
bool left_side = outer_area.x1 <= inner_area.x1;
bool right_side = outer_area.x2 >= inner_area.x2;
/*Draw the straight lines first */
if(top_side) {
blend_area.x1 = core_area.x1;
blend_area.x2 = core_area.x2;
blend_area.y1 = outer_area.y1;
blend_area.y2 = inner_area.y1 - 1;
d2_renderbox(u->d2_handle,
(d2_point)D2_FIX4(blend_area.x1),
(d2_point)D2_FIX4(blend_area.y1),
(d2_point)D2_FIX4(lv_area_get_width(&blend_area)),
(d2_point)D2_FIX4(lv_area_get_height(&blend_area)));
}
if(bottom_side) {
blend_area.x1 = core_area.x1;
blend_area.x2 = core_area.x2;
blend_area.y1 = inner_area.y2 + 1;
blend_area.y2 = outer_area.y2;
d2_renderbox(u->d2_handle,
(d2_point)D2_FIX4(blend_area.x1),
(d2_point)D2_FIX4(blend_area.y1),
(d2_point)D2_FIX4(lv_area_get_width(&blend_area)),
(d2_point)D2_FIX4(lv_area_get_height(&blend_area)));
}
if(left_side) {
blend_area.x1 = outer_area.x1;
blend_area.x2 = inner_area.x1 - 1;
blend_area.y1 = core_area.y1;
blend_area.y2 = core_area.y2;
d2_renderbox(u->d2_handle,
(d2_point)D2_FIX4(blend_area.x1),
(d2_point)D2_FIX4(blend_area.y1),
(d2_point)D2_FIX4(lv_area_get_width(&blend_area)),
(d2_point)D2_FIX4(lv_area_get_height(&blend_area)));
}
if(right_side) {
blend_area.x1 = inner_area.x2 + 1;
blend_area.x2 = outer_area.x2;
blend_area.y1 = core_area.y1;
blend_area.y2 = core_area.y2;
d2_renderbox(u->d2_handle,
(d2_point)D2_FIX4(blend_area.x1),
(d2_point)D2_FIX4(blend_area.y1),
(d2_point)D2_FIX4(lv_area_get_width(&blend_area)),
(d2_point)D2_FIX4(lv_area_get_height(&blend_area)));
}
/*Draw the corners*/
int32_t blend_w;
/*Left corners*/
blend_area.x1 = draw_area.x1;
blend_area.x2 = LV_MIN(draw_area.x2, core_area.x1 - 1);
blend_w = lv_area_get_width(&blend_area);
if(blend_w > 0) {
if(left_side || top_side) {
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(core_area.x1),
(d2_point) D2_FIX4(core_area.y1),
(d2_width) D2_FIX4(rout),
(d2_width) D2_FIX4((rout - rin)),
(d2_s32) D2_FIX16(0), // 180 Degrees
(d2_s32) D2_FIX16((int16_t) -1),
(d2_s32) D2_FIX16((int16_t) -1),//( 270 Degrees
(d2_s32) D2_FIX16(0),
flags);
if(D2_OK != result) {
__BKPT(0);
}
}
if(left_side || bottom_side) {
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(core_area.x1),
(d2_point) D2_FIX4(core_area.y2),
(d2_width) D2_FIX4(rout),
(d2_width) D2_FIX4((rout - rin)),
(d2_s32) D2_FIX16((int16_t) -1), //90 degrees
(d2_s32) D2_FIX16(0),
(d2_s32) D2_FIX16(0), //180 degrees
(d2_s32) D2_FIX16(1),
flags);
if(D2_OK != result) {
__BKPT(0);
}
}
/*Right corners*/
blend_area.x1 = LV_MAX(draw_area.x1, blend_area.x2 + 1); /*To not overlap with the left side*/
blend_area.x1 = LV_MAX(draw_area.x1, core_area.x2 + 1);
blend_area.x2 = draw_area.x2;
blend_w = lv_area_get_width(&blend_area);
if(blend_w > 0) {
if(right_side || top_side) {
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(core_area.x2),
(d2_point) D2_FIX4(core_area.y1),
(d2_width) D2_FIX4(rout),
(d2_width) D2_FIX4((rout - rin)),
(d2_s32) D2_FIX16((int16_t)1), // 270 Degrees
(d2_s32) D2_FIX16(0),
(d2_s32) D2_FIX16(0),// 0 degrees
(d2_s32) D2_FIX16(-1),
flags);
if(D2_OK != result) {
__BKPT(0);
}
}
if(right_side || bottom_side) {
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(core_area.x2),
(d2_point) D2_FIX4(core_area.y2),
(d2_width) D2_FIX4(rout),
(d2_width) D2_FIX4((rout - rin)),
(d2_s32) D2_FIX16(0),// 0 degrees
(d2_s32) D2_FIX16(1),
(d2_s32) D2_FIX16(1),// 90 degrees
(d2_s32) D2_FIX16(0),
flags);
if(D2_OK != result) {
__BKPT(0);
}
}
}
}
//
// Execute render operations
//
#if D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
d2_flushframe(u->d2_handle);
#endif
#if LV_USE_OS
status = lv_mutex_unlock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
#endif /*LV_DRAW_SW_COMPLEX*/
}
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,290 @@
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords)
{
lv_area_t draw_area;
lv_area_t buffer_area;
lv_area_t coordinates;
bool is_common;
int32_t x;
int32_t y;
d2_u8 current_alpha_mode = 0;
d2_s32 result;
d2_u32 flags = 0;
lv_point_t arc_centre;
is_common = _lv_area_intersect(&draw_area, coords, u->base_unit.clip_area);
if(!is_common) return;
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
buffer_area = u->base_unit.target_layer->buf_area;
coordinates = *coords;
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
lv_area_move(&draw_area, x, y);
lv_area_move(&buffer_area, x, y);
lv_area_move(&coordinates, x, y);
//
// Generate render operations
//
#if D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
#endif
d2_framebuffer(u->d2_handle,
u->base_unit.target_layer->buf,
(d2_s32)u->base_unit.target_layer->buf_stride / lv_color_format_get_size(u->base_unit.target_layer->color_format),
(d2_u32)lv_area_get_width(&buffer_area),
(d2_u32)lv_area_get_height(&buffer_area),
lv_draw_dave2d_cf_fb_get());
if(LV_GRAD_DIR_NONE != dsc->grad.dir) {
float a1;
float a2;
float y1;
float y2;
float y3;
float y0;
int16_t y0_i ;
int16_t y3_i ;
if(LV_GRAD_DIR_VER == dsc->grad.dir) {
a1 = dsc->grad.stops[0].opa;
a2 = dsc->grad.stops[dsc->grad.stops_count - 1].opa;
y1 = (float)LV_MIN(coordinates.y1, coordinates.y2);
y2 = (float)LV_MAX(coordinates.y1, coordinates.y2);
if(a1 < a2) {
/* TODO */
__BKPT(0);
y0 = 0.0f;//silence the compiler warning
y3 = 0.0f;
}
else {
y0 = y2 - ((y2 - y1) / (a2 - a1) * (a2)); //point where alpha is 0
y3 = y1 + ((y2 - y1) / (a2 - a1) * (255 - a1)); //point where alpha is 255
}
y0_i = (int16_t)y0;
y3_i = (int16_t)y3;
d2_setalphagradient(u->d2_handle, 0, (d2_point)D2_FIX4(0), (d2_point)D2_FIX4(y0_i), (d2_point)D2_FIX4(0),
(d2_point)D2_FIX4((y3_i - y0_i)));
}
else if(LV_GRAD_DIR_HOR == dsc->grad.dir) {
/* TODO */
__BKPT(0);
float x1;
float x2;
float x3;
float x0;
int16_t x0_i ;
int16_t x3_i ;
a1 = dsc->grad.stops[0].opa;
a2 = dsc->grad.stops[dsc->grad.stops_count - 1].opa;
x1 = (float)LV_MIN(coordinates.x1, coordinates.x2);
x2 = (float)LV_MAX(coordinates.x1, coordinates.x2);
if(a1 < a2) {
/* TODO */
__BKPT(0);
x0 = 0.0f;//silence the compiler warning
x3 = 0.0f;
}
else {
x0 = x2 - ((x2 - x1) / (a2 - a1) * (a2)); //point where alpha is 0
x3 = x1 + ((x2 - x1) / (a2 - a1) * (255 - a1)); //point where alpha is 255
}
x0_i = (int16_t)x0;
x3_i = (int16_t)x3;
d2_setalphagradient(u->d2_handle, 0, (d2_point)D2_FIX4(x0_i), (d2_point)D2_FIX4(0), (d2_point)D2_FIX4(x3_i - x0_i),
(d2_point)D2_FIX4((0)));
}
current_alpha_mode = d2_getalphamode(u->d2_handle);
d2_setfillmode(u->d2_handle, d2_fm_color);
d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->grad.stops[0].color));
d2_setalphamode(u->d2_handle, d2_am_gradient1);
}
else {
d2_setfillmode(u->d2_handle, d2_fm_color); //default
d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->color));
d2_setalpha(u->d2_handle, dsc->opa);
}
d2_cliprect(u->d2_handle, (d2_border)draw_area.x1, (d2_border)draw_area.y1, (d2_border)draw_area.x2,
(d2_border)draw_area.y2);
if(dsc->radius == 0) {
d2_renderbox(u->d2_handle, (d2_point)D2_FIX4(coordinates.x1),
(d2_point)D2_FIX4(coordinates.y1),
(d2_point)D2_FIX4(lv_area_get_width(&coordinates)),
(d2_point)D2_FIX4(lv_area_get_height(&coordinates)));
}
else {
/*Get the real radius. Can't be larger than the half of the shortest side */
int32_t coords_bg_w = lv_area_get_width(&coordinates);
int32_t coords_bg_h = lv_area_get_height(&coordinates);
int32_t short_side = LV_MIN(coords_bg_w, coords_bg_h);
int32_t radius = LV_MIN(dsc->radius, short_side >> 1);
arc_centre.x = coordinates.x1 + radius;
arc_centre.y = coordinates.y1 + radius;
if(((2 * radius) == coords_bg_w) && ((2 * radius) == coords_bg_h)) {
result = d2_rendercircle(u->d2_handle,
(d2_point)D2_FIX4(arc_centre.x),
(d2_point) D2_FIX4(arc_centre.y),
(d2_width) D2_FIX4(radius),
(d2_width) D2_FIX4(0));
if(D2_OK != result) {
__BKPT(0);
}
}
else {
arc_centre.x = coordinates.x1 + radius;
arc_centre.y = coordinates.y1 + radius;
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(arc_centre.x),
(d2_point) D2_FIX4(arc_centre.y),
(d2_width) D2_FIX4(radius),
(d2_width) D2_FIX4(0),
(d2_s32) D2_FIX16(0), // 180 Degrees
(d2_s32) D2_FIX16((int16_t) -1),
(d2_s32) D2_FIX16((int16_t) -1),//( 270 Degrees
(d2_s32) D2_FIX16(0),
flags);
if(D2_OK != result) {
__BKPT(0);
}
arc_centre.x = coordinates.x2 - radius;
arc_centre.y = coordinates.y1 + radius;
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(arc_centre.x),
(d2_point) D2_FIX4(arc_centre.y),
(d2_width) D2_FIX4(radius),
(d2_width) D2_FIX4(0),
(d2_s32) D2_FIX16((int16_t)1), // 270 Degrees
(d2_s32) D2_FIX16(0),
(d2_s32) D2_FIX16(0),// 0 degrees
(d2_s32) D2_FIX16(-1),
flags);
if(D2_OK != result) {
__BKPT(0);
}
arc_centre.x = coordinates.x2 - radius;
arc_centre.y = coordinates.y2 - radius;
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(arc_centre.x),
(d2_point) D2_FIX4(arc_centre.y),
(d2_width) D2_FIX4(radius),
(d2_width) D2_FIX4(0),
(d2_s32) D2_FIX16(0),// 0 degrees
(d2_s32) D2_FIX16(1),
(d2_s32) D2_FIX16(1),// 90 degrees
(d2_s32) D2_FIX16(0),
flags);
if(D2_OK != result) {
__BKPT(0);
}
arc_centre.x = coordinates.x1 + radius;
arc_centre.y = coordinates.y2 - radius;
result = d2_renderwedge(u->d2_handle,
(d2_point)D2_FIX4(arc_centre.x),
(d2_point) D2_FIX4(arc_centre.y),
(d2_width) D2_FIX4(radius),
(d2_width) D2_FIX4(0),
(d2_s32) D2_FIX16((int16_t) -1), //90 degrees
(d2_s32) D2_FIX16(0),
(d2_s32) D2_FIX16(0), //180 degrees
(d2_s32) D2_FIX16(1),
flags);
if(D2_OK != result) {
__BKPT(0);
}
result = d2_renderbox(u->d2_handle,
(d2_width)D2_FIX4(coordinates.x1 + radius),
(d2_width)D2_FIX4(coordinates.y1),
(d2_width)D2_FIX4(lv_area_get_width(&coordinates) - (2 * radius)),
(d2_width)D2_FIX4(lv_area_get_height(&coordinates)));
if(D2_OK != result) {
__BKPT(0);
}
result = d2_renderbox(u->d2_handle,
(d2_width)D2_FIX4(coordinates.x1),
(d2_width)D2_FIX4(coordinates.y1 + radius),
(d2_width)D2_FIX4(radius),
(d2_width)D2_FIX4(lv_area_get_height(&coordinates) - (2 * radius)));
if(D2_OK != result) {
__BKPT(0);
}
result = d2_renderbox(u->d2_handle,
(d2_width)D2_FIX4(coordinates.x2 - radius),
(d2_width)D2_FIX4(coordinates.y1 + radius),
(d2_width)D2_FIX4(radius),
(d2_width)D2_FIX4(lv_area_get_height(&coordinates) - (2 * radius)));
if(D2_OK != result) {
__BKPT(0);
}
}
}
//
// Execute render operations
//
#if D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
d2_flushframe(u->d2_handle);
#endif
if(LV_GRAD_DIR_NONE != dsc->grad.dir) {
d2_setalphamode(u->d2_handle, current_alpha_mode);
d2_setfillmode(u->d2_handle, d2_fm_color); //default
}
#if LV_USE_OS
status = lv_mutex_unlock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,580 @@
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
#include "../../sw/lv_draw_sw.h"
#include "../../../display/lv_display.h"
#include "../../../display/lv_display_private.h"
#include "../../../misc/lv_log.h"
#include "../../../core/lv_refr.h"
#include "../../../stdlib/lv_mem.h"
#include "../../../misc/lv_cache.h"
#include "../../../misc/lv_math.h"
#include "../../../misc/lv_color.h"
#include "../../../stdlib/lv_string.h"
#include "../../../core/lv_global.h"
/*********************
* DEFINES
*********************/
#define MAX_BUF_SIZE (uint32_t) (4 * lv_display_get_horizontal_resolution(_lv_refr_get_disp_refreshing()) * lv_color_format_get_size(lv_display_get_color_format(_lv_refr_get_disp_refreshing())))
static void dave2d_img_draw_normal(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_area_t * coords);
static void dave2d_img_draw_tiled(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_area_t * coords);
static void dave2d_img_decode_and_draw(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
lv_image_decoder_dsc_t * decoder_dsc,
const lv_area_t * img_area, const lv_area_t * clipped_img_area);
static void dave2d_img_draw_core(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
const lv_area_t * img_coords, const lv_area_t * clipped_img_area);
static void sw_fallback_img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
const lv_area_t * img_coords, const lv_area_t * clipped_img_area);
void lv_draw_dave2d_image(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_area_t * coords)
{
if(!draw_dsc->tile) {
dave2d_img_draw_normal(draw_unit, draw_dsc, coords);
}
else {
dave2d_img_draw_tiled(draw_unit, draw_dsc, coords);
}
}
static void dave2d_img_draw_normal(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_area_t * coords)
{
lv_area_t draw_area;
lv_area_copy(&draw_area, coords);
if(draw_dsc->rotation || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE) {
int32_t w = lv_area_get_width(coords);
int32_t h = lv_area_get_height(coords);
_lv_image_buf_get_transformed_area(&draw_area, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y,
&draw_dsc->pivot);
draw_area.x1 += coords->x1;
draw_area.y1 += coords->y1;
draw_area.x2 += coords->x1;
draw_area.y2 += coords->y1;
}
lv_area_t clipped_img_area;
if(!_lv_area_intersect(&clipped_img_area, &draw_area, draw_unit->base_unit.clip_area)) {
return;
}
lv_image_decoder_dsc_t decoder_dsc;
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, NULL);
if(res != LV_RESULT_OK) {
LV_LOG_ERROR("Failed to open image");
return;
}
dave2d_img_decode_and_draw(draw_unit, draw_dsc, &decoder_dsc, coords, &clipped_img_area);
lv_image_decoder_close(&decoder_dsc);
}
static void dave2d_img_draw_tiled(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_area_t * coords)
{
lv_image_decoder_dsc_t decoder_dsc;
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, NULL);
if(res != LV_RESULT_OK) {
LV_LOG_ERROR("Failed to open image");
return;
}
int32_t img_w = lv_area_get_width(coords);
int32_t img_h = lv_area_get_height(coords);
lv_area_t tile_area = *coords;
int32_t tile_x_start = tile_area.x1;
while(tile_area.y1 < draw_unit->base_unit.clip_area->y2) {
while(tile_area.x1 < draw_unit->base_unit.clip_area->x2) {
lv_area_t clipped_img_area;
if(_lv_area_intersect(&clipped_img_area, &tile_area, draw_unit->base_unit.clip_area)) {
dave2d_img_decode_and_draw(draw_unit, draw_dsc, &decoder_dsc, &tile_area, &clipped_img_area);
}
tile_area.x1 += img_w;
tile_area.x2 += img_w;
}
tile_area.y1 += img_h;
tile_area.y2 += img_h;
tile_area.x1 = tile_x_start;
tile_area.x2 = tile_x_start + img_w - 1;
}
lv_image_decoder_close(&decoder_dsc);
}
static void dave2d_img_decode_and_draw(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
lv_image_decoder_dsc_t * decoder_dsc,
const lv_area_t * img_area, const lv_area_t * clipped_img_area)
{
lv_draw_image_sup_t sup;
sup.alpha_color = draw_dsc->recolor;
sup.palette = decoder_dsc->palette;
sup.palette_size = decoder_dsc->palette_size;
/*The whole image is available, just draw it*/
if(decoder_dsc->img_data) {
dave2d_img_draw_core(draw_unit, draw_dsc, decoder_dsc, &sup, img_area, clipped_img_area);
}
/*Draw in smaller pieces*/
else {
lv_area_t relative_full_area_to_decode = *clipped_img_area;
lv_area_move(&relative_full_area_to_decode, -img_area->x1, -img_area->y1);
lv_area_t relative_decoded_area;
relative_decoded_area.x1 = LV_COORD_MIN;
relative_decoded_area.y1 = LV_COORD_MIN;
relative_decoded_area.x2 = LV_COORD_MIN;
relative_decoded_area.y2 = LV_COORD_MIN;
lv_result_t res = LV_RESULT_OK;
while(res == LV_RESULT_OK) {
res = lv_image_decoder_get_area(decoder_dsc, &relative_full_area_to_decode, &relative_decoded_area);
lv_area_t absolute_decoded_area = relative_decoded_area;
lv_area_move(&absolute_decoded_area, img_area->x1, img_area->y1);
if(res == LV_RESULT_OK) {
/*Limit draw area to the current decoded area and draw the image*/
lv_area_t clipped_img_area_sub;
if(_lv_area_intersect(&clipped_img_area_sub, clipped_img_area, &absolute_decoded_area)) {
dave2d_img_draw_core(draw_unit, draw_dsc, decoder_dsc, &sup,
&absolute_decoded_area, &clipped_img_area_sub);
}
}
}
}
}
static void dave2d_img_draw_core(lv_draw_dave2d_unit_t * u, const lv_draw_image_dsc_t * draw_dsc,
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
const lv_area_t * img_coords, const lv_area_t * clipped_img_area)
{
bool transformed = draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
draw_dsc->scale_y != LV_SCALE_NONE ? true : false;
const uint8_t * src_buf = decoder_dsc->img_data;
const lv_image_header_t * header = &decoder_dsc->header;
lv_area_t buffer_area;
lv_area_t draw_area;
lv_area_t clipped_area;
int32_t x;
int32_t y;
d2_u8 a_texture_op = d2_to_one;
d2_u8 r_texture_op = d2_to_copy;
d2_u8 g_texture_op = d2_to_copy;
d2_u8 b_texture_op = d2_to_copy;
d2_u8 current_fill_mode;
d2_u32 src_blend_mode;
d2_u32 dst_blend_mode;
if(LV_COLOR_FORMAT_RGB565A8 == header->cf) {
/* Colour format not support by Dave2D */
sw_fallback_img_draw_core(&u->base_unit, draw_dsc, decoder_dsc, sup, img_coords, clipped_img_area);
return;
}
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
buffer_area = u->base_unit.target_layer->buf_area;
draw_area = *img_coords;
clipped_area = *clipped_img_area;
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
lv_area_move(&draw_area, x, y);
lv_area_move(&buffer_area, x, y);
lv_area_move(&clipped_area, x, y);
//
// Generate render operations
//
#if D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
#endif
current_fill_mode = d2_getfillmode(u->d2_handle);
a_texture_op = d2_gettextureoperationa(u->d2_handle);
r_texture_op = d2_gettextureoperationr(u->d2_handle);
g_texture_op = d2_gettextureoperationg(u->d2_handle);
b_texture_op = d2_gettextureoperationb(u->d2_handle);
src_blend_mode = d2_getblendmodesrc(u->d2_handle);
dst_blend_mode = d2_getblendmodedst(u->d2_handle);
d2_framebuffer(u->d2_handle,
u->base_unit.target_layer->buf,
(d2_s32)u->base_unit.target_layer->buf_stride / lv_color_format_get_size(u->base_unit.target_layer->color_format),
(d2_u32)lv_area_get_width(&buffer_area),
(d2_u32)lv_area_get_height(&buffer_area),
lv_draw_dave2d_cf_fb_get());
d2_cliprect(u->d2_handle, (d2_border)clipped_area.x1, (d2_border)clipped_area.y1, (d2_border)clipped_area.x2,
(d2_border)clipped_area.y2);
#if defined(RENESAS_CORTEX_M85)
#if (BSP_CFG_DCACHE_ENABLED)
d1_cacheblockflush(u->d2_handle, 0, src_buf,
decoder_dsc->header.stride * decoder_dsc->header.h); //Stride is in bytes, not pixels/texels
#endif
#endif
d2_settexopparam(u->d2_handle, d2_cc_alpha, draw_dsc->opa, 0);
if(LV_COLOR_FORMAT_RGB565 == header->cf) {
d2_settextureoperation(u->d2_handle, d2_to_replace, d2_to_copy, d2_to_copy, d2_to_copy);
}
else { //Formats with an alpha channel,
d2_settextureoperation(u->d2_handle, d2_to_multiply, d2_to_copy, d2_to_copy, d2_to_copy);
}
if(LV_BLEND_MODE_NORMAL == draw_dsc->blend_mode) { /**< Simply mix according to the opacity value*/
d2_setblendmode(u->d2_handle, d2_bm_alpha, d2_bm_one_minus_alpha); //direct linear blend
}
else if(LV_BLEND_MODE_ADDITIVE == draw_dsc->blend_mode) { /**< Add the respective color channels*/
/* TODO */
d2_setblendmode(u->d2_handle, d2_bm_alpha, d2_bm_one); //Additive blending
}
else if(LV_BLEND_MODE_SUBTRACTIVE == draw_dsc->blend_mode) { /**< Subtract the foreground from the background*/
/* TODO */
__NOP();
}
else { //LV_BLEND_MODE_MULTIPLY, /**< Multiply the foreground and background*/
/* TODO */
__NOP();
}
lv_point_t p[4] = { //Points in clockwise order
{0, 0},
{decoder_dsc->header.w - 1, 0},
{decoder_dsc->header.w - 1, decoder_dsc->header.h - 1},
{0, decoder_dsc->header.h - 1},
};
d2_settexture(u->d2_handle, (void *)src_buf,
(d2_s32)(decoder_dsc->header.stride / lv_color_format_get_size(header->cf)),
decoder_dsc->header.w, decoder_dsc->header.h, lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(header->cf));
d2_settexturemode(u->d2_handle, d2_tm_filter);
d2_setfillmode(u->d2_handle, d2_fm_texture);
d2_s32 dxu = D2_FIX16(1);
d2_s32 dxv = D2_FIX16(0);
d2_s32 dyu = D2_FIX16(0);
d2_s32 dyv = D2_FIX16(1);
if(transformed) {
lv_point_transform(&p[0], draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, &draw_dsc->pivot, true);
lv_point_transform(&p[1], draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, &draw_dsc->pivot, true);
lv_point_transform(&p[2], draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, &draw_dsc->pivot, true);
lv_point_transform(&p[3], draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y, &draw_dsc->pivot, true);
int32_t sin_xv = 0; //0 degrees
int32_t cos_xu = (1 << 15);
int32_t sin_yv = (1 << 15); //90 degress
int32_t cos_yu = 0;
int32_t angle_limited = draw_dsc->rotation;
if(angle_limited > 3600) angle_limited -= 3600;
if(angle_limited < 0) angle_limited += 3600;
int32_t angle_low = angle_limited / 10;
if(0 != angle_low) {
sin_xv = lv_trigo_sin((int16_t)angle_low);
cos_xu = lv_trigo_cos((int16_t)angle_low);
sin_yv = lv_trigo_sin((int16_t)angle_low + 90);
cos_yu = lv_trigo_cos((int16_t)angle_low + 90);
}
/* LV_TRIGO_SHIFT is 15, so only need to shift by 1 to get 16:16 fixed point */
dxu = (d2_s32)((1 << 1) *
cos_xu); /* TODO - Need to handle scaling of the texture based on draw_dsc->scale_x, draw_dsc->scale_y, currently no scaling it is 1:1 */
dxv = (d2_s32)((1 << 1) * sin_xv);
dyu = (d2_s32)((1 << 1) * cos_yu);
dyv = (d2_s32)((1 << 1) * sin_yv);
}
p[0].x += draw_area.x1;
p[0].y += draw_area.y1;
p[1].x += draw_area.x1;
p[1].y += draw_area.y1;
p[2].x += draw_area.x1;
p[2].y += draw_area.y1;
p[3].x += draw_area.x1;
p[3].y += draw_area.y1;
d2_settexturemapping(u->d2_handle, D2_FIX4(p[0].x), D2_FIX4(p[0].y), D2_FIX16(0), D2_FIX16(0), dxu, dxv, dyu, dyv);
d2_renderquad(u->d2_handle,
(d2_point)D2_FIX4(p[0].x),
(d2_point)D2_FIX4(p[0].y),
(d2_point)D2_FIX4(p[1].x),
(d2_point)D2_FIX4(p[1].y),
(d2_point)D2_FIX4(p[2].x),
(d2_point)D2_FIX4(p[2].y),
(d2_point)D2_FIX4(p[3].x),
(d2_point)D2_FIX4(p[3].y),
0);
//
// Execute render operations
//
#if D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
d2_flushframe(u->d2_handle);
#endif
d2_setfillmode(u->d2_handle, current_fill_mode);
d2_settextureoperation(u->d2_handle, a_texture_op, r_texture_op, g_texture_op, b_texture_op);
d2_setblendmode(u->d2_handle, src_blend_mode, dst_blend_mode);
#if LV_USE_OS
status = lv_mutex_unlock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
static void sw_fallback_img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
const lv_area_t * img_coords, const lv_area_t * clipped_img_area)
{
bool transformed = draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
draw_dsc->scale_y != LV_SCALE_NONE ? true : false;
lv_draw_sw_blend_dsc_t blend_dsc;
const uint8_t * src_buf = decoder_dsc->img_data;
const lv_image_header_t * header = &decoder_dsc->header;
uint32_t img_stride = header->stride;
lv_color_format_t cf = header->cf;
cf = LV_COLOR_FORMAT_IS_INDEXED(cf) ? LV_COLOR_FORMAT_ARGB8888 : cf,
lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t));
blend_dsc.opa = draw_dsc->opa;
blend_dsc.blend_mode = draw_dsc->blend_mode;
blend_dsc.src_stride = img_stride;
if(!transformed && cf == LV_COLOR_FORMAT_A8) {
lv_area_t clipped_coords;
if(!_lv_area_intersect(&clipped_coords, img_coords, draw_unit->clip_area)) return;
blend_dsc.mask_buf = (lv_opa_t *)src_buf;
blend_dsc.mask_area = img_coords;
blend_dsc.mask_stride = img_stride;
blend_dsc.src_buf = NULL;
blend_dsc.color = draw_dsc->recolor;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
blend_dsc.blend_area = img_coords;
lv_draw_sw_blend(draw_unit, &blend_dsc);
}
else if(!transformed && cf == LV_COLOR_FORMAT_RGB565A8 && draw_dsc->recolor_opa <= LV_OPA_MIN) {
int32_t src_h = lv_area_get_height(img_coords);
int32_t src_w = lv_area_get_width(img_coords);
blend_dsc.src_area = img_coords;
blend_dsc.src_buf = src_buf;
blend_dsc.mask_buf = (lv_opa_t *)src_buf;
blend_dsc.mask_buf += img_stride * src_w / header->w * src_h;
/**
* Note, for RGB565A8, lacking of stride parameter, we always use
* always half of RGB map stride as alpha map stride. The image should
* be generated in this way too.
*/
blend_dsc.mask_stride = img_stride / 2;
blend_dsc.blend_area = img_coords;
blend_dsc.mask_area = img_coords;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565;
lv_draw_sw_blend(draw_unit, &blend_dsc);
}
/*The simplest case just copy the pixels into the draw_buf. Blending will convert the colors if needed*/
else if(!transformed && draw_dsc->recolor_opa <= LV_OPA_MIN) {
blend_dsc.src_area = img_coords;
blend_dsc.src_buf = src_buf;
blend_dsc.blend_area = img_coords;
blend_dsc.src_color_format = cf;
lv_draw_sw_blend(draw_unit, &blend_dsc);
}
/*In the other cases every pixel need to be checked one-by-one*/
else {
lv_area_t blend_area = *clipped_img_area;
blend_dsc.blend_area = &blend_area;
int32_t src_w = lv_area_get_width(img_coords);
int32_t src_h = lv_area_get_height(img_coords);
int32_t blend_w = lv_area_get_width(&blend_area);
int32_t blend_h = lv_area_get_height(&blend_area);
lv_color_format_t cf_final = cf;
if(transformed) {
if(cf == LV_COLOR_FORMAT_RGB888 || cf == LV_COLOR_FORMAT_XRGB8888) cf_final = LV_COLOR_FORMAT_ARGB8888;
else if(cf == LV_COLOR_FORMAT_RGB565) cf_final = LV_COLOR_FORMAT_RGB565A8;
}
uint8_t * tmp_buf;
uint32_t px_size = lv_color_format_get_size(cf_final);
int32_t buf_h;
if(cf_final == LV_COLOR_FORMAT_RGB565A8) {
uint32_t buf_stride = blend_w * 3;
buf_h = MAX_BUF_SIZE / buf_stride;
if(buf_h > blend_h) buf_h = blend_h;
tmp_buf = lv_malloc(buf_stride * buf_h);
}
else {
uint32_t buf_stride = blend_w * lv_color_format_get_size(cf_final);
buf_h = MAX_BUF_SIZE / buf_stride;
if(buf_h > blend_h) buf_h = blend_h;
tmp_buf = lv_malloc(buf_stride * buf_h);
}
blend_dsc.src_buf = tmp_buf;
blend_dsc.src_color_format = cf_final;
int32_t y_last = blend_area.y2;
blend_area.y2 = blend_area.y1 + buf_h - 1;
blend_dsc.src_area = &blend_area;
if(cf_final == LV_COLOR_FORMAT_RGB565A8) {
/*RGB565A8 images will blended as RGB565 + mask
*Therefore the stride can be different. */
blend_dsc.src_stride = blend_w * 2;
blend_dsc.mask_buf = tmp_buf + blend_w * 2 * buf_h;
blend_dsc.mask_stride = blend_w;
blend_dsc.mask_area = &blend_area;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565;
}
else if(cf_final == LV_COLOR_FORMAT_A8) {
blend_dsc.mask_buf = blend_dsc.src_buf;
blend_dsc.mask_stride = blend_w;
blend_dsc.mask_area = &blend_area;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
blend_dsc.color = draw_dsc->recolor;
blend_dsc.src_buf = NULL;
}
else {
blend_dsc.src_stride = blend_w * lv_color_format_get_size(cf_final);
}
while(blend_area.y1 <= y_last) {
/*Apply transformations if any or separate the channels*/
lv_area_t relative_area;
lv_area_copy(&relative_area, &blend_area);
lv_area_move(&relative_area, -img_coords->x1, -img_coords->y1);
if(transformed) {
lv_draw_sw_transform(draw_unit, &relative_area, src_buf, src_w, src_h, img_stride,
draw_dsc, sup, cf, tmp_buf);
}
else if(draw_dsc->recolor_opa >= LV_OPA_MIN) {
int32_t h = lv_area_get_height(&relative_area);
if(cf_final == LV_COLOR_FORMAT_RGB565A8) {
uint32_t stride_px = img_stride / 2;
const uint8_t * rgb_src_buf = src_buf + stride_px * 2 * relative_area.y1 + relative_area.x1 * 2;
const uint8_t * a_src_buf = src_buf + stride_px * 2 * src_h + stride_px * relative_area.y1 +
relative_area.x1;
uint8_t * rgb_dest_buf = tmp_buf;
uint8_t * a_dest_buf = (uint8_t *)blend_dsc.mask_buf;
int32_t i;
for(i = 0; i < h; i++) {
lv_memcpy(rgb_dest_buf, rgb_src_buf, blend_w * 2);
lv_memcpy(a_dest_buf, a_src_buf, blend_w);
rgb_src_buf += stride_px * 2;
a_src_buf += stride_px;
rgb_dest_buf += blend_w * 2;
a_dest_buf += blend_w;
}
}
else if(cf_final != LV_COLOR_FORMAT_A8) {
const uint8_t * src_buf_tmp = src_buf + img_stride * relative_area.y1 + relative_area.x1 * px_size;
uint8_t * dest_buf_tmp = tmp_buf;
int32_t i;
for(i = 0; i < h; i++) {
lv_memcpy(dest_buf_tmp, src_buf_tmp, blend_w * px_size);
dest_buf_tmp += blend_w * px_size;
src_buf_tmp += img_stride;
}
}
}
/*Apply recolor*/
if(draw_dsc->recolor_opa > LV_OPA_MIN) {
lv_color_t color = draw_dsc->recolor;
lv_opa_t mix = draw_dsc->recolor_opa;
lv_opa_t mix_inv = 255 - mix;
if(cf_final == LV_COLOR_FORMAT_RGB565A8 || cf_final == LV_COLOR_FORMAT_RGB565) {
uint16_t c_mult[3];
c_mult[0] = (color.blue >> 3) * mix;
c_mult[1] = (color.green >> 2) * mix;
c_mult[2] = (color.red >> 3) * mix;
uint16_t * buf16 = (uint16_t *)tmp_buf;
int32_t i;
int32_t size = lv_area_get_size(&blend_area);
for(i = 0; i < size; i++) {
buf16[i] = (((c_mult[2] + ((buf16[i] >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) +
(((c_mult[1] + ((buf16[i] >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) +
((c_mult[0] + (buf16[i] & 0x1F) * mix_inv) >> 8);
}
}
else if(cf_final != LV_COLOR_FORMAT_A8) {
uint32_t size = lv_area_get_size(&blend_area);
uint32_t i;
uint16_t c_mult[3];
c_mult[0] = color.blue * mix;
c_mult[1] = color.green * mix;
c_mult[2] = color.red * mix;
uint8_t * tmp_buf_2 = tmp_buf;
for(i = 0; i < size * px_size; i += px_size) {
tmp_buf_2[i + 0] = (c_mult[0] + (tmp_buf_2[i + 0] * mix_inv)) >> 8;
tmp_buf_2[i + 1] = (c_mult[1] + (tmp_buf_2[i + 1] * mix_inv)) >> 8;
tmp_buf_2[i + 2] = (c_mult[2] + (tmp_buf_2[i + 2] * mix_inv)) >> 8;
}
}
}
/*Blend*/
lv_draw_sw_blend(draw_unit, &blend_dsc);
/*Go to the next area*/
blend_area.y1 = blend_area.y2 + 1;
blend_area.y2 = blend_area.y1 + buf_h - 1;
if(blend_area.y2 > y_last) {
blend_area.y2 = y_last;
if(cf_final == LV_COLOR_FORMAT_RGB565A8) {
blend_dsc.mask_buf = tmp_buf + blend_w * 2 * lv_area_get_height(&blend_area);
}
}
}
lv_free(tmp_buf);
}
}
#endif //LV_USE_DRAW_DAVE2D

View File

@ -0,0 +1,166 @@
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area);
static lv_draw_dave2d_unit_t * unit = NULL;
void lv_draw_dave2d_label(lv_draw_dave2d_unit_t * u, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords)
{
if(dsc->opa <= LV_OPA_MIN) return;
unit = u;
lv_draw_label_iterate_letters(&u->base_unit, dsc, coords, lv_draw_dave2d_draw_letter_cb);
}
static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_t * glyph_draw_dsc,
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area)
{
d2_u8 current_fillmode;
lv_area_t clip_area;
lv_area_t buffer_area;
lv_area_t letter_coords;
int32_t x;
int32_t y;
buffer_area = unit->base_unit.target_layer->buf_area;
letter_coords = *glyph_draw_dsc->letter_coords;
bool is_common;
is_common = _lv_area_intersect(&clip_area, glyph_draw_dsc->letter_coords, u->clip_area);
if(!is_common) return;
x = 0 - unit->base_unit.target_layer->buf_area.x1;
y = 0 - unit->base_unit.target_layer->buf_area.y1;
lv_area_move(&clip_area, x, y);
lv_area_move(&buffer_area, x, y);
lv_area_move(&letter_coords, x, y);
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(unit->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
#if D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(unit->d2_handle, unit->renderbuffer);
#endif
//
// Generate render operations
//
d2_framebuffer(unit->d2_handle,
unit->base_unit.target_layer->buf,
(d2_s32)unit->base_unit.target_layer->buf_stride / lv_color_format_get_size(unit->base_unit.target_layer->color_format),
(d2_u32)lv_area_get_width(&buffer_area),
(d2_u32)lv_area_get_height(&buffer_area),
lv_draw_dave2d_cf_fb_get());
current_fillmode = d2_getfillmode(unit->d2_handle);
d2_cliprect(unit->d2_handle, (d2_border)clip_area.x1, (d2_border)clip_area.y1, (d2_border)clip_area.x2,
(d2_border)clip_area.y2);
if(glyph_draw_dsc) {
if(glyph_draw_dsc->bitmap == NULL) {
#if LV_USE_FONT_PLACEHOLDER
/* Draw a placeholder rectangle*/
lv_draw_border_dsc_t border_draw_dsc;
lv_draw_border_dsc_init(&border_draw_dsc);
border_draw_dsc.opa = glyph_draw_dsc->opa;
border_draw_dsc.color = glyph_draw_dsc->color;
border_draw_dsc.width = 1;
//lv_draw_sw_border(u, &border_draw_dsc, glyph_draw_dsc->bg_coords);
lv_draw_dave2d_border(unit, &border_draw_dsc, glyph_draw_dsc->bg_coords);
#endif
}
else if(glyph_draw_dsc->format == LV_DRAW_LETTER_BITMAP_FORMAT_A8) {
lv_area_t mask_area = letter_coords;
mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1;
// lv_draw_sw_blend_dsc_t blend_dsc;
// lv_memzero(&blend_dsc, sizeof(blend_dsc));
// blend_dsc.color = glyph_draw_dsc->color;
// blend_dsc.opa = glyph_draw_dsc->opa;
// blend_dsc.mask_buf = glyph_draw_dsc->bitmap;
// blend_dsc.mask_area = &mask_area;
// blend_dsc.blend_area = glyph_draw_dsc->letter_coords;
// blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
//lv_draw_sw_blend(u, &blend_dsc);
#if defined(RENESAS_CORTEX_M85)
#if (BSP_CFG_DCACHE_ENABLED)
d1_cacheblockflush(unit->d2_handle, 0, glyph_draw_dsc->bitmap, glyph_draw_dsc->_bitmap_buf_size);
#endif
#endif
d2_settexture(unit->d2_handle, (void *)glyph_draw_dsc->bitmap,
(d2_s32)lv_draw_buf_width_to_stride((uint32_t)lv_area_get_width(&letter_coords), LV_COLOR_FORMAT_A8),
lv_area_get_width(&letter_coords), lv_area_get_height(&letter_coords), d2_mode_alpha8);
d2_settexopparam(unit->d2_handle, d2_cc_red, glyph_draw_dsc->color.red, 0);
d2_settexopparam(unit->d2_handle, d2_cc_green, glyph_draw_dsc->color.green, 0);
d2_settexopparam(unit->d2_handle, d2_cc_blue, glyph_draw_dsc->color.blue, 0);
d2_settexopparam(unit->d2_handle, d2_cc_alpha, glyph_draw_dsc->opa, 0);
d2_settextureoperation(unit->d2_handle, d2_to_multiply, d2_to_multiply, d2_to_multiply, d2_to_multiply);
d2_settexturemapping(unit->d2_handle, D2_FIX4(letter_coords.x1), D2_FIX4(letter_coords.y1), D2_FIX16(0), D2_FIX16(0),
D2_FIX16(1), D2_FIX16(0), D2_FIX16(0), D2_FIX16(1));
d2_settexturemode(unit->d2_handle, d2_tm_filter);
d2_setfillmode(unit->d2_handle, d2_fm_texture);
d2_renderbox(unit->d2_handle, (d2_point)D2_FIX4(letter_coords.x1),
(d2_point)D2_FIX4(letter_coords.y1),
(d2_point)D2_FIX4(lv_area_get_width(&letter_coords)),
(d2_point)D2_FIX4(lv_area_get_height(&letter_coords)));
d2_setfillmode(unit->d2_handle, current_fillmode);
}
else if(glyph_draw_dsc->format == LV_DRAW_LETTER_BITMAP_FORMAT_IMAGE) {
#if LV_USE_IMGFONT
lv_draw_image_dsc_t img_dsc;
lv_draw_image_dsc_init(&img_dsc);
img_dsc.rotation = 0;
img_dsc.scale_x = LV_SCALE_NONE;
img_dsc.scale_y = LV_SCALE_NONE;
img_dsc.opa = glyph_draw_dsc->opa;
img_dsc.src = glyph_draw_dsc->bitmap;
//lv_draw_sw_image(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords);
#endif
}
}
//
// Execute render operations
//
#if D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(unit->d2_handle, unit->renderbuffer, 0);
d2_flushframe(unit->d2_handle);
#endif
if(fill_draw_dsc && fill_area) {
//lv_draw_sw_fill(u, fill_draw_dsc, fill_area);
lv_draw_dave2d_fill(unit, fill_draw_dsc, fill_area);
}
#if LV_USE_OS
status = lv_mutex_unlock(unit->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,107 @@
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * dsc)
{
lv_area_t clip_line;
d2_u32 mode;
d2_s32 result;
lv_area_t buffer_area;
uint32_t res;
lv_value_precise_t p1_x;
lv_value_precise_t p1_y;
lv_value_precise_t p2_x;
lv_value_precise_t p2_y;
int32_t x;
int32_t y;
clip_line.x1 = LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width / 2;
clip_line.x2 = LV_MAX(dsc->p1.x, dsc->p2.x) + dsc->width / 2;
clip_line.y1 = LV_MIN(dsc->p1.y, dsc->p2.y) - dsc->width / 2;
clip_line.y2 = LV_MAX(dsc->p1.y, dsc->p2.y) + dsc->width / 2;
bool is_common;
is_common = _lv_area_intersect(&clip_line, &clip_line, u->base_unit.clip_area);
if(!is_common) return;
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
buffer_area = u->base_unit.target_layer->buf_area;
p1_x = dsc->p1.x - buffer_area.x1;
p1_y = dsc->p1.y - buffer_area.y1;
p2_x = dsc->p2.x - buffer_area.x1;
p2_y = dsc->p2.y - buffer_area.y1;
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
lv_area_move(&clip_line, x, y);
lv_area_move(&buffer_area, x, y);
bool dashed = dsc->dash_gap && dsc->dash_width;
if(dashed) {
/* TODO */
__BKPT(0);
}
#if D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
#endif
//
// Generate render operations
//
d2_framebuffer(u->d2_handle,
u->base_unit.target_layer->buf,
(d2_s32)u->base_unit.target_layer->buf_stride / lv_color_format_get_size(u->base_unit.target_layer->color_format),
(d2_u32)lv_area_get_width(&buffer_area),
(d2_u32)lv_area_get_height(&buffer_area),
lv_draw_dave2d_cf_fb_get());
d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->color));
d2_setalpha(u->d2_handle, dsc->opa);
d2_cliprect(u->d2_handle, clip_line.x1, clip_line.y1, clip_line.x2, clip_line.y2);
if((dsc->round_end == 1) || (dsc->round_start == 1)) {
mode = d2_lc_round;
}
else {
mode = d2_lc_butt; // lines end directly at endpoints
}
d2_setlinecap(u->d2_handle, mode);
d2_renderline(u->d2_handle, D2_FIX4(p1_x), D2_FIX4(p1_y), D2_FIX4(p2_x),
D2_FIX4(p2_y), D2_FIX4(dsc->width), d2_le_exclude_none);
//
// Execute render operations
//
#if D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
d2_flushframe(u->d2_handle);
#endif
#if LV_USE_OS
status = lv_mutex_unlock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,69 @@
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * u, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords)
{
lv_area_t clipped_area;
lv_area_t buffer_area;
lv_area_t coordinates;
int32_t x;
int32_t y;
if(!_lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return;
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
buffer_area = u->base_unit.target_layer->buf_area;
coordinates = *coords;
lv_area_move(&clipped_area, x, y);
lv_area_move(&buffer_area, x, y);
lv_area_move(&coordinates, x, y);
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
#ifdef D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
#endif
d2_framebuffer(u->d2_handle,
u->base_unit.target_layer->buf,
lv_area_get_width(&u->base_unit.target_layer->buf_area),
(d2_u32)lv_area_get_width(&u->base_unit.target_layer->buf_area),
(d2_u32)lv_area_get_height(&u->base_unit.target_layer->buf_area),
lv_draw_dave2d_cf_fb_get());
d2_cliprect(u->d2_handle, (d2_border)clipped_area.x1, (d2_border)clipped_area.y1, (d2_border)clipped_area.x2,
(d2_border)clipped_area.y2);
d2_renderbox(u->d2_handle,
(d2_point) D2_FIX4(coordinates.x1),
(d2_point) D2_FIX4(coordinates.y1),
(d2_width) D2_FIX4(lv_area_get_width(&coordinates)),
(d2_width) D2_FIX4(lv_area_get_height(&coordinates)));
//
// Execute render operations
//
#ifdef D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
d2_flushframe(u->d2_handle);
#endif
#if LV_USE_OS
status = lv_mutex_unlock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
#endif //LV_USE_DRAW_DAVE2D

View File

@ -0,0 +1,192 @@
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_dsc_t * dsc)
{
lv_area_t clipped_area;
d2_u32 flags = 0;
d2_u8 current_alpha_mode = 0;
lv_area_t buffer_area;
int32_t x;
int32_t y;
lv_area_t tri_area;
tri_area.x1 = LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
tri_area.y1 = LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
tri_area.x2 = LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
tri_area.y2 = LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
if(!_lv_area_intersect(&clipped_area, &tri_area, u->base_unit.clip_area)) return;
#if LV_USE_OS
lv_result_t status;
status = lv_mutex_lock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
x = 0 - u->base_unit.target_layer->buf_area.x1;
y = 0 - u->base_unit.target_layer->buf_area.y1;
buffer_area = u->base_unit.target_layer->buf_area;
lv_area_move(&clipped_area, x, y);
lv_area_move(&buffer_area, x, y);
#if D2_RENDER_EACH_OPERATION
d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
#endif
lv_point_precise_t p[3];
p[0] = dsc->p[0];
p[1] = dsc->p[1];
p[2] = dsc->p[2];
/*Order the points like this:
* [0]: top
* [1]: right bottom
* [2]: left bottom */
if(dsc->p[0].y <= dsc->p[1].y && dsc->p[0].y <= dsc->p[2].y) {
p[0] = dsc->p[0];
if(dsc->p[1].x < dsc->p[2].x) {
p[2] = dsc->p[1];
p[1] = dsc->p[2];
}
else {
p[2] = dsc->p[2];
p[1] = dsc->p[1];
}
}
else if(dsc->p[1].y <= dsc->p[0].y && dsc->p[1].y <= dsc->p[2].y) {
p[0] = dsc->p[1];
if(dsc->p[0].x < dsc->p[2].x) {
p[2] = dsc->p[0];
p[1] = dsc->p[2];
}
else {
p[2] = dsc->p[2];
p[1] = dsc->p[0];
}
}
else {
p[0] = dsc->p[2];
if(dsc->p[0].x < dsc->p[1].x) {
p[2] = dsc->p[0];
p[1] = dsc->p[1];
}
else {
p[2] = dsc->p[1];
p[1] = dsc->p[0];
}
}
p[0].x -= u->base_unit.target_layer->buf_area.x1;
p[1].x -= u->base_unit.target_layer->buf_area.x1;
p[2].x -= u->base_unit.target_layer->buf_area.x1;
p[0].y -= u->base_unit.target_layer->buf_area.y1;
p[1].y -= u->base_unit.target_layer->buf_area.y1;
p[2].y -= u->base_unit.target_layer->buf_area.y1;
current_alpha_mode = d2_getalphamode(u->d2_handle);
if(LV_GRAD_DIR_NONE != dsc->bg_grad.dir) {
float a1;
float a2;
float y1;
float y2;
float y3;
float y0;
int32_t y0_i ;
int32_t y3_i ;
if(LV_GRAD_DIR_VER == dsc->bg_grad.dir) {
a1 = dsc->bg_grad.stops[0].opa;
a2 = dsc->bg_grad.stops[dsc->bg_grad.stops_count - 1].opa;
y1 = LV_MIN3(p[0].y, p[1].y, p[2].y);
y2 = LV_MAX3(p[0].y, p[1].y, p[2].y);
if(a1 < a2) {
/* TODO */
__BKPT(0);
y0 = 0.0f;//silence the compiler warning
y3 = 0.0f;
}
else {
y0 = y2 - ((y2 - y1) / (a2 - a1) * (a2)); //point where alpha is 0
y3 = y1 + ((y2 - y1) / (a2 - a1) * (255 - a1)); //point where alpha is 255
}
y0_i = (int16_t)y0;
y3_i = (int16_t)y3;
d2_setalphagradient(u->d2_handle, 0, D2_FIX4(0), D2_FIX4(y0_i), D2_FIX4(0), D2_FIX4((y3_i - y0_i)));
}
else if(LV_GRAD_DIR_HOR == dsc->bg_grad.dir) {
/* TODO */
__BKPT(0);
}
d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->bg_grad.stops[0].color));
d2_setalphamode(u->d2_handle, d2_am_gradient1);
}
else {
d2_setalpha(u->d2_handle, dsc->bg_opa);
d2_setalphamode(u->d2_handle, d2_am_constant);
d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->bg_color));
}
d2_framebuffer(u->d2_handle,
u->base_unit.target_layer->buf,
(d2_s32)u->base_unit.target_layer->buf_stride / lv_color_format_get_size(u->base_unit.target_layer->color_format),
(d2_u32)lv_area_get_width(&buffer_area),
(d2_u32)lv_area_get_height(&buffer_area),
lv_draw_dave2d_cf_fb_get());
d2_cliprect(u->d2_handle, (d2_border)clipped_area.x1, (d2_border)clipped_area.y1, (d2_border)clipped_area.x2,
(d2_border)clipped_area.y2);
d2_rendertri(u->d2_handle,
(d2_point) D2_FIX4(p[0].x),
(d2_point) D2_FIX4(p[0].y),
(d2_point) D2_FIX4(p[1].x),
(d2_point) D2_FIX4(p[1].y),
(d2_point) D2_FIX4(p[2].x),
(d2_point) D2_FIX4(p[2].y),
flags);
//
// Execute render operations
//
#if D2_RENDER_EACH_OPERATION
d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
d2_flushframe(u->d2_handle);
#endif
d2_setalphamode(u->d2_handle, current_alpha_mode);
#if LV_USE_OS
status = lv_mutex_unlock(u->pd2Mutex);
if(LV_RESULT_OK != status) {
__BKPT(0);
}
#endif
}
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,121 @@
/**
* @file lv_draw_dave2d_utils.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_draw_dave2d.h"
#if LV_USE_DRAW_DAVE2D
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
d2_color lv_draw_dave2d_lv_colour_to_d2_colour(lv_color_t color)
{
uint8_t alpha, red, green, blue;
alpha = 0x00;
red = color.red ;
green = color.green ;
blue = color.blue;
/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
switch(LV_COLOR_DEPTH) {
case(8):
__BKPT(0);
break;
case(16):
break;
case(24):
break;
case(32):
break;
default:
break;
}
return (alpha) << 24UL
| (red) << 16UL
| (green) << 8UL
| (blue) << 0UL;
}
d2_s32 lv_draw_dave2d_cf_fb_get(void)
{
d2_s32 d2_fb_mode = 0;
switch(g_display0_cfg.input->format) {
case DISPLAY_IN_FORMAT_16BITS_RGB565: ///< RGB565, 16 bits
d2_fb_mode = d2_mode_rgb565;
break;
case DISPLAY_IN_FORMAT_32BITS_ARGB8888: ///< ARGB8888, 32 bits
case DISPLAY_IN_FORMAT_32BITS_RGB888: ///< RGB888, 32 bits
case DISPLAY_IN_FORMAT_16BITS_ARGB1555: ///< ARGB1555, 16 bits
case DISPLAY_IN_FORMAT_16BITS_ARGB4444: ///< ARGB4444, 16 bits
case DISPLAY_IN_FORMAT_CLUT8 : ///< CLUT8
case DISPLAY_IN_FORMAT_CLUT4 : ///< CLUT4
case DISPLAY_IN_FORMAT_CLUT1 : ///< CLUT1
break;
default:
break;
}
return d2_fb_mode;
}
d2_u32 lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(lv_color_format_t colour_format)
{
d2_u32 d2_lvgl_mode = 0;
switch(colour_format) {
case(8):
d2_lvgl_mode = d2_mode_alpha8; //?
break;
case(LV_COLOR_FORMAT_RGB565):
d2_lvgl_mode = d2_mode_rgb565;
break;
case(LV_COLOR_FORMAT_RGB888):
d2_lvgl_mode = d2_mode_argb8888; //?
break;
case(LV_COLOR_FORMAT_ARGB8888):
d2_lvgl_mode = d2_mode_argb8888;
break;
default:
__BKPT(0);
break;
}
return d2_lvgl_mode;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /*LV_USE_DRAW_DAVE2D*/

View File

@ -0,0 +1,43 @@
/**
* @file lv_draw_dave2d_utils.h
*
*/
#ifndef LV_DRAW_DAVE2D_UTILS_H
#define LV_DRAW_DAVE2D_UTILS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
d2_color lv_draw_dave2d_lv_colour_to_d2_colour(lv_color_t color);
d2_s32 lv_draw_dave2d_cf_fb_get(void);
d2_u32 lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(lv_color_format_t colour_format);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_DRAW_DAVE2D_UTILS_H*/

View File

@ -332,6 +332,15 @@
#endif
#endif
/* Use Renesas Dave2D on RA platforms. */
#ifndef LV_USE_DRAW_DAVE2D
#ifdef CONFIG_LV_USE_DRAW_DAVE2D
#define LV_USE_DRAW_DAVE2D CONFIG_LV_USE_DRAW_DAVE2D
#else
#define LV_USE_DRAW_DAVE2D 0
#endif
#endif
/* Draw using cached SDL textures*/
#ifndef LV_USE_DRAW_SDL
#ifdef CONFIG_LV_USE_DRAW_SDL

View File

@ -32,6 +32,9 @@
#if LV_USE_DRAW_PXP
#include "draw/nxp/pxp/lv_draw_pxp.h"
#endif
#if LV_USE_DRAW_DAVE2D
#include "draw/renesas/dave2d/lv_draw_dave2d.h"
#endif
#if LV_USE_DRAW_SDL
#include "draw/sdl/lv_draw_sdl.h"
#endif
@ -169,10 +172,15 @@ void lv_init(void)
lv_draw_pxp_init();
#endif
#if LV_USE_DRAW_DAVE2D
lv_draw_dave2d_init();
#endif
#if LV_USE_DRAW_SDL
lv_draw_sdl_init();
#endif
_lv_obj_style_init();
/*Initialize the screen refresh system*/