refactor surface, make it easy to add a custom surface

This commit is contained in:
idea4good 2020-03-14 10:58:01 +08:00
parent acf025bf3a
commit 865365f2c5
2 changed files with 98 additions and 99 deletions

View File

@ -389,8 +389,9 @@ class c_surface;
class c_display { class c_display {
friend class c_surface; friend class c_surface;
public: public:
inline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op = 0); inline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op = 0);//multiple surface or surface_no_fb
inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder); inline c_display(void* phy_fb, int display_width, int display_height, c_surface* surface);//single custom surface
inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder);//for multiple surfaces
inline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset); inline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset);
int get_width() { return m_width; } int get_width() { return m_width; }
int get_height() { return m_height; } int get_height() { return m_height; }
@ -441,10 +442,10 @@ private:
int m_width; //in pixels int m_width; //in pixels
int m_height; //in pixels int m_height; //in pixels
int m_color_bytes; //16 bits, 32 bits only int m_color_bytes; //16 bits, 32 bits only
void* m_phy_fb; void* m_phy_fb;
int m_phy_read_index; int m_phy_read_index;
int m_phy_write_index; int m_phy_write_index;
c_surface* m_surface_group[SURFACE_CNT_MAX]; c_surface* m_surface_group[SURFACE_CNT_MAX];
int m_surface_cnt; int m_surface_cnt;
int m_surface_index; int m_surface_index;
}; };
@ -459,29 +460,11 @@ public:
class c_surface { class c_surface {
friend class c_display; friend class c_bitmap; friend class c_display; friend class c_bitmap;
public: public:
c_surface(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_max_zorder(Z_ORDER_LEVEL_0), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0) c_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0)
{ {
if (display) set_surface(max_zorder);
{
m_display = display;
m_phy_fb = display->m_phy_fb;
m_phy_write_index = &display->m_phy_write_index;
}
m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height); m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height);
} }
void set_surface(Z_ORDER_LEVEL max_z_order)
{
m_max_zorder = max_z_order;
if (m_display->m_surface_cnt > 1)
{
m_fb = calloc(m_width * m_height, m_color_bytes);
}
for (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++)
{//Top layber fb always be 0
m_frame_layers[i].fb = (unsigned short*)calloc(m_width * m_height, sizeof(unsigned short));
ASSERT(0 != m_frame_layers[i].fb);
}
}
int get_width() { return m_width; } int get_width() { return m_width; }
int get_height() { return m_height; } int get_height() { return m_height; }
unsigned int get_pixel(int x, int y, unsigned int z_order) unsigned int get_pixel(int x, int y, unsigned int z_order)
@ -843,9 +826,7 @@ protected:
{ {
(m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb); (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb);
} }
int display_width = m_display->get_width(); if (m_is_active && (x < m_display->get_width()) && (y < m_display->get_height()))
int display_height = m_display->get_height();
if (m_is_active && (x < display_width) && (y < display_height))
{ {
if (m_color_bytes == 4) if (m_color_bytes == 4)
{ {
@ -858,23 +839,44 @@ protected:
*m_phy_write_index = *m_phy_write_index + 1; *m_phy_write_index = *m_phy_write_index + 1;
} }
} }
void attach_display(c_display* display)
{
ASSERT(display);
m_display = display;
m_phy_fb = display->m_phy_fb;
m_phy_write_index = &display->m_phy_write_index;
}
void set_surface(Z_ORDER_LEVEL max_z_order)
{
m_max_zorder = max_z_order;
if (m_display && (m_display->m_surface_cnt > 1))
{
m_fb = calloc(m_width * m_height, m_color_bytes);
}
for (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++)
{//Top layber fb always be 0
ASSERT(!m_frame_layers[i].fb);
m_frame_layers[i].fb = (unsigned short*)calloc(m_width * m_height, sizeof(unsigned short));
ASSERT(m_frame_layers[i].fb);
}
}
int m_width; //in pixels int m_width; //in pixels
int m_height; //in pixels int m_height; //in pixels
int m_color_bytes; //16 bits, 32 bits only int m_color_bytes; //16 bits, 32 bits only
void* m_fb; //frame buffer you could see void* m_fb; //frame buffer you could see
c_frame_layer m_frame_layers[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0 c_frame_layer m_frame_layers[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0
bool m_is_active; bool m_is_active;
Z_ORDER_LEVEL m_max_zorder; Z_ORDER_LEVEL m_max_zorder;
Z_ORDER_LEVEL m_top_zorder; Z_ORDER_LEVEL m_top_zorder;
void* m_phy_fb; void* m_phy_fb;
int* m_phy_write_index; int* m_phy_write_index;
c_display* m_display; c_display* m_display;
}; };
class c_surface_no_fb : public c_surface {//No physical framebuffer class c_surface_no_fb : public c_surface {//No physical framebuffer
friend class c_display; friend class c_display;
public:
c_surface_no_fb(unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0) : c_surface(width, height, color_bytes, max_zorder), m_gfx_op(gfx_op) {}
protected: protected:
c_surface_no_fb(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) :
c_surface(display, width, height, color_bytes), m_gfx_op(gfx_op) {}
virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb)
{ {
if (!m_gfx_op) if (!m_gfx_op)
@ -942,11 +944,7 @@ protected:
}; };
inline c_display::c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op) : m_width(display_width), m_height(display_height), m_color_bytes(color_bytes), m_phy_fb(phy_fb), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(surface_cnt), m_surface_index(0) inline c_display::c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op) : m_width(display_width), m_height(display_height), m_color_bytes(color_bytes), m_phy_fb(phy_fb), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(surface_cnt), m_surface_index(0)
{ {
if (color_bytes != 2 && color_bytes != 4) ASSERT(color_bytes == 2 || color_bytes == 4);
{
log_out("Support 16 bits, 32 bits color only!");
ASSERT(false);
}
ASSERT(m_surface_cnt <= SURFACE_CNT_MAX); ASSERT(m_surface_cnt <= SURFACE_CNT_MAX);
memset(m_surface_group, 0, sizeof(m_surface_group)); memset(m_surface_group, 0, sizeof(m_surface_group));
@ -954,7 +952,7 @@ inline c_display::c_display(void* phy_fb, int display_width, int display_height,
{// Avoid new operation, new operation maybe crash program on Keil platform sometimes. {// Avoid new operation, new operation maybe crash program on Keil platform sometimes.
if (phy_fb) if (phy_fb)
{ {
c_surface tmp(this, surface_width, surface_height, color_bytes); c_surface tmp(surface_width, surface_height, color_bytes);
c_surface* surface = (c_surface*)malloc(sizeof(c_surface)); c_surface* surface = (c_surface*)malloc(sizeof(c_surface));
ASSERT(surface); ASSERT(surface);
memcpy(surface, &tmp, sizeof(tmp)); memcpy(surface, &tmp, sizeof(tmp));
@ -962,24 +960,25 @@ inline c_display::c_display(void* phy_fb, int display_width, int display_height,
} }
else else
{ {
c_surface_no_fb tmp(this, surface_width, surface_height, color_bytes, gfx_op); c_surface_no_fb tmp(surface_width, surface_height, color_bytes, gfx_op);
c_surface_no_fb* surface = (c_surface_no_fb*)malloc(sizeof(c_surface_no_fb)); c_surface_no_fb* surface = (c_surface_no_fb*)malloc(sizeof(c_surface_no_fb));
ASSERT(surface); ASSERT(surface);
memcpy(surface, &tmp, sizeof(tmp)); memcpy(surface, &tmp, sizeof(tmp));
m_surface_group[i] = surface; m_surface_group[i] = surface;
} }
m_surface_group[i]->attach_display(this);
} }
} }
inline c_display::c_display(void* phy_fb, int display_width, int display_height, c_surface* surface) : m_width(display_width), m_height(display_height), m_phy_fb(phy_fb), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(1), m_surface_index(0)
{
surface->m_is_active = true;
(m_surface_group[0] = surface)->attach_display(this);
}
inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder) inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder)
{ {
if (max_zorder >= Z_ORDER_LEVEL_MAX || m_surface_index >= m_surface_cnt) ASSERT(max_zorder < Z_ORDER_LEVEL_MAX && m_surface_index < m_surface_cnt);
{ m_surface_group[m_surface_index]->set_surface(max_zorder);
ASSERT(false); return m_surface_group[m_surface_index++];
return 0;
}
int i = m_surface_index++;
m_surface_group[i]->set_surface(max_zorder);
return m_surface_group[i];
} }
inline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset) inline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset)
{ {

View File

@ -28,8 +28,9 @@ class c_surface;
class c_display { class c_display {
friend class c_surface; friend class c_surface;
public: public:
inline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op = 0); inline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op = 0);//multiple surface or surface_no_fb
inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder); inline c_display(void* phy_fb, int display_width, int display_height, c_surface* surface);//single custom surface
inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder);//for multiple surfaces
inline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset); inline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset);
int get_width() { return m_width; } int get_width() { return m_width; }
int get_height() { return m_height; } int get_height() { return m_height; }
@ -88,10 +89,10 @@ private:
int m_width; //in pixels int m_width; //in pixels
int m_height; //in pixels int m_height; //in pixels
int m_color_bytes; //16 bits, 32 bits only int m_color_bytes; //16 bits, 32 bits only
void* m_phy_fb; void* m_phy_fb;
int m_phy_read_index; int m_phy_read_index;
int m_phy_write_index; int m_phy_write_index;
c_surface* m_surface_group[SURFACE_CNT_MAX]; c_surface* m_surface_group[SURFACE_CNT_MAX];
int m_surface_cnt; int m_surface_cnt;
int m_surface_index; int m_surface_index;
}; };
@ -108,33 +109,12 @@ public:
class c_surface { class c_surface {
friend class c_display; friend class c_bitmap; friend class c_display; friend class c_bitmap;
public: public:
c_surface(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_max_zorder(Z_ORDER_LEVEL_0), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0) c_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0)
{ {
if (display) set_surface(max_zorder);
{
m_display = display;
m_phy_fb = display->m_phy_fb;
m_phy_write_index = &display->m_phy_write_index;
}
m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height); m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height);
} }
void set_surface(Z_ORDER_LEVEL max_z_order)
{
m_max_zorder = max_z_order;
if (m_display->m_surface_cnt > 1)
{
m_fb = calloc(m_width * m_height, m_color_bytes);
}
for (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++)
{//Top layber fb always be 0
m_frame_layers[i].fb = (unsigned short*)calloc(m_width * m_height, sizeof(unsigned short));
ASSERT(0 != m_frame_layers[i].fb);
}
}
int get_width() { return m_width; } int get_width() { return m_width; }
int get_height() { return m_height; } int get_height() { return m_height; }
@ -531,9 +511,7 @@ protected:
(m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb); (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb);
} }
int display_width = m_display->get_width(); if (m_is_active && (x < m_display->get_width()) && (y < m_display->get_height()))
int display_height = m_display->get_height();
if (m_is_active && (x < display_width) && (y < display_height))
{ {
if (m_color_bytes == 4) if (m_color_bytes == 4)
{ {
@ -547,24 +525,48 @@ protected:
} }
} }
void attach_display(c_display* display)
{
ASSERT(display);
m_display = display;
m_phy_fb = display->m_phy_fb;
m_phy_write_index = &display->m_phy_write_index;
}
void set_surface(Z_ORDER_LEVEL max_z_order)
{
m_max_zorder = max_z_order;
if (m_display && (m_display->m_surface_cnt > 1))
{
m_fb = calloc(m_width * m_height, m_color_bytes);
}
for (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++)
{//Top layber fb always be 0
ASSERT(!m_frame_layers[i].fb);
m_frame_layers[i].fb = (unsigned short*)calloc(m_width * m_height, sizeof(unsigned short));
ASSERT(m_frame_layers[i].fb);
}
}
int m_width; //in pixels int m_width; //in pixels
int m_height; //in pixels int m_height; //in pixels
int m_color_bytes; //16 bits, 32 bits only int m_color_bytes; //16 bits, 32 bits only
void* m_fb; //frame buffer you could see void* m_fb; //frame buffer you could see
c_frame_layer m_frame_layers[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0 c_frame_layer m_frame_layers[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0
bool m_is_active; bool m_is_active;
Z_ORDER_LEVEL m_max_zorder; Z_ORDER_LEVEL m_max_zorder;
Z_ORDER_LEVEL m_top_zorder; Z_ORDER_LEVEL m_top_zorder;
void* m_phy_fb; void* m_phy_fb;
int* m_phy_write_index; int* m_phy_write_index;
c_display* m_display; c_display* m_display;
}; };
class c_surface_no_fb : public c_surface {//No physical framebuffer class c_surface_no_fb : public c_surface {//No physical framebuffer
friend class c_display; friend class c_display;
public:
c_surface_no_fb(unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0) : c_surface(width, height, color_bytes, max_zorder), m_gfx_op(gfx_op) {}
protected: protected:
c_surface_no_fb(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) :
c_surface(display, width, height, color_bytes), m_gfx_op(gfx_op) {}
virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb)
{ {
if (!m_gfx_op) if (!m_gfx_op)
@ -637,11 +639,7 @@ protected:
inline c_display::c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op) : m_width(display_width), m_height(display_height), m_color_bytes(color_bytes), m_phy_fb(phy_fb), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(surface_cnt), m_surface_index(0) inline c_display::c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op) : m_width(display_width), m_height(display_height), m_color_bytes(color_bytes), m_phy_fb(phy_fb), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(surface_cnt), m_surface_index(0)
{ {
if (color_bytes != 2 && color_bytes != 4) ASSERT(color_bytes == 2 || color_bytes == 4);
{
log_out("Support 16 bits, 32 bits color only!");
ASSERT(false);
}
ASSERT(m_surface_cnt <= SURFACE_CNT_MAX); ASSERT(m_surface_cnt <= SURFACE_CNT_MAX);
memset(m_surface_group, 0, sizeof(m_surface_group)); memset(m_surface_group, 0, sizeof(m_surface_group));
@ -649,7 +647,7 @@ inline c_display::c_display(void* phy_fb, int display_width, int display_height,
{// Avoid new operation, new operation maybe crash program on Keil platform sometimes. {// Avoid new operation, new operation maybe crash program on Keil platform sometimes.
if (phy_fb) if (phy_fb)
{ {
c_surface tmp(this, surface_width, surface_height, color_bytes); c_surface tmp(surface_width, surface_height, color_bytes);
c_surface* surface = (c_surface*)malloc(sizeof(c_surface)); c_surface* surface = (c_surface*)malloc(sizeof(c_surface));
ASSERT(surface); ASSERT(surface);
memcpy(surface, &tmp, sizeof(tmp)); memcpy(surface, &tmp, sizeof(tmp));
@ -657,25 +655,27 @@ inline c_display::c_display(void* phy_fb, int display_width, int display_height,
} }
else else
{ {
c_surface_no_fb tmp(this, surface_width, surface_height, color_bytes, gfx_op); c_surface_no_fb tmp(surface_width, surface_height, color_bytes, gfx_op);
c_surface_no_fb* surface = (c_surface_no_fb*)malloc(sizeof(c_surface_no_fb)); c_surface_no_fb* surface = (c_surface_no_fb*)malloc(sizeof(c_surface_no_fb));
ASSERT(surface); ASSERT(surface);
memcpy(surface, &tmp, sizeof(tmp)); memcpy(surface, &tmp, sizeof(tmp));
m_surface_group[i] = surface; m_surface_group[i] = surface;
} }
m_surface_group[i]->attach_display(this);
} }
} }
inline c_display::c_display(void* phy_fb, int display_width, int display_height, c_surface* surface) : m_width(display_width), m_height(display_height), m_phy_fb(phy_fb), m_phy_read_index(0), m_phy_write_index(0), m_surface_cnt(1), m_surface_index(0)
{
surface->m_is_active = true;
(m_surface_group[0] = surface)->attach_display(this);
}
inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder) inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder)
{ {
if (max_zorder >= Z_ORDER_LEVEL_MAX || m_surface_index >= m_surface_cnt) ASSERT(max_zorder < Z_ORDER_LEVEL_MAX && m_surface_index < m_surface_cnt);
{ m_surface_group[m_surface_index]->set_surface(max_zorder);
ASSERT(false); return m_surface_group[m_surface_index++];
return 0;
}
int i = m_surface_index++;
m_surface_group[i]->set_surface(max_zorder);
return m_surface_group[i];
} }
inline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset) inline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset)