Open FandelXiong opened 4 years ago
1,通过 pixel.h 看到,这两个函数应该是有和 alpha 通道做相乘的,而其中 pixel_bgra8888_blend_rgba_premulti 函数中的 rgba 参数中的 r,g,b 值是在传入函数前做了预乘 alpha 的操作。 ` static inline void pixel_bgra8888_blend_rgba_dark(void pixel, uint8_t a) { uint8_t p = (uint8_t*)pixel;
if (p[3] > 0xf4) { p[0] = (p[0] a) >> 8; p[1] = (p[1] a) >> 8; p[2] = (p[2] a) >> 8; p[3] = 0xff; } else { uint8_t s_a = 0xff - a; uint8_t out_a = tk_pixel_limit_uint8(p[3] + s_a - ((p[3] s_a) >> 8)); if (out_a > 0) { uint8_t d_a = (p[3] (0xff - a)) >> 8; p[0] = (p[0] d_a) / out_a; p[1] = (p[1] d_a) / out_a; p[2] = (p[2] d_a) / out_a; } p[3] = out_a; } }
static inline void pixel_bgra8888_blend_rgba_premulti(void pixel, rgba_t rgba) { uint8_t a = rgba.a; uint8_t p = (uint8_t*)pixel;
if (p[3] > 0xf4) { p[0] = ((p[0] a) >> 8) + rgba.b; p[1] = ((p[1] a) >> 8) + rgba.g; p[2] = ((p[2] a) >> 8) + rgba.r; p[3] = 0xff; } else { uint8_t s_a = 0xff - a; uint8_t out_a = tk_pixel_limit_uint8(p[3] + s_a - ((p[3] s_a) >> 8)); if (out_a > 0) { uint8_t d_a = (p[3] (0xff - rgba.a)) >> 8; p[0] = (p[0] d_a + (rgba.b << 8)) / out_a; p[1] = (p[1] d_a + (rgba.g << 8)) / out_a; p[2] = (p[2] d_a + (rgba.r << 8)) / out_a; } p[3] = out_a; } } ` 2,第二个问题应该是没有定义 WITH_LCD_CLEAR_ALPHA 宏,而你看到的底层的 dialog 窗体只是残影来的,而不是真实存在的,如果需要让窗体半透明或者全透明的话,需要开启 WITH_LCD_CLEAR_ALPHA 宏
嗯,第一个问题确实修复了,我当时看的时候,没有做混合; 第二个我尝试开启后,残影问题解决了,但背景半透明情况下,性能会大幅度降低,1080p分辨率,需要绘制很长时间;
主要是两个问题导致速度变慢: 1,半透明的效果主要是每个像素点都进行混合运行(没有提供硬件加速的前提, WITH_G2D 宏就是开启硬件加速),而且当背景色为半透明的时候,混合运算的公式更加复杂了,所以增加每个像素点融合的运算量,我们可以看到 pixel_bgra8888_blend_rgba_premulti 函数中的 p[3] <= 0xf4 的时候就是背景色为半透明,可以看到算法变复杂了。 2,而且开了窗口半透效果后,每一帧都会在脏矩形区域上面刷新一层透明色来解决残影的问题,这样也会消耗性能,如果不开启脏矩形机制,就会整屏幕刷透明色,这样性能会比较低一点。
感觉脏矩形机制有些问题,我现在背景是半透明,上面有些一些按钮,现在点击按钮,会触发整个界面重绘制,导致性能很低,按照我的理解,应该只重绘变化的这个区域把
因为不会吧,你把你的 xml 或者代码发出来看看?又或者你检查一下啊,你的使用三缓冲机制还是用双缓冲机制的,一般三缓冲机制都是不启用脏矩形机制的。
`
`
这是整个xml,我使用的双buffer,我是在canvas_fill_rect函数这里打的断点,发现绘制区域是1080p
canvas_fill_rect 函数只是给指定的区域填充颜色,但是在实际画到 buffer 上面的时候受到脏矩形的裁剪,所以你最好在 lcd_mem.inc 文件中的 lcd_mem_end_frame 函数中打印 lcd->dirty_rect 出来看看,你说的点击按钮会导致全屏刷新具体是指点击那个按钮?
我刚才在lcd_mem_end_frame上打了断点,胀矩形还是1080p,按钮就是数字键盘上的任意一个
不要断点,一直用printf打印出来看吧,因为脏矩形会一直变的,你的意思是按钮指键盘上面的按钮?
打印出来也是一样的,我的xml有自定义的数字键盘,就是点击上面的按钮;就算不是透明的窗体也是一样的,少数胀矩形是正确的,大多数时候都是1080p
但是我看这个 xml 中也没有什么特别的地方,你用的是 awtk-linux-fb 的是适配层么?
代码可以发出来么?
整个工程的代码吗
又或者你可以试一下只通过 window_open 打开这个 xml,然后就不执行其他的代码,看一下是不是代码引起的
是的,这样胀区域,就是正确的,忘记了,原来的代码按钮按下时,有几个label也会变,但不至于整个屏幕的画面都变化;我把代码给你分析下 AwtkApplication1.tar.gz
我这边编译不了项目,你可以删除一些代码试试看,脏矩形机制是是把所有脏的区域合并在一起的,比如说左上角脏了一个像素点和右下角脏了一个像素点,合并在一起,脏矩形区域就是整个屏幕了
我使用的是双buffer,没有开启脏矩形算法,没有发现这个问题。@FandelXiong 另外,请教个问题@WNsACE, 你说的硬件加速打开宏WITH_G2D,我不清楚我的硬件可不可以硬件加速,那么,我自行定义WITH_G2D宏,会有问题吗?或者说怎么知道我的硬件是不是支持硬件加速?
环境 linux framebuffer brga8888 后端agge