swscale/ops_chain: simplify SwsClearOp checking

Since this now has an explicit mask, we can just check that directly, instead
of relying on the unused comps hack/trick.

Additionally, this also allows us to distinguish between fixed value and
arbitrary value clears by just having the SwsOpEntry contain NAN values iff
they support any clear value.

Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
Niklas Haas
2026-03-31 13:44:08 +02:00
parent 80bd6c0cd5
commit 6a83e15392
4 changed files with 13 additions and 19 deletions

View File

@@ -112,16 +112,6 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry)
}
}
if (op->op == SWS_OP_CLEAR) {
/* Clear pattern must match exactly, regardless of `entry->flexible` */
for (int i = 0; i < 4; i++) {
if (!SWS_OP_NEEDED(op, i))
continue;
if (entry->unused[i] != SWS_COMP_TEST(op->clear.mask, i))
return 0;
}
}
/* Flexible variants always match, but lower the score to prioritize more
* specific implementations if they exist */
if (entry->flexible)
@@ -148,10 +138,15 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry)
}
return score;
case SWS_OP_CLEAR:
/* Clear mask must match exactly */
if (op->clear.mask != entry->clear.mask)
return 0;
for (int i = 0; i < 4; i++) {
if (!SWS_COMP_TEST(op->clear.mask, i) || !SWS_OP_NEEDED(op, i))
continue;
if (av_cmp_q(op->clear.value[i], Q(entry->clear_value)))
else if (!entry->clear.value[i].den)
continue; /* Any clear value supported */
else if (av_cmp_q(op->clear.value[i], entry->clear.value[i]))
return 0;
}
return score;

View File

@@ -128,9 +128,9 @@ typedef struct SwsOpEntry {
SwsPackOp pack;
SwsSwizzleOp swizzle;
SwsConvertOp convert;
SwsClearOp clear;
uint32_t linear_mask; /* subset of SwsLinearOp */
int dither_size; /* subset of SwsDitherOp */
int clear_value; /* clear value for integer clears */
AVRational scale; /* scale factor for SWS_OP_SCALE */
};

View File

@@ -84,8 +84,7 @@ DECL_IMPL(clear, clear##_##X##Y##Z##W, X, Y, Z, W)
DECL_ENTRY(clear##_##X##Y##Z##W, \
.setup = ff_sws_setup_clear, \
.op = SWS_OP_CLEAR, \
.flexible = true, \
.unused = { !X, !Y, !Z, !W }, \
.clear.mask = SWS_COMP_MASK(!X, !Y, !Z, !W), \
);
WRAP_CLEAR(1, 1, 1, 0) /* rgba alpha */

View File

@@ -118,15 +118,15 @@ static int setup_swap_bytes(const SwsImplParams *params, SwsImplResult *out)
#define DECL_CLEAR_ALPHA(EXT, IDX) \
DECL_ASM(U8, clear_alpha##IDX##EXT, \
.op = SWS_OP_CLEAR, \
.clear_value = -1, \
.unused[IDX] = true, \
.clear.mask = SWS_COMP(IDX), \
.clear.value[IDX] = { -1, 1 }, \
); \
#define DECL_CLEAR_ZERO(EXT, IDX) \
DECL_ASM(U8, clear_zero##IDX##EXT, \
.op = SWS_OP_CLEAR, \
.clear_value = 0, \
.unused[IDX] = true, \
.clear.mask = SWS_COMP(IDX), \
.clear.value[IDX] = { 0, 1 }, \
);
static int setup_clear(const SwsImplParams *params, SwsImplResult *out)
@@ -141,7 +141,7 @@ static int setup_clear(const SwsImplParams *params, SwsImplResult *out)
DECL_PATTERN(U8, clear##EXT, X, Y, Z, W, \
.op = SWS_OP_CLEAR, \
.setup = setup_clear, \
.flexible = true, \
.clear.mask = SWS_COMP_MASK(!X, !Y, !Z, !W), \
);
#define DECL_SWIZZLE(EXT, X, Y, Z, W) \