From bbc4dbdb666c70bad4ea7b68df1d8a419f596861 Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Sat, 9 Aug 2014 00:01:18 +0200 Subject: [PATCH 1/6] exynos: font: buffer doesn't need special color initialization --- gfx/exynos_gfx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gfx/exynos_gfx.c b/gfx/exynos_gfx.c index ac5a180cc1..3da3d4cfc3 100644 --- a/gfx/exynos_gfx.c +++ b/gfx/exynos_gfx.c @@ -480,7 +480,6 @@ static int exynos_g2d_init(struct exynos_data *pdata) { src->stride = defaults[i].width * defaults[i].bpp; src->color_mode = defaults[i].g2d_color_mode; - src->color = (i == exynos_image_font) ? 0x00 : 0xff000000; /* Associate GEM buffer storage with G2D image. */ src->buf_type = G2D_IMGBUF_GEM; From e8439c30ff362ec2da6f6a15c8c9a7c0a279935a Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Sat, 9 Aug 2014 00:03:59 +0200 Subject: [PATCH 2/6] exynos: font: use defaults properties for buffer bpp --- gfx/exynos_gfx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gfx/exynos_gfx.c b/gfx/exynos_gfx.c index 3da3d4cfc3..c7483d8400 100644 --- a/gfx/exynos_gfx.c +++ b/gfx/exynos_gfx.c @@ -1064,6 +1064,7 @@ static int exynos_init_font(struct exynos_video *vid) { const unsigned buf_height = defaults[exynos_image_font].height; const unsigned buf_width = align_common(pdata->aspect * (float)buf_height, 16); + const unsigned buf_bpp = defaults[exynos_image_font].bpp; if (!g_settings.video.font_enable) return 0; @@ -1084,14 +1085,14 @@ static int exynos_init_font(struct exynos_video *vid) { /* The font buffer color type is ARGB4444. */ if (realloc_buffer(pdata, defaults[exynos_image_font].buf_type, - buf_width * buf_height * 2) != 0) { + buf_width * buf_height * buf_bpp) != 0) { vid->font_driver->free(vid->font); return -1; } src->width = buf_width; src->height = buf_height; - src->stride = buf_width * 2; + src->stride = buf_width * buf_bpp; #if (EXYNOS_GFX_DEBUG_LOG == 1) RARCH_LOG("video_exynos: using font rendering image with size %ux%u\n", From 34e1b6921f2137ed89ab7e2d2ca0303728b71339 Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Sat, 9 Aug 2014 00:19:19 +0200 Subject: [PATCH 3/6] exynos: font: use restrict for src/dst in put_glyph_rgba4444 This should help the compiler to generate better code for memory access. --- gfx/exynos_gfx.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gfx/exynos_gfx.c b/gfx/exynos_gfx.c index c7483d8400..a5c806741a 100644 --- a/gfx/exynos_gfx.c +++ b/gfx/exynos_gfx.c @@ -373,16 +373,15 @@ static int clear_buffer(struct g2d_context *g2d, struct g2d_image *img) { } /* Put a font glyph at a position in the buffer that is backing the G2D font image object. */ -static void put_glyph_rgba4444(struct exynos_data *pdata, const uint8_t *src, uint16_t color, - unsigned g_width, unsigned g_height, unsigned g_pitch, - unsigned dst_x, unsigned dst_y) { +static void put_glyph_rgba4444(struct exynos_data *pdata, const uint8_t *__restrict__ src, + uint16_t color, unsigned g_width, unsigned g_height, + unsigned g_pitch, unsigned dst_x, unsigned dst_y) { const enum exynos_image_type buf_type = defaults[exynos_image_font].buf_type; const unsigned buf_width = pdata->src[exynos_image_font]->width; unsigned x, y; - uint16_t *dst; - - dst = (uint16_t*)pdata->buf[buf_type]->vaddr + dst_y * buf_width + dst_x; + uint16_t *__restrict__ dst = (uint16_t*)pdata->buf[buf_type]->vaddr + + dst_y * buf_width + dst_x; for (y = 0; y < g_height; ++y, src += g_pitch, dst += buf_width) { for (x = 0; x < g_width; ++x) { From 2dcac8cbd4e668376f4b0154c85e90c2994ce137 Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Sat, 9 Aug 2014 01:11:47 +0200 Subject: [PATCH 4/6] exynos: remove G2D safety zone Extensive tests have shown that this is no longer necessary. --- gfx/exynos_gfx.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/gfx/exynos_gfx.c b/gfx/exynos_gfx.c index a5c806741a..785778bd1f 100644 --- a/gfx/exynos_gfx.c +++ b/gfx/exynos_gfx.c @@ -45,11 +45,6 @@ extern void *memcpy_neon(void *dst, const void *src, size_t n); -/* When scaling the G2D seems to need a small 'safety zone' towards the borders of * - * the destination buffer, otherwise leading to execution errors. This needs further * - * investigation, but for now we just stay 4 (= 8 / 2) pixels away from the border. */ -static const unsigned g2d_safety_zone = 8; - /* We use two GEM buffers (main and aux) to handle 'data' from the frontend. */ enum exynos_buffer_type { exynos_buffer_main = 0, @@ -897,9 +892,6 @@ static void exynos_setup_scale(struct exynos_data *pdata, unsigned width, } } - w -= g2d_safety_zone; - h -= g2d_safety_zone; - pdata->blit_params[0] = (pdata->width - w) / 2; pdata->blit_params[1] = (pdata->height - h) / 2; pdata->blit_params[2] = w; @@ -912,13 +904,12 @@ static void exynos_setup_scale(struct exynos_data *pdata, unsigned width, } static void exynos_set_fake_blit(struct exynos_data *pdata) { - const unsigned offset = g2d_safety_zone / 2; unsigned i; - pdata->blit_params[0] = offset; - pdata->blit_params[1] = offset; - pdata->blit_params[2] = pdata->width - offset; - pdata->blit_params[3] = pdata->height - offset; + pdata->blit_params[0] = 0; + pdata->blit_params[1] = 0; + pdata->blit_params[2] = pdata->width; + pdata->blit_params[3] = pdata->height; for (i = 0; i < pdata->num_pages; ++i) pdata->pages[i].clear = true; @@ -992,16 +983,14 @@ static int exynos_blend_menu(struct exynos_data *pdata, static int exynos_blend_font(struct exynos_data *pdata) { struct g2d_image *src = pdata->src[exynos_image_font]; - const unsigned offset = g2d_safety_zone / 2; #if (EXYNOS_GFX_DEBUG_PERF == 1) perf_g2d(&pdata->perf, true); #endif - if (g2d_scale_and_blend(pdata->g2d, src, pdata->dst, 0, 0, - src->width, src->height, offset, - offset, pdata->width - offset, - pdata->height - offset, G2D_OP_INTERPOLATE) || + if (g2d_scale_and_blend(pdata->g2d, src, pdata->dst, 0, 0, src->width, + src->height, 0, 0, pdata->width, pdata->height, + G2D_OP_INTERPOLATE) || g2d_exec(pdata->g2d)) { RARCH_ERR("video_exynos: failed to blend font\n"); return -1; From 55d331c2fe383b3cb495554afc9fac798e567330 Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Sat, 9 Aug 2014 01:16:07 +0200 Subject: [PATCH 5/6] exynos: also use interpolate mode for menu blending --- gfx/exynos_gfx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/exynos_gfx.c b/gfx/exynos_gfx.c index 785778bd1f..3d685b275e 100644 --- a/gfx/exynos_gfx.c +++ b/gfx/exynos_gfx.c @@ -968,7 +968,7 @@ static int exynos_blend_menu(struct exynos_data *pdata, if (g2d_scale_and_blend(pdata->g2d, src, pdata->dst, 0, 0, src->width, src->height, pdata->blit_params[0], pdata->blit_params[1], pdata->blit_params[2], - pdata->blit_params[3], G2D_OP_OVER) || + pdata->blit_params[3], G2D_OP_INTERPOLATE) || g2d_exec(pdata->g2d)) { RARCH_ERR("video_exynos: failed to blend menu\n"); return -1; From a6fd9f6a008735d1fcf96f63d50f0cf135d3a5ba Mon Sep 17 00:00:00 2001 From: Tobias Jakobi Date: Sat, 9 Aug 2014 11:55:16 +0200 Subject: [PATCH 6/6] exynos: update TODO list --- README-exynos.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-exynos.md b/README-exynos.md index eeffe0df12..caf8e7b406 100644 --- a/README-exynos.md +++ b/README-exynos.md @@ -55,6 +55,6 @@ The two fullscreen parameters select the mode the DRM should select. If zero, th The driver still suffers from some issues. - The aspect ratio computation can be improved. In particular the user supplied aspect ratio is currently unused. - - Font rendering and blitting is very inefficient since the backing buffer is cleared every frame. Introduce a invalidation rectangle which covers the region where font glyphs are drawn, and then only clear this region. + - Font rendering and blitting is very inefficient since the backing buffer is cleared every frame. Introduce a invalidation rectangle which covers the region where font glyphs are drawn, and then only clear this region. Also consider converting the buffer to A8 color format and using global color (not sure if this is possible). - Temporary GEM buffers are used as source for blitting operations. Support for the IOMMU has to be enabled, so that one can use the 'userptr' functionality. - More TODOs are pointed out in the code itself.