Skip to content

Commit

Permalink
Finalize cairo handling for LVGL, restrict to ARGB32
Browse files Browse the repository at this point in the history
Signed-off-by: falkTX <[email protected]>
  • Loading branch information
falkTX committed May 8, 2024
1 parent 3ff2d1a commit 9660ac6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 42 deletions.
55 changes: 14 additions & 41 deletions generic/LVGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ struct LVGLWidget<BaseWidget>::PrivateData {

#if defined(DGL_CAIRO)
cairo_surface_t* surface = nullptr;
uchar* surfacedata = nullptr;
#elif defined(DGL_OPENGL)
GLuint textureId = 0;
#endif
Expand Down Expand Up @@ -183,7 +182,10 @@ struct LVGLWidget<BaseWidget>::PrivateData {
display = nullptr;
}

#ifdef DGL_OPENGL
#if defined(DGL_CAIRO)
cairo_surface_destroy(surface);
surface = nullptr;
#elif defined(DGL_OPENGL)
if (textureId != 0)
{
glDeleteTextures(1, &textureId);
Expand All @@ -200,15 +202,20 @@ struct LVGLWidget<BaseWidget>::PrivateData {
void recreateTextureData(const uint width, const uint height)
{
const lv_color_format_t lvformat = lv_display_get_color_format(display);
const uint32_t data_size = lv_draw_buf_width_to_stride(width, lvformat) * height;
const uint32_t stride = lv_draw_buf_width_to_stride(width, lvformat);
const uint32_t data_size = stride * height;

textureData = static_cast<uint8_t*>(std::realloc(textureData, data_size));
std::memset(textureData, 0, data_size);

textureSize = Size<uint>(width, height);
lv_display_set_buffers(display, textureData, nullptr, data_size, LV_DISPLAY_RENDER_MODE_DIRECT);

// TODO create full-size cairo texture here
#ifdef DGL_CAIRO
cairo_surface_destroy(surface);
surface = cairo_image_surface_create_for_data(textureData, CAIRO_FORMAT_ARGB32, width, height, stride);
DISTRHO_SAFE_ASSERT(surface != nullptr);
#endif
}

void repaint(const Rectangle<uint>& rect);
Expand Down Expand Up @@ -255,9 +262,6 @@ struct LVGLWidget<BaseWidget>::PrivateData {
_lv_area_join(&evthis->updatedArea, &tmp, area);
}

// TODO convert to cairo texture format here, only touching updated areas
// TODO use double-buffering, touching new area before swapping and notifying flush ready

evthis->repaint(Rectangle<uint>(evthis->updatedArea.x1,
evthis->updatedArea.y1,
evthis->updatedArea.x2 - evthis->updatedArea.x1,
Expand Down Expand Up @@ -343,45 +347,14 @@ void LVGLWidget<BaseWidget>::onDisplay()
#endif

#if defined(DGL_CAIRO)
cairo_t* const handle = static_cast<const CairoGraphicsContext&>(BaseWidget::getGraphicsContext()).handle;

// TODO move this into flush_cb and convert updated pixels directly
if (lvglData->updatedArea.x1 != lvglData->updatedArea.x2 || lvglData->updatedArea.y1 != lvglData->updatedArea.y2)
{
const lv_color_format_t lvformat = lv_display_get_color_format(lvglData->display);
const uint32_t stride = lv_draw_buf_width_to_stride(width, lvformat);

delete[] lvglData->surfacedata;
lvglData->surfacedata = static_cast<uchar*>(std::malloc(static_cast<size_t>(width * height * stride * sizeof(uint32_t))));

#if LV_COLOR_DEPTH == 32
static constexpr const cairo_format_t format = CAIRO_FORMAT_ARGB32;

for (int h = 0; h < height; ++h)
{
for (int w = 0; w < width; ++w)
{
const uchar a = lvglData->textureData[h*width*4+w*4+3];
lvglData->surfacedata[h*width*4+w*4+0] = static_cast<uchar>((lvglData->textureData[h*width*4+w*4+0] * a) >> 8);
lvglData->surfacedata[h*width*4+w*4+1] = static_cast<uchar>((lvglData->textureData[h*width*4+w*4+1] * a) >> 8);
lvglData->surfacedata[h*width*4+w*4+2] = static_cast<uchar>((lvglData->textureData[h*width*4+w*4+2] * a) >> 8);
lvglData->surfacedata[h*width*4+w*4+3] = a;
}
}
#else
#error Unsupported color format
#endif

cairo_surface_destroy(lvglData->surface);
lvglData->surface = cairo_image_surface_create_for_data(lvglData->surfacedata, format, width, height, stride);
DISTRHO_SAFE_ASSERT_RETURN(lvglData->surface != nullptr,);
}

if (lvglData->surface != nullptr)
{
cairo_t* const handle = static_cast<const CairoGraphicsContext&>(BaseWidget::getGraphicsContext()).handle;
cairo_set_source_surface(handle, lvglData->surface, 0, 0);
cairo_paint(handle);
}

lv_area_set(&lvglData->updatedArea, 0, 0, 0, 0);
#elif defined(DGL_OPENGL)
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, lvglData->textureId);
Expand Down
8 changes: 7 additions & 1 deletion generic/LVGL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,16 @@ START_NAMESPACE_DGL
# error LV_ENABLE_GLOBAL_CUSTOM must be set to 1 for DPF builds
#endif

#if LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32
#if defined(DGL_CAIRO) && LV_COLOR_DEPTH != 32
# error LV_COLOR_DEPTH must be 32 for Cairo DPF builds
#elif LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32
# error LV_COLOR_DEPTH must be 24 or 32 for DPF builds
#endif

#if LV_DEF_REFR_PERIOD != 1
# error LV_DEF_REFR_PERIOD must be 1 for DPF builds
#endif

#if LV_DPI_DEF != 160
# error LV_DPI_DEF must be 160 for DPF builds
#endif
Expand Down

0 comments on commit 9660ac6

Please sign in to comment.