libpayload: cbgfx: Clear screen by sequential access
Currently clear_screen() calls set_pixel() to set all pixels. However, the actual order of pixels being set depends on the framebuffer orientation. With NORMAL orientation, the framebuffer is accessed sequentially; with LEFT_UP/RIGHT_UP orientation, it is accessed back and forth, leading to performance drop (>1 second on bugzzy). Therefore, ensure sequential access to the framebuffer, regardless of the orientation. BUG=b:194967458 TEST=emerge-cherry libpayload BRANCH=dedede Change-Id: Iecaff5b6abc24ba4b3859cbc44c0d61b2a90b2d9 Signed-off-by: Yu-Ping Wu <yupingso@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/57104 Reviewed-by: Hung-Te Lin <hungte@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
		@@ -274,12 +274,19 @@ static inline uint32_t calculate_color(const struct rgb_color *rgb,
 | 
				
			|||||||
 * Plot a pixel in a framebuffer. This is called from tight loops. Keep it slim
 | 
					 * Plot a pixel in a framebuffer. This is called from tight loops. Keep it slim
 | 
				
			||||||
 * and do the validation at callers' site.
 | 
					 * and do the validation at callers' site.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static inline void set_pixel(struct vector *coord, uint32_t color)
 | 
					static inline void set_pixel_raw(struct vector *rcoord, uint32_t color)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const int bpp = fbinfo->bits_per_pixel;
 | 
						const int bpp = fbinfo->bits_per_pixel;
 | 
				
			||||||
	const int bpl = fbinfo->bytes_per_line;
 | 
						const int bpl = fbinfo->bytes_per_line;
 | 
				
			||||||
	struct vector rcoord;
 | 
					 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
						uint8_t * const pixel = FB + rcoord->y * bpl + rcoord->x * bpp / 8;
 | 
				
			||||||
 | 
						for (i = 0; i < bpp / 8; i++)
 | 
				
			||||||
 | 
							pixel[i] = (color >> (i * 8));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void set_pixel(struct vector *coord, uint32_t color)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct vector rcoord;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (fbinfo->orientation) {
 | 
						switch (fbinfo->orientation) {
 | 
				
			||||||
	case CB_FB_ORIENTATION_NORMAL:
 | 
						case CB_FB_ORIENTATION_NORMAL:
 | 
				
			||||||
@@ -301,9 +308,7 @@ static inline void set_pixel(struct vector *coord, uint32_t color)
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint8_t * const pixel = FB + rcoord.y * bpl + rcoord.x * bpp / 8;
 | 
						set_pixel_raw(&rcoord, color);
 | 
				
			||||||
	for (i = 0; i < bpp / 8; i++)
 | 
					 | 
				
			||||||
		pixel[i] = (color >> (i * 8));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -631,9 +636,9 @@ int clear_screen(const struct rgb_color *rgb)
 | 
				
			|||||||
	    (((color >> 16) & 0xff) == (color & 0xff)))) {
 | 
						    (((color >> 16) & 0xff) == (color & 0xff)))) {
 | 
				
			||||||
		memset(FB, color & 0xff, fbinfo->y_resolution * bpl);
 | 
							memset(FB, color & 0xff, fbinfo->y_resolution * bpl);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		for (p.y = 0; p.y < screen.size.height; p.y++)
 | 
							for (p.y = 0; p.y < fbinfo->y_resolution; p.y++)
 | 
				
			||||||
			for (p.x = 0; p.x < screen.size.width; p.x++)
 | 
								for (p.x = 0; p.x < fbinfo->x_resolution; p.x++)
 | 
				
			||||||
				set_pixel(&p, color);
 | 
									set_pixel_raw(&p, color);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return CBGFX_SUCCESS;
 | 
						return CBGFX_SUCCESS;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user