Reorganize common code in CompositePixelArgb2Argb functions
Move the common code used by 3 related functions into
CompositePixelArgb2ArgbCommon(), which handles trivial cases that do not
require any color blending. Then CopyInputAndAlpha() only has 1 caller
and can be folded into CompositePixelArgb2ArgbCommon().
This change fixes some performance regressions from adding
CompositePixelArgb2Argb functions.
Change-Id: I0be17dc946ebb498028ca2e4e4322bbfacc96f96
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/123231
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
diff --git a/core/fxge/dib/cfx_scanlinecompositor.cpp b/core/fxge/dib/cfx_scanlinecompositor.cpp
index 02a0c6c..81d08c4 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.cpp
+++ b/core/fxge/dib/cfx_scanlinecompositor.cpp
@@ -27,14 +27,6 @@
return dest + src - dest * src / 255;
}
-template <typename T, typename U>
-void CopyInputAndAlpha(const T& input, uint8_t alpha, U& output) {
- output.blue = input.blue;
- output.green = input.green;
- output.red = input.red;
- output.alpha = alpha;
-}
-
int Lum(FX_RGB_STRUCT<int> color) {
return (color.red * 30 + color.green * 59 + color.blue * 11) / 100;
}
@@ -534,21 +526,30 @@
}
}
+// Returns 0 when no further work is required by the caller. Otherwise, returns
+// `src_alpha` and the caller needs to use that to do more work.
+template <typename DestPixelStruct>
+uint8_t CompositePixelArgb2ArgbCommon(const FX_BGRA_STRUCT<uint8_t>& input,
+ uint8_t clip,
+ DestPixelStruct& output) {
+ const uint8_t src_alpha = input.alpha * clip / 255;
+ if (output.alpha != 0) {
+ return src_alpha;
+ }
+
+ output.blue = input.blue;
+ output.green = input.green;
+ output.red = input.red;
+ output.alpha = src_alpha;
+ return 0;
+}
+
template <typename DestPixelStruct>
void CompositePixelArgb2ArgbNonSeparableBlend(
const FX_BGRA_STRUCT<uint8_t>& input,
- uint8_t clip,
+ uint8_t src_alpha,
DestPixelStruct& output,
BlendMode blend_type) {
- const uint8_t src_alpha = input.alpha * clip / 255;
- if (output.alpha == 0) {
- CopyInputAndAlpha(input, src_alpha, output);
- return;
- }
- if (src_alpha == 0) {
- return;
- }
-
const uint8_t dest_alpha = AlphaUnion(output.alpha, src_alpha);
const int alpha_ratio = src_alpha * 255 / dest_alpha;
FX_RGB_STRUCT<int> blended_color = RgbBlend(blend_type, input, output);
@@ -559,18 +560,9 @@
template <typename DestPixelStruct>
void CompositePixelArgb2ArgbBlend(const FX_BGRA_STRUCT<uint8_t>& input,
- uint8_t clip,
+ uint8_t src_alpha,
DestPixelStruct& output,
BlendMode blend_type) {
- const uint8_t src_alpha = input.alpha * clip / 255;
- if (output.alpha == 0) {
- CopyInputAndAlpha(input, src_alpha, output);
- return;
- }
- if (src_alpha == 0) {
- return;
- }
-
const uint8_t dest_alpha = AlphaUnion(output.alpha, src_alpha);
const int alpha_ratio = src_alpha * 255 / dest_alpha;
FX_RGB_STRUCT<int> blended_color = {
@@ -585,17 +577,8 @@
template <typename DestPixelStruct>
void CompositePixelArgb2ArgbNoBlend(const FX_BGRA_STRUCT<uint8_t>& input,
- uint8_t clip,
+ uint8_t src_alpha,
DestPixelStruct& output) {
- const uint8_t src_alpha = input.alpha * clip / 255;
- if (output.alpha == 0) {
- CopyInputAndAlpha(input, src_alpha, output);
- return;
- }
- if (src_alpha == 0) {
- return;
- }
-
const uint8_t dest_alpha = AlphaUnion(output.alpha, src_alpha);
const int alpha_ratio = src_alpha * 255 / dest_alpha;
AlphaMerge(input, output, alpha_ratio);
@@ -611,19 +594,31 @@
if (clip_span.empty()) {
if (non_separable_blend) {
for (auto [input, output] : fxcrt::Zip(src_span, dest_span)) {
- CompositePixelArgb2ArgbNonSeparableBlend(input, /*clip=*/255, output,
- blend_type);
+ const uint8_t src_alpha =
+ CompositePixelArgb2ArgbCommon(input, /*clip=*/255, output);
+ if (src_alpha != 0) {
+ CompositePixelArgb2ArgbNonSeparableBlend(input, src_alpha, output,
+ blend_type);
+ }
}
return;
}
if (blend_type != BlendMode::kNormal) {
for (auto [input, output] : fxcrt::Zip(src_span, dest_span)) {
- CompositePixelArgb2ArgbBlend(input, /*clip=*/255, output, blend_type);
+ const uint8_t src_alpha =
+ CompositePixelArgb2ArgbCommon(input, /*clip=*/255, output);
+ if (src_alpha != 0) {
+ CompositePixelArgb2ArgbBlend(input, src_alpha, output, blend_type);
+ }
}
return;
}
for (auto [input, output] : fxcrt::Zip(src_span, dest_span)) {
- CompositePixelArgb2ArgbNoBlend(input, /*clip=*/255, output);
+ const uint8_t src_alpha =
+ CompositePixelArgb2ArgbCommon(input, /*clip=*/255, output);
+ if (src_alpha != 0) {
+ CompositePixelArgb2ArgbNoBlend(input, src_alpha, output);
+ }
}
return;
}
@@ -631,20 +626,33 @@
if (non_separable_blend) {
for (auto [input, clip, output] :
fxcrt::Zip(src_span, clip_span, dest_span)) {
- CompositePixelArgb2ArgbNonSeparableBlend(input, clip, output, blend_type);
+ const uint8_t src_alpha =
+ CompositePixelArgb2ArgbCommon(input, clip, output);
+ if (src_alpha != 0) {
+ CompositePixelArgb2ArgbNonSeparableBlend(input, src_alpha, output,
+ blend_type);
+ }
}
return;
}
if (blend_type != BlendMode::kNormal) {
for (auto [input, clip, output] :
fxcrt::Zip(src_span, clip_span, dest_span)) {
- CompositePixelArgb2ArgbBlend(input, clip, output, blend_type);
+ const uint8_t src_alpha =
+ CompositePixelArgb2ArgbCommon(input, clip, output);
+ if (src_alpha != 0) {
+ CompositePixelArgb2ArgbBlend(input, src_alpha, output, blend_type);
+ }
}
return;
}
for (auto [input, clip, output] :
fxcrt::Zip(src_span, clip_span, dest_span)) {
- CompositePixelArgb2ArgbNoBlend(input, clip, output);
+ const uint8_t src_alpha =
+ CompositePixelArgb2ArgbCommon(input, clip, output);
+ if (src_alpha != 0) {
+ CompositePixelArgb2ArgbNoBlend(input, src_alpha, output);
+ }
}
}