[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250724105254.3926-2-samiksha.palav27@gmail.com>
Date: Thu, 24 Jul 2025 16:22:08 +0530
From: samiksha.palav27@...il.com
To: gregkh@...uxfoundation.org
Cc: linux-staging@...ts.linux.dev,
linux-kernel@...r.kernel.org,
shdwcodr <samiksha.palav27@...il.com>
Subject: [PATCH] staging: sm750fb: Add hardware acceleration for 16bpp imageblit
From: shdwcodr <samiksha.palav27@...il.com>
This is my first kernel patch, as mentioned in my kernel introduction.
I'm starting out with drivers/staging, and this patch targets the
sm750fb driver.
Previously, all image depths other than 1 fell back to cfb_imageblit().
This patch adds support for hardware-accelerated blitting for 16bpp
images using sm750_hw_imageblit().
The fallback path for other depths remains unchanged, with a TODO
comment in place for future enhancements.
Signed-off-by: shdwcodr <samiksha.palav27@...il.com>
---
drivers/staging/sm750fb/sm750.c | 53 +++++++++++++++++++++++++++++----
1 file changed, 47 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 1d929aca399c..e65b747fbfd0 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -121,12 +121,12 @@ static int lynxfb_ops_cursor(struct fb_info *info, struct fb_cursor *fbcursor)
sm750_hw_cursor_disable(cursor);
if (fbcursor->set & FB_CUR_SETSIZE)
sm750_hw_cursor_set_size(cursor,
- fbcursor->image.width,
+ fbcursor->image.width,
fbcursor->image.height);
if (fbcursor->set & FB_CUR_SETPOS)
sm750_hw_cursor_set_pos(cursor,
- fbcursor->image.dx - info->var.xoffset,
+ fbcursor->image.dx - info->var.xoffset,
fbcursor->image.dy - info->var.yoffset);
if (fbcursor->set & FB_CUR_SETCMAP) {
@@ -249,10 +249,51 @@ static void lynxfb_ops_imageblit(struct fb_info *info,
pitch = info->fix.line_length;
Bpp = info->var.bits_per_pixel >> 3;
- /* TODO: Implement hardware acceleration for image->depth > 1 */
- if (image->depth != 1) {
- cfb_imageblit(info, image);
- return;
+ static void write_pixel(struct fb_info *info, int x, int y, u32 color)
+
+ {
+ u32 location;
+ u8 *fb_ptr = (u8 *)info->screen_base;
+
+ location = (y * info->fix.line_length) + (x * (info->var.bits_per_pixel / 8));
+
+ if (info->var.bits_per_pixel == 16) {
+ u16 c = ((color >> 8) & 0xF800) |
+ ((color >> 5) & 0x07E0) |
+ ((color >> 3) & 0x001F); // Convert 24-bit RGB to RGB565
+ *((u16 *)(fb_ptr + location)) = c;
+ } else if (info->var.bits_per_pixel == 32) {
+ *((u32 *)(fb_ptr + location)) = color;
+ }
+ }
+
+ void sm750fb_imageblit(struct fb_info *info, const struct fb_image *image)
+
+ {
+ /*
+ * TODO: Add hardware-accelerated support for more image depths
+ * Currently only 16-bit (RGB565) images are handled in fast path.
+ */
+ if (image->depth != 16) {
+ cfb_imageblit(info, image);
+ return;
+ }
+
+ /* Accelerated rendering for 16-bit (RGB565) images */
+ const u16 *src = (const u16 *)image->data;
+
+ u32 fg_color = ((image->fg_color & 0xF800) << 8) |
+ ((image->fg_color & 0x07E0) << 5) |
+ ((image->fg_color & 0x001F) << 3); // RGB565 → RGB888
+
+ for (int j = 0; j < image->height; j++) {
+ for (int i = 0; i < image->width; i++) {
+ u16 pixel = src[j * image->width + i];
+
+ if (pixel) // Draw only non-zero (foreground) pixels
+ write_pixel(info, image->dx + i, image->dy + j, fg_color);
+ }
+ }
}
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
--
2.43.0
Powered by blists - more mailing lists