From 59cb7994c676a79c70c3b37c93b424d58b591769 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 13 May 2024 12:39:29 +0200 Subject: [PATCH] LibWeb: Use memcpy() in CanvasRenderingContext2D.getImageData() Instead of copying the image data pixel-by-pixel, we can memcpy full scanlines at a time. This knocks a 4% item down to <1% in profiles of Another World JS. --- .../Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index 340b661fb76..e40d26d77d3 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -407,10 +407,9 @@ WebIDL::ExceptionOr> CanvasRenderingContext2D::get_image_da // 6. Set the pixel values of imageData to be the pixels of this's output bitmap in the area specified by the source rectangle in the bitmap's coordinate space units, converted from this's color space to imageData's colorSpace using 'relative-colorimetric' rendering intent. // FIXME: Can't use a Gfx::Painter + blit() here as it doesn't support ImageData bitmap's RGBA8888 format. for (int target_y = 0; target_y < source_rect_intersected.height(); ++target_y) { - for (int target_x = 0; target_x < source_rect_intersected.width(); ++target_x) { - auto pixel = bitmap.get_pixel(target_x + x, target_y + y); - image_data->bitmap().set_pixel(target_x, target_y, pixel); - } + auto* dst = image_data->bitmap().scanline(target_y); + auto const* src = bitmap.scanline(target_y + y) + x; + memcpy(dst, src, source_rect_intersected.width() * sizeof(Gfx::ARGB32)); } // 7. Set the pixels values of imageData for areas of the source rectangle that are outside of the output bitmap to transparent black.