diff options
35 files changed, 3888 insertions, 1733 deletions
diff --git a/X11/extensions/randr.h b/X11/extensions/randr.h index 33d22fb3d..3c6721bc5 100644 --- a/X11/extensions/randr.h +++ b/X11/extensions/randr.h @@ -180,6 +180,7 @@ typedef unsigned long XRandrModeFlags; #define RR_PROPERTY_CLONE_LIST "CloneList" #define RR_PROPERTY_BORDER "Border" #define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions" +#define RR_PROPERTY_GUID "GUID" /* roles this device can carry out */ #define RR_Capability_None 0 diff --git a/X11/extensions/randrproto.txt b/X11/extensions/randrproto.txt index 2bf065f6d..f82407c30 100644 --- a/X11/extensions/randrproto.txt +++ b/X11/extensions/randrproto.txt @@ -1957,6 +1957,17 @@ doesn't handle a mandatory property correctly. 2 = left/right and top/bottom borders can be specified independently 4 = all four borders can be specified independently + "GUID" aka RR_PROPERTY_GUID + Type: INTEGER + Format: 8 + Num items: 16 + Flags: Immutable + Range/List: - + + Some display devices, such as DisplayPort 1.2 devices, have globally + unique identifiers. When such an identifier is available, this property + contains its raw bytes. + 9.2 Properties introduced with version 1.2 of the RandR extension @@ -1990,6 +2001,7 @@ Property Immutable Mandatory since ──────── ───────── ─────────────── Border yes not mandatory BorderDimensions yes: static not mandatory +GUID yes not mandatory ❧❧❧❧❧❧❧❧❧❧❧ diff --git a/libXau/AuFileName.c b/libXau/AuFileName.c index 7cedfcc5b..37c8b6283 100644 --- a/libXau/AuFileName.c +++ b/libXau/AuFileName.c @@ -29,6 +29,7 @@ in this Software without prior written authorization from The Open Group. #endif #include <X11/Xauth.h> #include <X11/Xos.h> +#include <assert.h> #include <stdlib.h> static char *buf = NULL; @@ -69,6 +70,7 @@ XauFileName (void) if ((size > bsize) || (buf == NULL)) { if (buf) free (buf); + assert(size > 0); buf = malloc (size); if (!buf) { bsize = 0; diff --git a/libxcb/src/c_client.py b/libxcb/src/c_client.py index 99fd307b0..45de54413 100644 --- a/libxcb/src/c_client.py +++ b/libxcb/src/c_client.py @@ -1762,7 +1762,7 @@ def c_simple(self, name): # Iterator _c_iterator(self, name) -def _c_complex(self): +def _c_complex(self, force_packed = False): ''' Helper function for handling all structure types. Called for all structs, requests, replies, events, errors. @@ -1817,7 +1817,7 @@ def _c_complex(self): if b.type.has_name: _h(' } %s;', b.c_field_name) - _h('} %s;', self.c_type) + _h('} %s%s;', 'XCB_PACKED ' if force_packed else '', self.c_type) def c_struct(self, name): ''' @@ -2902,6 +2902,7 @@ def c_event(self, name): # events while generating the structure for them. Otherwise we would read # garbage (the internal full_sequence) when accessing normal event fields # there. + force_packed = False if hasattr(self, 'is_ge_event') and self.is_ge_event and self.name == name: event_size = 0 for field in self.fields: @@ -2911,6 +2912,11 @@ def c_event(self, name): full_sequence = Field(tcard32, tcard32.name, 'full_sequence', False, True, True) idx = self.fields.index(field) self.fields.insert(idx + 1, full_sequence) + + # If the event contains any 64-bit extended fields, they need + # to remain aligned on a 64-bit boundary. Adding full_sequence + # would normally break that; force the struct to be packed. + force_packed = any(f.type.size == 8 and f.type.is_simple for f in self.fields[(idx+1):]) break _c_type_setup(self, name, ('event',)) @@ -2920,7 +2926,7 @@ def c_event(self, name): if self.name == name: # Structure definition - _c_complex(self) + _c_complex(self, force_packed) else: # Typedef _h('') diff --git a/libxcb/src/xcb.h b/libxcb/src/xcb.h index e62c985d5..73c77a3a1 100644 --- a/libxcb/src/xcb.h +++ b/libxcb/src/xcb.h @@ -51,6 +51,8 @@ extern "C" { * @file xcb.h */ +#define XCB_PACKED __attribute__((__packed__)) + /** * @defgroup XCB_Core_API XCB Core API * @brief Core API of the XCB library. diff --git a/mesalib/include/GL/glx.h b/mesalib/include/GL/glx.h index 62d0ede9e..234abc050 100644 --- a/mesalib/include/GL/glx.h +++ b/mesalib/include/GL/glx.h @@ -168,6 +168,7 @@ typedef XID GLXDrawable; /* GLX 1.3 and later */ typedef struct __GLXFBConfigRec *GLXFBConfig; typedef XID GLXFBConfigID; +typedef XID GLXContextID; typedef XID GLXWindow; typedef XID GLXPbuffer; diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 3bc181e87..91810f985 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2110,7 +2110,7 @@ validate_explicit_location(const struct ast_type_qualifier *qual, _mesa_glsl_error(loc, state, "%s cannot be given an explicit location in %s shader", mode_string(var), - _mesa_glsl_shader_target_name(state->target)); + _mesa_shader_type_to_string(state->target)); } else { var->data.explicit_location = true; @@ -2188,7 +2188,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, _mesa_glsl_error(loc, state, "`attribute' variables may not be declared in the " "%s shader", - _mesa_glsl_shader_target_name(state->target)); + _mesa_shader_type_to_string(state->target)); } /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says: @@ -2599,7 +2599,7 @@ process_initializer(ir_variable *var, ast_declaration *decl, if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) { _mesa_glsl_error(& initializer_loc, state, "cannot initialize %s shader input / %s", - _mesa_glsl_shader_target_name(state->target), + _mesa_shader_type_to_string(state->target), (state->target == MESA_SHADER_VERTEX) ? "attribute" : "varying"); } @@ -4890,7 +4890,7 @@ ast_interface_block::hir(exec_list *instructions, _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex input not allowed " "in the %s shader", - _mesa_glsl_shader_target_name(state->target)); + _mesa_shader_type_to_string(state->target)); } if (this->instance_name == NULL || strcmp(this->instance_name, "gl_in") != 0 || !this->is_array) { @@ -4907,7 +4907,7 @@ ast_interface_block::hir(exec_list *instructions, _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex output not " "allowed in the %s shader", - _mesa_glsl_shader_target_name(state->target)); + _mesa_shader_type_to_string(state->target)); } if (this->instance_name != NULL) { _mesa_glsl_error(&loc, state, diff --git a/mesalib/src/glsl/builtin_type_macros.h b/mesalib/src/glsl/builtin_type_macros.h index 263fd83ff..06b4dbd0f 100644 --- a/mesalib/src/glsl/builtin_type_macros.h +++ b/mesalib/src/glsl/builtin_type_macros.h @@ -91,7 +91,7 @@ DECL_TYPE(isampler2DMSArray, GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_SAMPLER_D DECL_TYPE(usampler1D, GL_UNSIGNED_INT_SAMPLER_1D, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT) DECL_TYPE(usampler2D, GL_UNSIGNED_INT_SAMPLER_2D, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT) DECL_TYPE(usampler3D, GL_UNSIGNED_INT_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT) -DECL_TYPE(usamplerCube, GL_INT_SAMPLER_CUBE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT) +DECL_TYPE(usamplerCube, GL_UNSIGNED_INT_SAMPLER_CUBE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT) DECL_TYPE(usampler1DArray, GL_UNSIGNED_INT_SAMPLER_1D_ARRAY, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT) DECL_TYPE(usampler2DArray, GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT) DECL_TYPE(usamplerCubeArray, GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT) diff --git a/mesalib/src/glsl/glcpp/glcpp-lex.l b/mesalib/src/glsl/glcpp/glcpp-lex.l index a029f6203..f1fa192c5 100644 --- a/mesalib/src/glsl/glcpp/glcpp-lex.l +++ b/mesalib/src/glsl/glcpp/glcpp-lex.l @@ -67,7 +67,7 @@ void glcpp_set_column (int column_no , yyscan_t yyscanner); %option stack %option never-interactive -%x DONE COMMENT UNREACHABLE SKIP DEFINE +%x DONE COMMENT UNREACHABLE SKIP DEFINE NEWLINE_CATCHUP SPACE [[:space:]] NONSPACE [^[:space:]] @@ -92,13 +92,62 @@ OCTAL_INTEGER 0[0-7]*[uU]? HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? %% - /* Implicitly switch between SKIP and INITIAL (non-skipping); - * don't switch if some other state was explicitly set. - */ + glcpp_parser_t *parser = yyextra; - if (YY_START == 0 || YY_START == SKIP) { - if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) { - BEGIN 0; + + /* When we lex a multi-line comment, we replace it (as + * specified) with a single space. But if the comment spanned + * multiple lines, then subsequent parsing stages will not + * count correct line numbers. To avoid this problem we keep + * track of all newlines that were commented out by a + * multi-line comment, and we emit a NEWLINE token for each at + * the next legal opportunity, (which is when the lexer would + * be emitting a NEWLINE token anyway). + */ + if (YY_START == NEWLINE_CATCHUP) { + if (parser->commented_newlines) + parser->commented_newlines--; + if (parser->commented_newlines == 0) + BEGIN INITIAL; + return NEWLINE; + } + + /* The handling of the SKIP vs INITIAL start states requires + * some special handling. Typically, a lexer would change + * start states with statements like "BEGIN SKIP" within the + * lexer rules. We can't get away with that here, since we + * need the parser to actually evaluate expressions for + * directives like "#if". + * + * So, here, in code that will be executed on every call to + * the lexer,and before any rules, we examine the skip_stack + * as set by the parser to know whether to change from INITIAL + * to SKIP or from SKIP back to INITIAL. + * + * Three cases cause us to switch out of the SKIP state and + * back to the INITIAL state: + * + * 1. The top of the skip_stack is of type SKIP_NO_SKIP + * This means we're still evaluating some #if + * hierarchy, but we're on a branch of it where + * content should not be skipped (such as "#if 1" or + * "#else" or so). + * + * 2. The skip_stack is NULL meaning that we've reached + * the last #endif. + * + * 3. The lexing_if bit is set. This indicates that we + * are lexing the expression following an "#if" of + * "#elif". Even inside an "#if 0" we need to lex this + * expression so the parser can correctly update the + * skip_stack state. + */ + if (YY_START == INITIAL || YY_START == SKIP) { + if (parser->lexing_if || + parser->skip_stack == NULL || + parser->skip_stack->type == SKIP_NO_SKIP) + { + BEGIN INITIAL; } else { BEGIN SKIP; } @@ -106,14 +155,16 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? /* Single-line comments */ "//"[^\n]* { + if (parser->commented_newlines) + BEGIN NEWLINE_CATCHUP; } /* Multi-line comments */ "/*" { yy_push_state(COMMENT, yyscanner); } <COMMENT>[^*\n]* -<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; } +<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; parser->commented_newlines++; } <COMMENT>"*"+[^*/\n]* -<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; } +<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; parser->commented_newlines++; } <COMMENT>"*"+"/" { yy_pop_state(yyscanner); if (yyextra->space_tokens) @@ -129,6 +180,8 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? /* glcpp doesn't handle #extension, #version, or #pragma directives. * Simply pass them through to the main compiler's lexer/parser. */ {HASH}(extension|pragma)[^\n]+ { + if (parser->commented_newlines) + BEGIN NEWLINE_CATCHUP; yylval->str = ralloc_strdup (yyextra, yytext); yylineno++; yycolumn = 0; @@ -175,7 +228,10 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? } } -<SKIP>[^\n] ; +<SKIP>[^\n] { + if (parser->commented_newlines) + BEGIN NEWLINE_CATCHUP; +} {HASH}error.* { char *p; @@ -290,6 +346,9 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? } <SKIP,INITIAL>\n { + if (parser->commented_newlines) { + BEGIN NEWLINE_CATCHUP; + } yyextra->lexing_if = 0; yylineno++; yycolumn = 0; diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index 7edc27488..ef084b639 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -310,6 +310,11 @@ control_line: _glcpp_parser_expand_and_lex_from (parser, ELIF_EXPANDED, $2); } + else if (parser->skip_stack && + parser->skip_stack->has_else) + { + glcpp_error(& @1, parser, "#elif after #else"); + } else { _glcpp_parser_skip_stack_change_if (parser, & @1, @@ -324,6 +329,11 @@ control_line: { glcpp_error(& @1, parser, "#elif with no expression"); } + else if (parser->skip_stack && + parser->skip_stack->has_else) + { + glcpp_error(& @1, parser, "#elif after #else"); + } else { _glcpp_parser_skip_stack_change_if (parser, & @1, @@ -332,7 +342,17 @@ control_line: } } | HASH_ELSE { - _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1); + if (parser->skip_stack && + parser->skip_stack->has_else) + { + glcpp_error(& @1, parser, "multiple #else"); + } + else + { + _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1); + if (parser->skip_stack) + parser->skip_stack->has_else = true; + } } NEWLINE | HASH_ENDIF { _glcpp_parser_skip_stack_pop (parser, & @1); @@ -1164,6 +1184,7 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) parser->newline_as_space = 0; parser->in_control_line = 0; parser->paren_count = 0; + parser->commented_newlines = 0; parser->skip_stack = NULL; @@ -2024,6 +2045,7 @@ _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, node->type = SKIP_TO_ENDIF; } + node->has_else = false; node->next = parser->skip_stack; parser->skip_stack = node; } diff --git a/mesalib/src/glsl/glcpp/glcpp.h b/mesalib/src/glsl/glcpp/glcpp.h index 8aaa551d1..85f3fdcd2 100644 --- a/mesalib/src/glsl/glcpp/glcpp.h +++ b/mesalib/src/glsl/glcpp/glcpp.h @@ -153,6 +153,7 @@ typedef enum skip_type { typedef struct skip_node { skip_type_t type; + bool has_else; YYLTYPE loc; /* location of the initial #if/#elif/... */ struct skip_node *next; } skip_node_t; @@ -172,6 +173,7 @@ struct glcpp_parser { int newline_as_space; int in_control_line; int paren_count; + int commented_newlines; skip_node_t *skip_stack; token_list_t *lex_from_list; token_node_t *lex_from_node; diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 5f19368d8..fc9a8b204 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -334,16 +334,15 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version, extern "C" { /** - * The most common use of _mesa_glsl_shader_target_name(), which is - * shared with C code in Mesa core to translate a GLenum to a short - * shader stage name in debug printouts. + * Translate a GLenum to a short shader stage name for debug printouts and + * error messages. * * It recognizes the PROGRAM variants of the names so it can be used * with a struct gl_program->Target, not just a struct * gl_shader->Type. */ const char * -_mesa_glsl_shader_target_name(GLenum type) +_mesa_shader_enum_to_string(GLenum type) { switch (type) { case GL_VERTEX_SHADER: @@ -363,11 +362,11 @@ _mesa_glsl_shader_target_name(GLenum type) } /* extern "C" */ /** - * Overloaded C++ variant usable within the compiler for translating - * our internal enum into short stage names. + * Translate a gl_shader_type to a short shader stage name for debug printouts + * and error messages. */ const char * -_mesa_glsl_shader_target_name(gl_shader_type target) +_mesa_shader_type_to_string(unsigned target) { switch (target) { case MESA_SHADER_VERTEX: return "vertex"; @@ -651,11 +650,11 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, if (behavior == extension_require) { _mesa_glsl_error(name_locp, state, fmt, - name, _mesa_glsl_shader_target_name(state->target)); + name, _mesa_shader_type_to_string(state->target)); return false; } else { _mesa_glsl_warning(name_locp, state, fmt, - name, _mesa_glsl_shader_target_name(state->target)); + name, _mesa_shader_type_to_string(state->target)); } } } diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 622ddbac7..7b013fa6d 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -422,10 +422,11 @@ extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, _mesa_glsl_parse_state *state); /** - * Get the textual name of the specified shader target + * Get the textual name of the specified shader target (which is a + * gl_shader_type). */ extern const char * -_mesa_glsl_shader_target_name(gl_shader_type target); +_mesa_shader_type_to_string(unsigned target); #endif /* __cplusplus */ @@ -439,7 +440,7 @@ extern "C" { #endif extern const char * -_mesa_glsl_shader_target_name(GLenum type); +_mesa_shader_enum_to_string(GLenum type); extern int glcpp_preprocess(void *ctx, const char **shader, char **info_log, const struct gl_extensions *extensions, struct gl_context *gl_ctx); diff --git a/mesalib/src/glsl/link_atomics.cpp b/mesalib/src/glsl/link_atomics.cpp index 33903ad54..603329c50 100644 --- a/mesalib/src/glsl/link_atomics.cpp +++ b/mesalib/src/glsl/link_atomics.cpp @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include "glsl_parser_extras.h" #include "ir.h" #include "ir_uniform.h" #include "linker.h" @@ -213,20 +214,18 @@ void link_check_atomic_counter_resources(struct gl_context *ctx, struct gl_shader_program *prog) { - STATIC_ASSERT(MESA_SHADER_TYPES == 3); - static const char *shader_names[MESA_SHADER_TYPES] = { - "vertex", "geometry", "fragment" - }; - const unsigned max_atomic_counters[MESA_SHADER_TYPES] = { + const unsigned max_atomic_counters[] = { ctx->Const.VertexProgram.MaxAtomicCounters, ctx->Const.GeometryProgram.MaxAtomicCounters, ctx->Const.FragmentProgram.MaxAtomicCounters }; - const unsigned max_atomic_buffers[MESA_SHADER_TYPES] = { + STATIC_ASSERT(Elements(max_atomic_counters) == MESA_SHADER_TYPES); + const unsigned max_atomic_buffers[] = { ctx->Const.VertexProgram.MaxAtomicBuffers, ctx->Const.GeometryProgram.MaxAtomicBuffers, ctx->Const.FragmentProgram.MaxAtomicBuffers }; + STATIC_ASSERT(Elements(max_atomic_buffers) == MESA_SHADER_TYPES); unsigned num_buffers; active_atomic_buffer *const abs = find_active_atomic_counters(ctx, prog, &num_buffers); @@ -260,11 +259,11 @@ link_check_atomic_counter_resources(struct gl_context *ctx, for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { if (atomic_counters[i] > max_atomic_counters[i]) linker_error(prog, "Too many %s shader atomic counters", - shader_names[i]); + _mesa_shader_type_to_string(i)); if (atomic_buffers[i] > max_atomic_buffers[i]) linker_error(prog, "Too many %s shader atomic counter buffers", - shader_names[i]); + _mesa_shader_type_to_string(i)); } if (total_atomic_counters > ctx->Const.MaxCombinedAtomicCounters) diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp index 229a4cb85..98f902ca4 100644 --- a/mesalib/src/glsl/link_varyings.cpp +++ b/mesalib/src/glsl/link_varyings.cpp @@ -82,10 +82,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, linker_error(prog, "%s shader output `%s' declared as type `%s', " "but %s shader input declared as type `%s'\n", - _mesa_glsl_shader_target_name(producer_type), + _mesa_shader_enum_to_string(producer_type), output->name, output->type->name, - _mesa_glsl_shader_target_name(consumer_type), + _mesa_shader_enum_to_string(consumer_type), input->type->name); return; } @@ -97,10 +97,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, linker_error(prog, "%s shader output `%s' %s centroid qualifier, " "but %s shader input %s centroid qualifier\n", - _mesa_glsl_shader_target_name(producer_type), + _mesa_shader_enum_to_string(producer_type), output->name, (output->data.centroid) ? "has" : "lacks", - _mesa_glsl_shader_target_name(consumer_type), + _mesa_shader_enum_to_string(consumer_type), (input->data.centroid) ? "has" : "lacks"); return; } @@ -109,10 +109,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, linker_error(prog, "%s shader output `%s' %s sample qualifier, " "but %s shader input %s sample qualifier\n", - _mesa_glsl_shader_target_name(producer_type), + _mesa_shader_enum_to_string(producer_type), output->name, (output->data.sample) ? "has" : "lacks", - _mesa_glsl_shader_target_name(consumer_type), + _mesa_shader_enum_to_string(consumer_type), (input->data.sample) ? "has" : "lacks"); return; } @@ -121,10 +121,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, linker_error(prog, "%s shader output `%s' %s invariant qualifier, " "but %s shader input %s invariant qualifier\n", - _mesa_glsl_shader_target_name(producer_type), + _mesa_shader_enum_to_string(producer_type), output->name, (output->data.invariant) ? "has" : "lacks", - _mesa_glsl_shader_target_name(consumer_type), + _mesa_shader_enum_to_string(consumer_type), (input->data.invariant) ? "has" : "lacks"); return; } @@ -135,10 +135,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, "interpolation qualifier, " "but %s shader input specifies %s " "interpolation qualifier\n", - _mesa_glsl_shader_target_name(producer_type), + _mesa_shader_enum_to_string(producer_type), output->name, interpolation_string(output->data.interpolation), - _mesa_glsl_shader_target_name(consumer_type), + _mesa_shader_enum_to_string(consumer_type), interpolation_string(input->data.interpolation)); return; } @@ -1217,9 +1217,9 @@ assign_varying_locations(struct gl_context *ctx, linker_error(prog, "%s shader varying %s not written " "by %s shader\n.", - _mesa_glsl_shader_target_name(consumer->Type), + _mesa_shader_enum_to_string(consumer->Type), var->name, - _mesa_glsl_shader_target_name(producer->Type)); + _mesa_shader_enum_to_string(producer->Type)); } /* An 'in' variable is only really a shader input if its diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index a6133ea9c..a81e10737 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -414,7 +414,7 @@ link_invalidate_variable_locations(exec_list *ir) * Return false if an error was reported. */ static void -analyze_clip_usage(const char *shader_type, struct gl_shader_program *prog, +analyze_clip_usage(struct gl_shader_program *prog, struct gl_shader *shader, GLboolean *UsesClipDistance, GLuint *ClipDistanceArraySize) { @@ -437,7 +437,8 @@ analyze_clip_usage(const char *shader_type, struct gl_shader_program *prog, clip_distance.run(shader->ir); if (clip_vertex.variable_found() && clip_distance.variable_found()) { linker_error(prog, "%s shader writes to both `gl_ClipVertex' " - "and `gl_ClipDistance'\n", shader_type); + "and `gl_ClipDistance'\n", + _mesa_shader_enum_to_string(shader->Type)); return; } *UsesClipDistance = clip_distance.variable_found(); @@ -501,7 +502,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, } } - analyze_clip_usage("vertex", prog, shader, &prog->Vert.UsesClipDistance, + analyze_clip_usage(prog, shader, &prog->Vert.UsesClipDistance, &prog->Vert.ClipDistanceArraySize); } @@ -548,7 +549,7 @@ validate_geometry_shader_executable(struct gl_shader_program *prog, unsigned num_vertices = vertices_per_prim(prog->Geom.InputType); prog->Geom.VerticesIn = num_vertices; - analyze_clip_usage("geometry", prog, shader, &prog->Geom.UsesClipDistance, + analyze_clip_usage(prog, shader, &prog->Geom.UsesClipDistance, &prog->Geom.ClipDistanceArraySize); find_end_primitive_visitor end_primitive; @@ -1375,7 +1376,7 @@ link_intrastage_shaders(void *mem_ctx, if (main == NULL) { linker_error(prog, "%s shader lacks `main'\n", - _mesa_glsl_shader_target_name(shader_list[0]->Type)); + _mesa_shader_enum_to_string(shader_list[0]->Type)); return NULL; } @@ -1893,33 +1894,35 @@ store_fragdepth_layout(struct gl_shader_program *prog) static void check_resources(struct gl_context *ctx, struct gl_shader_program *prog) { - static const char *const shader_names[MESA_SHADER_TYPES] = { - "vertex", "geometry", "fragment" - }; - - const unsigned max_samplers[MESA_SHADER_TYPES] = { + const unsigned max_samplers[] = { ctx->Const.VertexProgram.MaxTextureImageUnits, ctx->Const.GeometryProgram.MaxTextureImageUnits, ctx->Const.FragmentProgram.MaxTextureImageUnits }; + STATIC_ASSERT(Elements(max_samplers) == MESA_SHADER_TYPES); - const unsigned max_default_uniform_components[MESA_SHADER_TYPES] = { + const unsigned max_default_uniform_components[] = { ctx->Const.VertexProgram.MaxUniformComponents, ctx->Const.GeometryProgram.MaxUniformComponents, ctx->Const.FragmentProgram.MaxUniformComponents }; + STATIC_ASSERT(Elements(max_default_uniform_components) == + MESA_SHADER_TYPES); - const unsigned max_combined_uniform_components[MESA_SHADER_TYPES] = { + const unsigned max_combined_uniform_components[] = { ctx->Const.VertexProgram.MaxCombinedUniformComponents, ctx->Const.GeometryProgram.MaxCombinedUniformComponents, ctx->Const.FragmentProgram.MaxCombinedUniformComponents }; + STATIC_ASSERT(Elements(max_combined_uniform_components) == + MESA_SHADER_TYPES); - const unsigned max_uniform_blocks[MESA_SHADER_TYPES] = { + const unsigned max_uniform_blocks[] = { ctx->Const.VertexProgram.MaxUniformBlocks, ctx->Const.GeometryProgram.MaxUniformBlocks, ctx->Const.FragmentProgram.MaxUniformBlocks }; + STATIC_ASSERT(Elements(max_uniform_blocks) == MESA_SHADER_TYPES); for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { struct gl_shader *sh = prog->_LinkedShaders[i]; @@ -1929,7 +1932,7 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) if (sh->num_samplers > max_samplers[i]) { linker_error(prog, "Too many %s shader texture samplers", - shader_names[i]); + _mesa_shader_type_to_string(i)); } if (sh->num_uniform_components > max_default_uniform_components[i]) { @@ -1938,11 +1941,11 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) "components, but the driver will try to optimize " "them out; this is non-portable out-of-spec " "behavior\n", - shader_names[i]); + _mesa_shader_type_to_string(i)); } else { linker_error(prog, "Too many %s shader default uniform block " "components", - shader_names[i]); + _mesa_shader_type_to_string(i)); } } @@ -1952,10 +1955,10 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) linker_warning(prog, "Too many %s shader uniform components, " "but the driver will try to optimize them out; " "this is non-portable out-of-spec behavior\n", - shader_names[i]); + _mesa_shader_type_to_string(i)); } else { linker_error(prog, "Too many %s shader uniform components", - shader_names[i]); + _mesa_shader_type_to_string(i)); } } } @@ -1979,7 +1982,7 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { if (blocks[i] > max_uniform_blocks[i]) { linker_error(prog, "Too many %s uniform blocks (%d/%d)", - shader_names[i], + _mesa_shader_type_to_string(i), blocks[i], max_uniform_blocks[i]); break; diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 4f3be68a4..57511e83e 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -791,7 +791,7 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) } else { if (ctx->Shader.Flags & GLSL_DUMP) { printf("GLSL source for %s shader %d:\n", - _mesa_glsl_shader_target_name(sh->Type), sh->Name); + _mesa_shader_enum_to_string(sh->Type), sh->Name); printf("%s\n", sh->Source); } @@ -823,7 +823,7 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) if (!sh->CompileStatus) { if (ctx->Shader.Flags & GLSL_DUMP_ON_ERROR) { fprintf(stderr, "GLSL source for %s shader %d:\n", - _mesa_glsl_shader_target_name(sh->Type), sh->Name); + _mesa_shader_enum_to_string(sh->Type), sh->Name); fprintf(stderr, "%s\n", sh->Source); fprintf(stderr, "Info Log:\n%s\n", sh->InfoLog); fflush(stderr); @@ -898,7 +898,7 @@ print_shader_info(const struct gl_shader_program *shProg) printf("Mesa: glUseProgram(%u)\n", shProg->Name); for (i = 0; i < shProg->NumShaders; i++) { printf(" %s shader %u, checksum %u\n", - _mesa_glsl_shader_target_name(shProg->Shaders[i]->Type), + _mesa_shader_enum_to_string(shProg->Shaders[i]->Type), shProg->Shaders[i]->Name, shProg->Shaders[i]->SourceChecksum); } diff --git a/mesalib/src/mesa/main/shaderobj.h b/mesalib/src/mesa/main/shaderobj.h index aff178f26..155058d71 100644 --- a/mesalib/src/mesa/main/shaderobj.h +++ b/mesalib/src/mesa/main/shaderobj.h @@ -118,21 +118,6 @@ _mesa_shader_type_to_index(GLenum v) } -static inline GLenum -_mesa_shader_index_to_type(GLuint i) -{ - static const GLenum enums[MESA_SHADER_TYPES] = { - GL_VERTEX_SHADER, - GL_GEOMETRY_SHADER, - GL_FRAGMENT_SHADER - }; - if (i >= MESA_SHADER_TYPES) - return 0; - else - return enums[i]; -} - - #ifdef __cplusplus } #endif diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 88ad476ac..61bcbcb8a 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -452,7 +452,7 @@ log_program_parameters(const struct gl_shader_program *shProg) const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program; printf("Program %d %s shader parameters:\n", - shProg->Name, _mesa_glsl_shader_target_name(prog->Target)); + shProg->Name, _mesa_shader_enum_to_string(prog->Target)); for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { printf("%s: %p %f %f %f %f\n", prog->Parameters->Parameters[j].Name, diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 23d479c32..beb0c093b 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -2801,7 +2801,7 @@ get_mesa_program(struct gl_context *ctx, int i; struct gl_program *prog; GLenum target; - const char *target_string = _mesa_glsl_shader_target_name(shader->Type); + const char *target_string = _mesa_shader_enum_to_string(shader->Type); struct gl_shader_compiler_options *options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; diff --git a/mesalib/src/mesa/program/program.h b/mesalib/src/mesa/program/program.h index 353ccab47..baff47376 100644 --- a/mesalib/src/mesa/program/program.h +++ b/mesalib/src/mesa/program/program.h @@ -210,14 +210,16 @@ _mesa_program_target_to_index(GLenum v) static inline GLenum _mesa_program_index_to_target(GLuint i) { - static const GLenum enums[MESA_SHADER_TYPES] = { + static const GLenum enums[] = { GL_VERTEX_PROGRAM_ARB, GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_ARB }; - if(i >= MESA_SHADER_TYPES) + STATIC_ASSERT(Elements(enums) == MESA_SHADER_TYPES); + if(i >= MESA_SHADER_TYPES) { + assert(!"Unexpected program index"); return 0; - else + } else return enums[i]; } diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 1331c73dc..eb12426a5 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -5143,7 +5143,7 @@ get_mesa_program(struct gl_context *ctx, if (ctx->Shader.Flags & GLSL_DUMP) { printf("\n"); printf("GLSL IR for linked %s program %d:\n", - _mesa_glsl_shader_target_name(shader->Type), + _mesa_shader_enum_to_string(shader->Type), shader_program->Name); _mesa_print_ir(shader->ir, NULL); printf("\n"); diff --git a/mkfontscale/list.c b/mkfontscale/list.c index 1614d9537..320ce20c6 100644 --- a/mkfontscale/list.c +++ b/mkfontscale/list.c @@ -235,7 +235,12 @@ sortList(ListPtr old) int i; int l = listLength(old); ListPtr n; - ListPtr *sorted = malloc(l * sizeof(ListPtr)); + ListPtr *sorted; + + if (l <= 0) + return old; + + sorted = malloc(l * sizeof(ListPtr)); if (sorted == NULL) return old; diff --git a/mkfontscale/mkfontscale.c b/mkfontscale/mkfontscale.c index a494f931d..265f91369 100644 --- a/mkfontscale/mkfontscale.c +++ b/mkfontscale/mkfontscale.c @@ -490,7 +490,7 @@ safe(const char* s) i++; } - if(safe_flag) return s; + if(safe_flag) return strdup(s); len = i; t = malloc(len + 1); @@ -514,7 +514,7 @@ makeXLFD(char *filename, FT_Face face, int isBitmap) { ListPtr xlfd = NULL; const char *foundry, *family, *weight, *slant, *sWidth, *adstyle, - *spacing, *full_name; + *spacing, *full_name, *tmp; TT_Header *head; TT_HoriHeader *hhea; TT_OS2 *os2; @@ -582,11 +582,11 @@ makeXLFD(char *filename, FT_Face face, int isBitmap) if(t1info) { if(!family) - family = t1info->family_name; + family = strdup(t1info->family_name); if(!family) - family = t1info->full_name; + family = strdup(t1info->full_name); if(!full_name) - full_name = t1info->full_name; + full_name = strdup(t1info->full_name); if(!foundry) foundry = notice_foundry(t1info->notice); if(!weight) @@ -603,7 +603,7 @@ makeXLFD(char *filename, FT_Face face, int isBitmap) if(!full_name) { fprintf(stderr, "Couldn't determine full name for %s\n", filename); - full_name = filename; + full_name = strdup(filename); } if(head) { @@ -628,11 +628,13 @@ makeXLFD(char *filename, FT_Face face, int isBitmap) notice = getName(face, TT_NAME_ID_TRADEMARK); if(notice) { foundry = notice_foundry(notice); + free(notice); } if(!foundry) { notice = getName(face, TT_NAME_ID_MANUFACTURER); if(notice) { foundry = notice_foundry(notice); + free(notice); } } } @@ -650,7 +652,7 @@ makeXLFD(char *filename, FT_Face face, int isBitmap) if(!foundry) foundry = "misc"; if(!family) { fprintf(stderr, "Couldn't get family name for %s\n", filename); - family = filename; + family = strdup(filename); } if(!weight) weight = "medium"; @@ -659,9 +661,11 @@ makeXLFD(char *filename, FT_Face face, int isBitmap) if(!adstyle) adstyle = ""; if(!spacing) spacing = "p"; - /* Yes, it's a memory leak. */ foundry = safe(foundry); + + tmp = family; family = safe(family); + free((void *)tmp); if(!isBitmap) { xlfd = listConsF(xlfd, @@ -684,6 +688,10 @@ makeXLFD(char *filename, FT_Face face, int isBitmap) spacing, 60); } } + + free((void *)family); + free((void *)foundry); + free((void *)full_name); return xlfd; } diff --git a/pixman/configure.ac b/pixman/configure.ac index 5910fbb4b..632797241 100644 --- a/pixman/configure.ac +++ b/pixman/configure.ac @@ -184,6 +184,7 @@ AC_SUBST(LT_VERSION_INFO) PIXMAN_CHECK_CFLAG([-Wall]) PIXMAN_CHECK_CFLAG([-Wdeclaration-after-statement]) +PIXMAN_CHECK_CFLAG([-Wno-unused-local-typedefs]) PIXMAN_CHECK_CFLAG([-fno-strict-aliasing]) dnl ========================================================================= diff --git a/pixman/pixman/pixman-combine-float.c b/pixman/pixman/pixman-combine-float.c index e9aab4833..f5145bc9d 100644 --- a/pixman/pixman/pixman-combine-float.c +++ b/pixman/pixman/pixman-combine-float.c @@ -319,23 +319,44 @@ MAKE_PD_COMBINERS (conjoint_xor, ONE_MINUS_DA_OVER_SA, ONE_MINUS_SA_OVER_DA) * * The following blend modes have been taken from the PDF ISO 32000 * specification, which at this point in time is available from - * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf - * The relevant chapters are 11.3.5 and 11.3.6. + * + * http://www.adobe.com/devnet/pdf/pdf_reference.html + * + * The specific documents of interest are the PDF spec itself: + * + * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf + * + * chapters 11.3.5 and 11.3.6 and a later supplement for Adobe Acrobat + * 9.1 and Reader 9.1: + * + * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000_1.pdf + * + * that clarifies the specifications for blend modes ColorDodge and + * ColorBurn. + * * The formula for computing the final pixel color given in 11.3.6 is: - * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) - * with B() being the blend function. - * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs - * - * These blend modes should match the SVG filter draft specification, as - * it has been designed to mirror ISO 32000. Note that at the current point - * no released draft exists that shows this, as the formulas have not been - * updated yet after the release of ISO 32000. - * - * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and - * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an - * argument. Note that this implementation operates on premultiplied colors, - * while the PDF specification does not. Therefore the code uses the formula - * ar.Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as) + * + * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) + * + * with B() is the blend function. When B(Cb, Cs) = Cs, this formula + * reduces to the regular OVER operator. + * + * Cs and Cb are not premultiplied, so in our implementation we instead + * use: + * + * cr = (1 – αs) × cb + (1 – αb) × cs + αb × αs × B (cb/αb, cs/αs) + * + * where cr, cs, and cb are premultiplied colors, and where the + * + * αb × αs × B(cb/αb, cs/αs) + * + * part is first arithmetically simplified under the assumption that αb + * and αs are not 0, and then updated to produce a meaningful result when + * they are. + * + * For all the blend mode operators, the alpha channel is given by + * + * αr = αs + αb + αb × αs */ #define MAKE_SEPARABLE_PDF_COMBINERS(name) \ @@ -355,18 +376,55 @@ MAKE_PD_COMBINERS (conjoint_xor, ONE_MINUS_DA_OVER_SA, ONE_MINUS_SA_OVER_DA) \ MAKE_COMBINERS (name, combine_ ## name ## _a, combine_ ## name ## _c) +/* + * Multiply + * + * ad * as * B(d / ad, s / as) + * = ad * as * d/ad * s/as + * = d * s + * + */ static force_inline float blend_multiply (float sa, float s, float da, float d) { return d * s; } +/* + * Screen + * + * ad * as * B(d/ad, s/as) + * = ad * as * (d/ad + s/as - s/as * d/ad) + * = ad * s + as * d - s * d + */ static force_inline float blend_screen (float sa, float s, float da, float d) { return d * sa + s * da - s * d; } +/* + * Overlay + * + * ad * as * B(d/ad, s/as) + * = ad * as * Hardlight (s, d) + * = if (d / ad < 0.5) + * as * ad * Multiply (s/as, 2 * d/ad) + * else + * as * ad * Screen (s/as, 2 * d / ad - 1) + * = if (d < 0.5 * ad) + * as * ad * s/as * 2 * d /ad + * else + * as * ad * (s/as + 2 * d / ad - 1 - s / as * (2 * d / ad - 1)) + * = if (2 * d < ad) + * 2 * s * d + * else + * ad * s + 2 * as * d - as * ad - ad * s * (2 * d / ad - 1) + * = if (2 * d < ad) + * 2 * s * d + * else + * as * ad - 2 * (ad - d) * (as - s) + */ static force_inline float blend_overlay (float sa, float s, float da, float d) { @@ -376,6 +434,13 @@ blend_overlay (float sa, float s, float da, float d) return sa * da - 2 * (da - d) * (sa - s); } +/* + * Darken + * + * ad * as * B(d/ad, s/as) + * = ad * as * MIN(d/ad, s/as) + * = MIN (as * d, ad * s) + */ static force_inline float blend_darken (float sa, float s, float da, float d) { @@ -388,6 +453,13 @@ blend_darken (float sa, float s, float da, float d) return s; } +/* + * Lighten + * + * ad * as * B(d/ad, s/as) + * = ad * as * MAX(d/ad, s/as) + * = MAX (as * d, ad * s) + */ static force_inline float blend_lighten (float sa, float s, float da, float d) { @@ -400,6 +472,24 @@ blend_lighten (float sa, float s, float da, float d) return d; } +/* + * Color dodge + * + * ad * as * B(d/ad, s/as) + * = if d/ad = 0 + * ad * as * 0 + * else if (d/ad >= (1 - s/as) + * ad * as * 1 + * else + * ad * as * ((d/ad) / (1 - s/as)) + * = if d = 0 + * 0 + * elif as * d >= ad * (as - s) + * ad * as + * else + * as * (as * d / (as - s)) + * + */ static force_inline float blend_color_dodge (float sa, float s, float da, float d) { @@ -413,6 +503,26 @@ blend_color_dodge (float sa, float s, float da, float d) return sa * sa * d / (sa - s); } +/* + * Color burn + * + * We modify the first clause "if d = 1" to "if d >= 1" since with + * premultiplied colors d > 1 can actually happen. + * + * ad * as * B(d/ad, s/as) + * = if d/ad >= 1 + * ad * as * 1 + * elif (1 - d/ad) >= s/as + * ad * as * 0 + * else + * ad * as * (1 - ((1 - d/ad) / (s/as))) + * = if d >= ad + * ad * as + * elif as * ad - as * d >= ad * s + * 0 + * else + * ad * as - as * as * (ad - d) / s + */ static force_inline float blend_color_burn (float sa, float s, float da, float d) { @@ -426,6 +536,23 @@ blend_color_burn (float sa, float s, float da, float d) return sa * (da - sa * (da - d) / s); } +/* + * Hard light + * + * ad * as * B(d/ad, s/as) + * = if (s/as <= 0.5) + * ad * as * Multiply (d/ad, 2 * s/as) + * else + * ad * as * Screen (d/ad, 2 * s/as - 1) + * = if 2 * s <= as + * ad * as * d/ad * 2 * s / as + * else + * ad * as * (d/ad + (2 * s/as - 1) + d/ad * (2 * s/as - 1)) + * = if 2 * s <= as + * 2 * s * d + * else + * as * ad - 2 * (ad - d) * (as - s) + */ static force_inline float blend_hard_light (float sa, float s, float da, float d) { @@ -435,6 +562,23 @@ blend_hard_light (float sa, float s, float da, float d) return sa * da - 2 * (da - d) * (sa - s); } +/* + * Soft light + * + * ad * as * B(d/ad, s/as) + * = if (s/as <= 0.5) + * ad * as * (d/ad - (1 - 2 * s/as) * d/ad * (1 - d/ad)) + * else if (d/ad <= 0.25) + * ad * as * (d/ad + (2 * s/as - 1) * ((((16 * d/ad - 12) * d/ad + 4) * d/ad) - d/ad)) + * else + * ad * as * (d/ad + (2 * s/as - 1) * sqrt (d/ad)) + * = if (2 * s <= as) + * d * as - d * (ad - d) * (as - 2 * s) / ad; + * else if (4 * d <= ad) + * (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3); + * else + * d * as + (sqrt (d * ad) - d) * (2 * s - as); + */ static force_inline float blend_soft_light (float sa, float s, float da, float d) { @@ -449,7 +593,7 @@ blend_soft_light (float sa, float s, float da, float d) { if (FLOAT_IS_ZERO (da)) { - return 0.0f; + return d * sa; } else { @@ -461,6 +605,20 @@ blend_soft_light (float sa, float s, float da, float d) } } +/* + * Difference + * + * ad * as * B(s/as, d/ad) + * = ad * as * abs (s/as - d/ad) + * = if (s/as <= d/ad) + * ad * as * (d/ad - s/as) + * else + * ad * as * (s/as - d/ad) + * = if (ad * s <= as * d) + * as * d - ad * s + * else + * ad * s - as * d + */ static force_inline float blend_difference (float sa, float s, float da, float d) { @@ -473,6 +631,13 @@ blend_difference (float sa, float s, float da, float d) return sda - dsa; } +/* + * Exclusion + * + * ad * as * B(s/as, d/ad) + * = ad * as * (d/ad + s/as - 2 * d/ad * s/as) + * = as * d + ad * s - 2 * s * d + */ static force_inline float blend_exclusion (float sa, float s, float da, float d) { @@ -492,116 +657,79 @@ MAKE_SEPARABLE_PDF_COMBINERS (difference) MAKE_SEPARABLE_PDF_COMBINERS (exclusion) /* - * PDF nonseperable blend modes. - * - * These are implemented using the following functions to operate in Hsl - * space, with Cmax, Cmid, Cmin referring to the max, mid and min value - * of the red, green and blue components. + * PDF nonseperable blend modes are implemented using the following functions + * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid + * and min value of the red, green and blue components. * * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue * * clip_color (C): - * l = LUM (C) - * min = Cmin - * max = Cmax - * if n < 0.0 - * C = l + (((C – l) × l) ⁄ (l – min)) - * if x > 1.0 - * C = l + (((C – l) × (1 – l)) (max – l)) - * return C + * l = LUM (C) + * min = Cmin + * max = Cmax + * if n < 0.0 + * C = l + (((C – l) × l) ⁄ (l – min)) + * if x > 1.0 + * C = l + (((C – l) × (1 – l) ) ⁄ (max – l)) + * return C * * set_lum (C, l): - * d = l – LUM (C) - * C += d - * return clip_color (C) + * d = l – LUM (C) + * C += d + * return clip_color (C) * * SAT (C) = CH_MAX (C) - CH_MIN (C) * * set_sat (C, s): - * if Cmax > Cmin - * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) ) - * Cmax = s - * else - * Cmid = Cmax = 0.0 - * Cmin = 0.0 - * return C + * if Cmax > Cmin + * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) ) + * Cmax = s + * else + * Cmid = Cmax = 0.0 + * Cmin = 0.0 + * return C */ /* For premultiplied colors, we need to know what happens when C is * multiplied by a real number. LUM and SAT are linear: * - * LUM (r × C) = r × LUM (C) SAT (r × C) = r × SAT (C) + * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C) * * If we extend clip_color with an extra argument a and change * - * if x >= 1.0 + * if x >= 1.0 * * into * - * if x >= a + * if x >= a * * then clip_color is also linear: * - * r * clip_color (C, a) = clip_color (r_c, ra); + * r * clip_color (C, a) = clip_color (r * C, r * a); * * for positive r. * * Similarly, we can extend set_lum with an extra argument that is just passed * on to clip_color: * - * r × set_lum ( C, l, a) + * r * set_lum (C, l, a) * - * = r × clip_color ( C + l - LUM (C), a) + * = r × clip_color (C + l - LUM (C), a) * - * = clip_color ( r * C + r × l - LUM (r × C), r * a) + * = clip_color (r * C + r × l - r * LUM (C), r * a) * - * = set_lum ( r * C, r * l, r * a) + * = set_lum (r * C, r * l, r * a) * * Finally, set_sat: * - * r * set_sat (C, s) = set_sat (x * C, r * s) + * r * set_sat (C, s) = set_sat (x * C, r * s) * - * The above holds for all non-zero x because they x'es in the fraction for + * The above holds for all non-zero x, because the x'es in the fraction for * C_mid cancel out. Specifically, it holds for x = r: * - * r * set_sat (C, s) = set_sat (r_c, rs) - * - * - * - * - * So, for the non-separable PDF blend modes, we have (using s, d for - * non-premultiplied colors, and S, D for premultiplied: - * - * Color: - * - * a_s * a_d * B(s, d) - * = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1) - * = set_lum (S * a_d, a_s * LUM (D), a_s * a_d) - * - * - * Luminosity: - * - * a_s * a_d * B(s, d) - * = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1) - * = set_lum (a_s * D, a_d * LUM(S), a_s * a_d) - * - * - * Saturation: - * - * a_s * a_d * B(s, d) - * = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1) - * = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)), - * a_s * LUM (D), a_s * a_d) - * = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d)) - * - * Hue: - * - * a_s * a_d * B(s, d) - * = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1) - * = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d) + * r * set_sat (C, s) = set_sat (r * C, r * s) * */ - typedef struct { float r; @@ -769,9 +897,12 @@ set_sat (rgb_t *src, float sat) *min = 0.0f; } -/* - * Hue: - * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb)) +/* Hue: + * + * as * ad * B(s/as, d/as) + * = as * ad * set_lum (set_sat (s/as, SAT (d/ad)), LUM (d/ad), 1) + * = set_lum (set_sat (ad * s, as * SAT (d)), as * LUM (d), as * ad) + * */ static force_inline void blend_hsl_hue (rgb_t *res, @@ -786,9 +917,14 @@ blend_hsl_hue (rgb_t *res, set_lum (res, sa * da, get_lum (dest) * sa); } -/* - * Saturation: - * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb)) +/* + * Saturation + * + * as * ad * B(s/as, d/ad) + * = as * ad * set_lum (set_sat (d/ad, SAT (s/as)), LUM (d/ad), 1) + * = set_lum (as * ad * set_sat (d/ad, SAT (s/as)), + * as * LUM (d), as * ad) + * = set_lum (set_sat (as * d, ad * SAT (s), as * LUM (d), as * ad)) */ static force_inline void blend_hsl_saturation (rgb_t *res, @@ -803,9 +939,12 @@ blend_hsl_saturation (rgb_t *res, set_lum (res, sa * da, get_lum (dest) * sa); } -/* - * Color: - * B(Cb, Cs) = set_lum (Cs, LUM (Cb)) +/* + * Color + * + * as * ad * B(s/as, d/as) + * = as * ad * set_lum (s/as, LUM (d/ad), 1) + * = set_lum (s * ad, as * LUM (d), as * ad) */ static force_inline void blend_hsl_color (rgb_t *res, @@ -820,8 +959,11 @@ blend_hsl_color (rgb_t *res, } /* - * Luminosity: - * B(Cb, Cs) = set_lum (Cb, LUM (Cs)) + * Luminosity + * + * as * ad * B(s/as, d/ad) + * = as * ad * set_lum (d/ad, LUM (s/as), 1) + * = set_lum (as * d, ad * LUM (s), as * ad) */ static force_inline void blend_hsl_luminosity (rgb_t *res, diff --git a/pixman/pixman/pixman-combine32.c b/pixman/pixman/pixman-combine32.c index 44ca7e857..4c484d3e3 100644 --- a/pixman/pixman/pixman-combine32.c +++ b/pixman/pixman/pixman-combine32.c @@ -434,36 +434,6 @@ combine_add_u (pixman_implementation_t *imp, } } -static void -combine_saturate_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint16_t sa, da; - - sa = s >> A_SHIFT; - da = ~d >> A_SHIFT; - if (sa > da) - { - sa = DIV_UN8 (da, sa); - UN8x4_MUL_UN8 (s, sa); - } - ; - UN8x4_ADD_UN8x4 (d, s); - *(dest + i) = d; - } -} - - /* * PDF blend modes: * @@ -571,6 +541,15 @@ combine_multiply_ca (pixman_implementation_t *imp, } } +#define CLAMP(v, low, high) \ + do \ + { \ + if (v < (low)) \ + v = (low); \ + if (v > (high)) \ + v = (high); \ + } while (0) + #define PDF_SEPARABLE_BLEND_MODE(name) \ static void \ combine_ ## name ## _u (pixman_implementation_t *imp, \ @@ -589,16 +568,28 @@ combine_multiply_ca (pixman_implementation_t *imp, uint8_t isa = ~sa; \ uint8_t da = ALPHA_8 (d); \ uint8_t ida = ~da; \ - uint32_t result; \ - \ - result = d; \ - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida); \ + int32_t ra, rr, rg, rb; \ \ - *(dest + i) = result + \ - (DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) + \ - (blend_ ## name (RED_8 (d), da, RED_8 (s), sa) << R_SHIFT) + \ - (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa) << G_SHIFT) + \ - (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa)); \ + ra = da * 0xff + sa * 0xff - sa * da; \ + rr = isa * RED_8 (d) + ida * RED_8 (s); \ + rg = isa * GREEN_8 (d) + ida * GREEN_8 (s); \ + rb = isa * BLUE_8 (d) + ida * BLUE_8 (s); \ + \ + rr += blend_ ## name (RED_8 (d), da, RED_8 (s), sa); \ + rg += blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa); \ + rb += blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa); \ + \ + CLAMP (ra, 0, 255 * 255); \ + CLAMP (rr, 0, 255 * 255); \ + CLAMP (rg, 0, 255 * 255); \ + CLAMP (rb, 0, 255 * 255); \ + \ + ra = DIV_ONE_UN8 (ra); \ + rr = DIV_ONE_UN8 (rr); \ + rg = DIV_ONE_UN8 (rg); \ + rb = DIV_ONE_UN8 (rb); \ + \ + *(dest + i) = ra << 24 | rr << 16 | rg << 8 | rb; \ } \ } \ \ @@ -618,20 +609,35 @@ combine_multiply_ca (pixman_implementation_t *imp, uint32_t d = *(dest + i); \ uint8_t da = ALPHA_8 (d); \ uint8_t ida = ~da; \ - uint32_t result; \ - \ + int32_t ra, rr, rg, rb; \ + uint8_t ira, iga, iba; \ + \ combine_mask_ca (&s, &m); \ - \ - result = d; \ - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (result, ~m, s, ida); \ - \ - result += \ - (DIV_ONE_UN8 (ALPHA_8 (m) * (uint32_t)da) << A_SHIFT) + \ - (blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)) << R_SHIFT) + \ - (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)) << G_SHIFT) + \ - (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m))); \ \ - *(dest + i) = result; \ + ira = ~RED_8 (m); \ + iga = ~GREEN_8 (m); \ + iba = ~BLUE_8 (m); \ + \ + ra = da * 0xff + ALPHA_8 (s) * 0xff - ALPHA_8 (s) * da; \ + rr = ira * RED_8 (d) + ida * RED_8 (s); \ + rg = iga * GREEN_8 (d) + ida * GREEN_8 (s); \ + rb = iba * BLUE_8 (d) + ida * BLUE_8 (s); \ + \ + rr += blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)); \ + rg += blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)); \ + rb += blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m)); \ + \ + CLAMP (ra, 0, 255 * 255); \ + CLAMP (rr, 0, 255 * 255); \ + CLAMP (rg, 0, 255 * 255); \ + CLAMP (rb, 0, 255 * 255); \ + \ + ra = DIV_ONE_UN8 (ra); \ + rr = DIV_ONE_UN8 (rr); \ + rg = DIV_ONE_UN8 (rg); \ + rb = DIV_ONE_UN8 (rb); \ + \ + *(dest + i) = ra << 24 | rr << 16 | rg << 8 | rb; \ } \ } @@ -642,10 +648,10 @@ combine_multiply_ca (pixman_implementation_t *imp, * = ad * as * (d/ad + s/as - s/as * d/ad) * = ad * s + as * d - s * d */ -static inline uint32_t -blend_screen (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +static inline int32_t +blend_screen (int32_t d, int32_t ad, int32_t s, int32_t as) { - return DIV_ONE_UN8 (s * ad + d * as - s * d); + return s * ad + d * as - s * d; } PDF_SEPARABLE_BLEND_MODE (screen) @@ -672,8 +678,8 @@ PDF_SEPARABLE_BLEND_MODE (screen) * else * as * ad - 2 * (ad - d) * (as - s) */ -static inline uint32_t -blend_overlay (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +static inline int32_t +blend_overlay (int32_t d, int32_t ad, int32_t s, int32_t as) { uint32_t r; @@ -682,7 +688,7 @@ blend_overlay (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) else r = as * ad - 2 * (ad - d) * (as - s); - return DIV_ONE_UN8 (r); + return r; } PDF_SEPARABLE_BLEND_MODE (overlay) @@ -694,13 +700,13 @@ PDF_SEPARABLE_BLEND_MODE (overlay) * = ad * as * MIN(d/ad, s/as) * = MIN (as * d, ad * s) */ -static inline uint32_t -blend_darken (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +static inline int32_t +blend_darken (int32_t d, int32_t ad, int32_t s, int32_t as) { s = ad * s; d = as * d; - return DIV_ONE_UN8 (s > d ? d : s); + return s > d ? d : s; } PDF_SEPARABLE_BLEND_MODE (darken) @@ -712,86 +718,18 @@ PDF_SEPARABLE_BLEND_MODE (darken) * = ad * as * MAX(d/ad, s/as) * = MAX (as * d, ad * s) */ -static inline uint32_t -blend_lighten (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +static inline int32_t +blend_lighten (int32_t d, int32_t ad, int32_t s, int32_t as) { s = ad * s; d = as * d; - return DIV_ONE_UN8 (s > d ? s : d); + return s > d ? s : d; } PDF_SEPARABLE_BLEND_MODE (lighten) /* - * Color dodge - * - * ad * as * B(d/ad, s/as) - * = if d/ad = 0 - * ad * as * 0 - * else if (d/ad >= (1 - s/as) - * ad * as * 1 - * else - * ad * as * ((d/ad) / (1 - s/as)) - * = if d = 0 - * 0 - * elif as * d >= ad * (as - s) - * ad * as - * else - * as * (as * d / (as - s)) - * - */ -static inline uint32_t -blend_color_dodge (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) -{ - if (d == 0) - return 0; - else if (as * d >= ad * (as - s)) - return DIV_ONE_UN8 (as * ad); - else if (as - s == 0) - return DIV_ONE_UN8 (as * ad); - else - return DIV_ONE_UN8 (as * ((d * as) / ((as - s)))); -} - -PDF_SEPARABLE_BLEND_MODE (color_dodge) - -/* - * Color burn - * - * We modify the first clause "if d = 1" to "if d >= 1" since with - * premultiplied colors d > 1 can actually happen. - * - * ad * as * B(d/ad, s/as) - * = if d/ad >= 1 - * ad * as * 1 - * elif (1 - d/ad) >= s/as - * ad * as * 0 - * else - * ad * as * (1 - ((1 - d/ad) / (s/as))) - * = if d >= ad - * ad * as - * elif as * ad - as * d >= ad * s - * 0 - * else - * ad * as - as * as * (ad - d) / s - */ -static inline uint32_t -blend_color_burn (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) -{ - if (d >= ad) - return DIV_ONE_UN8 (ad * as); - else if (as * ad - as * d >= ad * s) - return 0; - else if (s == 0) - return 0; - else - return DIV_ONE_UN8 (ad * as - (as * as * (ad - d)) / s); -} - -PDF_SEPARABLE_BLEND_MODE (color_burn) - -/* * Hard light * * ad * as * B(d/ad, s/as) @@ -808,72 +746,18 @@ PDF_SEPARABLE_BLEND_MODE (color_burn) * else * as * ad - 2 * (ad - d) * (as - s) */ -static inline uint32_t -blend_hard_light (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +static inline int32_t +blend_hard_light (int32_t d, int32_t ad, int32_t s, int32_t as) { if (2 * s < as) - return DIV_ONE_UN8 (2 * s * d); + return 2 * s * d; else - return DIV_ONE_UN8 (as * ad - 2 * (ad - d) * (as - s)); + return as * ad - 2 * (ad - d) * (as - s); } PDF_SEPARABLE_BLEND_MODE (hard_light) /* - * Soft light - * - * ad * as * B(d/ad, s/as) - * = if (s/as <= 0.5) - * ad * as * (d/ad - (1 - 2 * s/as) * d/ad * (1 - d/ad)) - * else if (d/ad <= 0.25) - * ad * as * (d/ad + (2 * s/as - 1) * ((((16 * d/ad - 12) * d/ad + 4) * d/ad) - d/ad)) - * else - * ad * as * (d/ad + (2 * s/as - 1) * sqrt (d/ad)) - * = if (2 * s <= as) - * d * as - d * (ad - d) * (as - 2 * s) / ad; - * else if (4 * d <= ad) - * (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3); - * else - * d * as + (sqrt (d * ad) - d) * (2 * s - as); - */ -static inline uint32_t -blend_soft_light (uint32_t d_org, - uint32_t ad_org, - uint32_t s_org, - uint32_t as_org) -{ - double d = d_org * (1.0 / MASK); - double ad = ad_org * (1.0 / MASK); - double s = s_org * (1.0 / MASK); - double as = as_org * (1.0 / MASK); - double r; - - if (2 * s <= as) - { - if (ad == 0) - r = d * as; - else - r = d * as - d * (ad - d) * (as - 2 * s) / ad; - } - else if (ad == 0) - { - r = 0; - } - else if (4 * d <= ad) - { - r = d * as + - (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3); - } - else - { - r = d * as + (sqrt (d * ad) - d) * (2 * s - as); - } - return r * MASK + 0.5; -} - -PDF_SEPARABLE_BLEND_MODE (soft_light) - -/* * Difference * * ad * as * B(s/as, d/ad) @@ -887,16 +771,16 @@ PDF_SEPARABLE_BLEND_MODE (soft_light) * else * ad * s - as * d */ -static inline uint32_t -blend_difference (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +static inline int32_t +blend_difference (int32_t d, int32_t ad, int32_t s, int32_t as) { - uint32_t das = d * as; - uint32_t sad = s * ad; + int32_t das = d * as; + int32_t sad = s * ad; if (sad < das) - return DIV_ONE_UN8 (das - sad); + return das - sad; else - return DIV_ONE_UN8 (sad - das); + return sad - das; } PDF_SEPARABLE_BLEND_MODE (difference) @@ -912,796 +796,16 @@ PDF_SEPARABLE_BLEND_MODE (difference) /* This can be made faster by writing it directly and not using * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */ -static inline uint32_t -blend_exclusion (uint32_t d, uint32_t ad, uint32_t s, uint32_t as) +static inline int32_t +blend_exclusion (int32_t d, int32_t ad, int32_t s, int32_t as) { - return DIV_ONE_UN8 (s * ad + d * as - 2 * d * s); + return s * ad + d * as - 2 * d * s; } PDF_SEPARABLE_BLEND_MODE (exclusion) #undef PDF_SEPARABLE_BLEND_MODE -/* - * PDF nonseperable blend modes are implemented using the following functions - * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid - * and min value of the red, green and blue components. - * - * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue - * - * clip_color (C): - * l = LUM (C) - * min = Cmin - * max = Cmax - * if n < 0.0 - * C = l + (((C – l) × l) ⁄ (l – min)) - * if x > 1.0 - * C = l + (((C – l) × (1 – l) ) ⁄ (max – l)) - * return C - * - * set_lum (C, l): - * d = l – LUM (C) - * C += d - * return clip_color (C) - * - * SAT (C) = CH_MAX (C) - CH_MIN (C) - * - * set_sat (C, s): - * if Cmax > Cmin - * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) ) - * Cmax = s - * else - * Cmid = Cmax = 0.0 - * Cmin = 0.0 - * return C - */ - -/* For premultiplied colors, we need to know what happens when C is - * multiplied by a real number. LUM and SAT are linear: - * - * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C) - * - * If we extend clip_color with an extra argument a and change - * - * if x >= 1.0 - * - * into - * - * if x >= a - * - * then clip_color is also linear: - * - * r * clip_color (C, a) = clip_color (r * C, r * a); - * - * for positive r. - * - * Similarly, we can extend set_lum with an extra argument that is just passed - * on to clip_color: - * - * r * set_lum (C, l, a) - * - * = r × clip_color (C + l - LUM (C), a) - * - * = clip_color (r * C + r × l - r * LUM (C), r * a) - * - * = set_lum (r * C, r * l, r * a) - * - * Finally, set_sat: - * - * r * set_sat (C, s) = set_sat (x * C, r * s) - * - * The above holds for all non-zero x, because the x'es in the fraction for - * C_mid cancel out. Specifically, it holds for x = r: - * - * r * set_sat (C, s) = set_sat (r * C, r * s) - * - */ - -#define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2])) -#define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2])) -#define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100) -#define SAT(c) (CH_MAX (c) - CH_MIN (c)) - -#define PDF_NON_SEPARABLE_BLEND_MODE(name) \ - static void \ - combine_ ## name ## _u (pixman_implementation_t *imp, \ - pixman_op_t op, \ - uint32_t * dest, \ - const uint32_t * src, \ - const uint32_t * mask, \ - int width) \ - { \ - int i; \ - for (i = 0; i < width; ++i) \ - { \ - uint32_t s = combine_mask (src, mask, i); \ - uint32_t d = *(dest + i); \ - uint8_t sa = ALPHA_8 (s); \ - uint8_t isa = ~sa; \ - uint8_t da = ALPHA_8 (d); \ - uint8_t ida = ~da; \ - uint32_t result; \ - uint32_t sc[3], dc[3], c[3]; \ - \ - result = d; \ - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida); \ - dc[0] = RED_8 (d); \ - sc[0] = RED_8 (s); \ - dc[1] = GREEN_8 (d); \ - sc[1] = GREEN_8 (s); \ - dc[2] = BLUE_8 (d); \ - sc[2] = BLUE_8 (s); \ - blend_ ## name (c, dc, da, sc, sa); \ - \ - *(dest + i) = result + \ - (DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) + \ - (DIV_ONE_UN8 (c[0]) << R_SHIFT) + \ - (DIV_ONE_UN8 (c[1]) << G_SHIFT) + \ - (DIV_ONE_UN8 (c[2])); \ - } \ - } - -static void -set_lum (uint32_t dest[3], uint32_t src[3], uint32_t sa, uint32_t lum) -{ - double a, l, min, max; - double tmp[3]; - - a = sa * (1.0 / MASK); - - l = lum * (1.0 / MASK); - tmp[0] = src[0] * (1.0 / MASK); - tmp[1] = src[1] * (1.0 / MASK); - tmp[2] = src[2] * (1.0 / MASK); - - l = l - LUM (tmp); - tmp[0] += l; - tmp[1] += l; - tmp[2] += l; - - /* clip_color */ - l = LUM (tmp); - min = CH_MIN (tmp); - max = CH_MAX (tmp); - - if (min < 0) - { - if (l - min == 0.0) - { - tmp[0] = 0; - tmp[1] = 0; - tmp[2] = 0; - } - else - { - tmp[0] = l + (tmp[0] - l) * l / (l - min); - tmp[1] = l + (tmp[1] - l) * l / (l - min); - tmp[2] = l + (tmp[2] - l) * l / (l - min); - } - } - if (max > a) - { - if (max - l == 0.0) - { - tmp[0] = a; - tmp[1] = a; - tmp[2] = a; - } - else - { - tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l); - tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l); - tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l); - } - } - - dest[0] = tmp[0] * MASK + 0.5; - dest[1] = tmp[1] * MASK + 0.5; - dest[2] = tmp[2] * MASK + 0.5; -} - -static void -set_sat (uint32_t dest[3], uint32_t src[3], uint32_t sat) -{ - int id[3]; - uint32_t min, max; - - if (src[0] > src[1]) - { - if (src[0] > src[2]) - { - id[0] = 0; - if (src[1] > src[2]) - { - id[1] = 1; - id[2] = 2; - } - else - { - id[1] = 2; - id[2] = 1; - } - } - else - { - id[0] = 2; - id[1] = 0; - id[2] = 1; - } - } - else - { - if (src[0] > src[2]) - { - id[0] = 1; - id[1] = 0; - id[2] = 2; - } - else - { - id[2] = 0; - if (src[1] > src[2]) - { - id[0] = 1; - id[1] = 2; - } - else - { - id[0] = 2; - id[1] = 1; - } - } - } - - max = dest[id[0]]; - min = dest[id[2]]; - if (max > min) - { - dest[id[1]] = (dest[id[1]] - min) * sat / (max - min); - dest[id[0]] = sat; - dest[id[2]] = 0; - } - else - { - dest[0] = dest[1] = dest[2] = 0; - } -} - -/* Hue: - * - * as * ad * B(s/as, d/as) - * = as * ad * set_lum (set_sat (s/as, SAT (d/ad)), LUM (d/ad), 1) - * = set_lum (set_sat (ad * s, as * SAT (d)), as * LUM (d), as * ad) - * - */ -static inline void -blend_hsl_hue (uint32_t r[3], - uint32_t d[3], - uint32_t ad, - uint32_t s[3], - uint32_t as) -{ - r[0] = s[0] * ad; - r[1] = s[1] * ad; - r[2] = s[2] * ad; - set_sat (r, r, SAT (d) * as); - set_lum (r, r, as * ad, LUM (d) * as); -} - -PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue) - -/* - * Saturation - * - * as * ad * B(s/as, d/ad) - * = as * ad * set_lum (set_sat (d/ad, SAT (s/as)), LUM (d/ad), 1) - * = set_lum (as * ad * set_sat (d/ad, SAT (s/as)), - * as * LUM (d), as * ad) - * = set_lum (set_sat (as * d, ad * SAT (s), as * LUM (d), as * ad)) - */ -static inline void -blend_hsl_saturation (uint32_t r[3], - uint32_t d[3], - uint32_t ad, - uint32_t s[3], - uint32_t as) -{ - r[0] = d[0] * as; - r[1] = d[1] * as; - r[2] = d[2] * as; - set_sat (r, r, SAT (s) * ad); - set_lum (r, r, as * ad, LUM (d) * as); -} - -PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation) - -/* - * Color - * - * as * ad * B(s/as, d/as) - * = as * ad * set_lum (s/as, LUM (d/ad), 1) - * = set_lum (s * ad, as * LUM (d), as * ad) - */ -static inline void -blend_hsl_color (uint32_t r[3], - uint32_t d[3], - uint32_t ad, - uint32_t s[3], - uint32_t as) -{ - r[0] = s[0] * ad; - r[1] = s[1] * ad; - r[2] = s[2] * ad; - set_lum (r, r, as * ad, LUM (d) * as); -} - -PDF_NON_SEPARABLE_BLEND_MODE (hsl_color) - -/* - * Luminosity - * - * as * ad * B(s/as, d/ad) - * = as * ad * set_lum (d/ad, LUM (s/as), 1) - * = set_lum (as * d, ad * LUM (s), as * ad) - */ -static inline void -blend_hsl_luminosity (uint32_t r[3], - uint32_t d[3], - uint32_t ad, - uint32_t s[3], - uint32_t as) -{ - r[0] = d[0] * as; - r[1] = d[1] * as; - r[2] = d[2] * as; - set_lum (r, r, as * ad, LUM (s) * ad); -} - -PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity) - -#undef SAT -#undef LUM -#undef CH_MAX -#undef CH_MIN -#undef PDF_NON_SEPARABLE_BLEND_MODE - -/* All of the disjoint/conjoint composing functions - * - * The four entries in the first column indicate what source contributions - * come from each of the four areas of the picture -- areas covered by neither - * A nor B, areas covered only by A, areas covered only by B and finally - * areas covered by both A and B. - * - * Disjoint Conjoint - * Fa Fb Fa Fb - * (0,0,0,0) 0 0 0 0 - * (0,A,0,A) 1 0 1 0 - * (0,0,B,B) 0 1 0 1 - * (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0) - * (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1 - * (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0 - * (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1) - * (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0 - * (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0) - * (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0) - * (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b) - * (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0) - * - * See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more - * information about these operators. - */ - -#define COMBINE_A_OUT 1 -#define COMBINE_A_IN 2 -#define COMBINE_B_OUT 4 -#define COMBINE_B_IN 8 - -#define COMBINE_CLEAR 0 -#define COMBINE_A (COMBINE_A_OUT | COMBINE_A_IN) -#define COMBINE_B (COMBINE_B_OUT | COMBINE_B_IN) -#define COMBINE_A_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_A_IN) -#define COMBINE_B_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_B_IN) -#define COMBINE_A_ATOP (COMBINE_B_OUT | COMBINE_A_IN) -#define COMBINE_B_ATOP (COMBINE_A_OUT | COMBINE_B_IN) -#define COMBINE_XOR (COMBINE_A_OUT | COMBINE_B_OUT) - -/* portion covered by a but not b */ -static uint8_t -combine_disjoint_out_part (uint8_t a, uint8_t b) -{ - /* min (1, (1-b) / a) */ - - b = ~b; /* 1 - b */ - if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ - return MASK; /* 1 */ - return DIV_UN8 (b, a); /* (1-b) / a */ -} - -/* portion covered by both a and b */ -static uint8_t -combine_disjoint_in_part (uint8_t a, uint8_t b) -{ - /* max (1-(1-b)/a,0) */ - /* = - min ((1-b)/a - 1, 0) */ - /* = 1 - min (1, (1-b)/a) */ - - b = ~b; /* 1 - b */ - if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ - return 0; /* 1 - 1 */ - return ~DIV_UN8(b, a); /* 1 - (1-b) / a */ -} - -/* portion covered by a but not b */ -static uint8_t -combine_conjoint_out_part (uint8_t a, uint8_t b) -{ - /* max (1-b/a,0) */ - /* = 1-min(b/a,1) */ - - /* min (1, (1-b) / a) */ - - if (b >= a) /* b >= a -> b/a >= 1 */ - return 0x00; /* 0 */ - return ~DIV_UN8(b, a); /* 1 - b/a */ -} - -/* portion covered by both a and b */ -static uint8_t -combine_conjoint_in_part (uint8_t a, uint8_t b) -{ - /* min (1,b/a) */ - - if (b >= a) /* b >= a -> b/a >= 1 */ - return MASK; /* 1 */ - return DIV_UN8 (b, a); /* b/a */ -} - -#define GET_COMP(v, i) ((uint16_t) (uint8_t) ((v) >> i)) - -#define ADD(x, y, i, t) \ - ((t) = GET_COMP (x, i) + GET_COMP (y, i), \ - (uint32_t) ((uint8_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i)) - -#define GENERIC(x, y, i, ax, ay, t, u, v) \ - ((t) = (MUL_UN8 (GET_COMP (y, i), ay, (u)) + \ - MUL_UN8 (GET_COMP (x, i), ax, (v))), \ - (uint32_t) ((uint8_t) ((t) | \ - (0 - ((t) >> G_SHIFT)))) << (i)) - -static void -combine_disjoint_general_u (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width, - uint8_t combine) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t m, n, o, p; - uint16_t Fa, Fb, t, u, v; - uint8_t sa = s >> A_SHIFT; - uint8_t da = d >> A_SHIFT; - - switch (combine & COMBINE_A) - { - default: - Fa = 0; - break; - - case COMBINE_A_OUT: - Fa = combine_disjoint_out_part (sa, da); - break; - - case COMBINE_A_IN: - Fa = combine_disjoint_in_part (sa, da); - break; - - case COMBINE_A: - Fa = MASK; - break; - } - - switch (combine & COMBINE_B) - { - default: - Fb = 0; - break; - - case COMBINE_B_OUT: - Fb = combine_disjoint_out_part (da, sa); - break; - - case COMBINE_B_IN: - Fb = combine_disjoint_in_part (da, sa); - break; - - case COMBINE_B: - Fb = MASK; - break; - } - m = GENERIC (s, d, 0, Fa, Fb, t, u, v); - n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v); - o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v); - p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v); - s = m | n | o | p; - *(dest + i) = s; - } -} - -static void -combine_disjoint_over_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint16_t a = s >> A_SHIFT; - - if (s != 0x00) - { - uint32_t d = *(dest + i); - a = combine_disjoint_out_part (d >> A_SHIFT, a); - UN8x4_MUL_UN8_ADD_UN8x4 (d, a, s); - - *(dest + i) = d; - } - } -} - -static void -combine_disjoint_in_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN); -} - -static void -combine_disjoint_in_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN); -} - -static void -combine_disjoint_out_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT); -} - -static void -combine_disjoint_out_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT); -} - -static void -combine_disjoint_atop_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP); -} - -static void -combine_disjoint_atop_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP); -} - -static void -combine_disjoint_xor_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR); -} - -static void -combine_conjoint_general_u (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width, - uint8_t combine) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t m, n, o, p; - uint16_t Fa, Fb, t, u, v; - uint8_t sa = s >> A_SHIFT; - uint8_t da = d >> A_SHIFT; - - switch (combine & COMBINE_A) - { - default: - Fa = 0; - break; - - case COMBINE_A_OUT: - Fa = combine_conjoint_out_part (sa, da); - break; - - case COMBINE_A_IN: - Fa = combine_conjoint_in_part (sa, da); - break; - - case COMBINE_A: - Fa = MASK; - break; - } - - switch (combine & COMBINE_B) - { - default: - Fb = 0; - break; - - case COMBINE_B_OUT: - Fb = combine_conjoint_out_part (da, sa); - break; - - case COMBINE_B_IN: - Fb = combine_conjoint_in_part (da, sa); - break; - - case COMBINE_B: - Fb = MASK; - break; - } - - m = GENERIC (s, d, 0, Fa, Fb, t, u, v); - n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v); - o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v); - p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v); - - s = m | n | o | p; - - *(dest + i) = s; - } -} - -static void -combine_conjoint_over_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER); -} - -static void -combine_conjoint_over_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER); -} - -static void -combine_conjoint_in_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN); -} - -static void -combine_conjoint_in_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN); -} - -static void -combine_conjoint_out_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT); -} - -static void -combine_conjoint_out_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT); -} - -static void -combine_conjoint_atop_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP); -} - -static void -combine_conjoint_atop_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP); -} - -static void -combine_conjoint_xor_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR); -} - - /* Component alpha combiners */ static void @@ -2032,428 +1136,6 @@ combine_add_ca (pixman_implementation_t *imp, } } -static void -combine_saturate_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s, d; - uint16_t sa, sr, sg, sb, da; - uint16_t t, u, v; - uint32_t m, n, o, p; - - d = *(dest + i); - s = *(src + i); - m = *(mask + i); - - combine_mask_ca (&s, &m); - - sa = (m >> A_SHIFT); - sr = (m >> R_SHIFT) & MASK; - sg = (m >> G_SHIFT) & MASK; - sb = m & MASK; - da = ~d >> A_SHIFT; - - if (sb <= da) - m = ADD (s, d, 0, t); - else - m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v); - - if (sg <= da) - n = ADD (s, d, G_SHIFT, t); - else - n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v); - - if (sr <= da) - o = ADD (s, d, R_SHIFT, t); - else - o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v); - - if (sa <= da) - p = ADD (s, d, A_SHIFT, t); - else - p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v); - - *(dest + i) = m | n | o | p; - } -} - -static void -combine_disjoint_general_ca (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width, - uint8_t combine) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s, d; - uint32_t m, n, o, p; - uint32_t Fa, Fb; - uint16_t t, u, v; - uint32_t sa; - uint8_t da; - - s = *(src + i); - m = *(mask + i); - d = *(dest + i); - da = d >> A_SHIFT; - - combine_mask_ca (&s, &m); - - sa = m; - - switch (combine & COMBINE_A) - { - default: - Fa = 0; - break; - - case COMBINE_A_OUT: - m = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> 0), da); - n = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT; - o = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT; - p = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT; - Fa = m | n | o | p; - break; - - case COMBINE_A_IN: - m = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> 0), da); - n = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT; - o = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT; - p = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT; - Fa = m | n | o | p; - break; - - case COMBINE_A: - Fa = ~0; - break; - } - - switch (combine & COMBINE_B) - { - default: - Fb = 0; - break; - - case COMBINE_B_OUT: - m = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> 0)); - n = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT; - o = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT; - p = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT; - Fb = m | n | o | p; - break; - - case COMBINE_B_IN: - m = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> 0)); - n = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT; - o = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT; - p = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT; - Fb = m | n | o | p; - break; - - case COMBINE_B: - Fb = ~0; - break; - } - m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v); - n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v); - o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v); - p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v); - - s = m | n | o | p; - - *(dest + i) = s; - } -} - -static void -combine_disjoint_over_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER); -} - -static void -combine_disjoint_in_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN); -} - -static void -combine_disjoint_in_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN); -} - -static void -combine_disjoint_out_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT); -} - -static void -combine_disjoint_out_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT); -} - -static void -combine_disjoint_atop_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP); -} - -static void -combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP); -} - -static void -combine_disjoint_xor_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR); -} - -static void -combine_conjoint_general_ca (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width, - uint8_t combine) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s, d; - uint32_t m, n, o, p; - uint32_t Fa, Fb; - uint16_t t, u, v; - uint32_t sa; - uint8_t da; - - s = *(src + i); - m = *(mask + i); - d = *(dest + i); - da = d >> A_SHIFT; - - combine_mask_ca (&s, &m); - - sa = m; - - switch (combine & COMBINE_A) - { - default: - Fa = 0; - break; - - case COMBINE_A_OUT: - m = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> 0), da); - n = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT; - o = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT; - p = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT; - Fa = m | n | o | p; - break; - - case COMBINE_A_IN: - m = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> 0), da); - n = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT; - o = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT; - p = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT; - Fa = m | n | o | p; - break; - - case COMBINE_A: - Fa = ~0; - break; - } - - switch (combine & COMBINE_B) - { - default: - Fb = 0; - break; - - case COMBINE_B_OUT: - m = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> 0)); - n = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT; - o = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT; - p = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT; - Fb = m | n | o | p; - break; - - case COMBINE_B_IN: - m = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> 0)); - n = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT; - o = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT; - p = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT; - Fb = m | n | o | p; - break; - - case COMBINE_B: - Fb = ~0; - break; - } - m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v); - n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v); - o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v); - p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v); - - s = m | n | o | p; - - *(dest + i) = s; - } -} - -static void -combine_conjoint_over_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER); -} - -static void -combine_conjoint_over_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER); -} - -static void -combine_conjoint_in_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN); -} - -static void -combine_conjoint_in_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN); -} - -static void -combine_conjoint_out_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT); -} - -static void -combine_conjoint_out_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT); -} - -static void -combine_conjoint_atop_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP); -} - -static void -combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP); -} - -static void -combine_conjoint_xor_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR); -} - void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp) { @@ -2471,51 +1153,15 @@ _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp) imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u; imp->combine_32[PIXMAN_OP_XOR] = combine_xor_u; imp->combine_32[PIXMAN_OP_ADD] = combine_add_u; - imp->combine_32[PIXMAN_OP_SATURATE] = combine_saturate_u; - - /* Disjoint, unified */ - imp->combine_32[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear; - imp->combine_32[PIXMAN_OP_DISJOINT_SRC] = combine_src_u; - imp->combine_32[PIXMAN_OP_DISJOINT_DST] = combine_dst; - imp->combine_32[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u; - imp->combine_32[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u; - imp->combine_32[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u; - imp->combine_32[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u; - imp->combine_32[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u; - imp->combine_32[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u; - imp->combine_32[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u; - imp->combine_32[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u; - imp->combine_32[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u; - - /* Conjoint, unified */ - imp->combine_32[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear; - imp->combine_32[PIXMAN_OP_CONJOINT_SRC] = combine_src_u; - imp->combine_32[PIXMAN_OP_CONJOINT_DST] = combine_dst; - imp->combine_32[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u; - imp->combine_32[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u; - imp->combine_32[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u; - imp->combine_32[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u; - imp->combine_32[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u; - imp->combine_32[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u; - imp->combine_32[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u; - imp->combine_32[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u; - imp->combine_32[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u; imp->combine_32[PIXMAN_OP_MULTIPLY] = combine_multiply_u; imp->combine_32[PIXMAN_OP_SCREEN] = combine_screen_u; imp->combine_32[PIXMAN_OP_OVERLAY] = combine_overlay_u; imp->combine_32[PIXMAN_OP_DARKEN] = combine_darken_u; imp->combine_32[PIXMAN_OP_LIGHTEN] = combine_lighten_u; - imp->combine_32[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u; - imp->combine_32[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u; imp->combine_32[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u; - imp->combine_32[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u; imp->combine_32[PIXMAN_OP_DIFFERENCE] = combine_difference_u; imp->combine_32[PIXMAN_OP_EXCLUSION] = combine_exclusion_u; - imp->combine_32[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u; - imp->combine_32[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u; - imp->combine_32[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u; - imp->combine_32[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u; /* Component alpha combiners */ imp->combine_32_ca[PIXMAN_OP_CLEAR] = combine_clear_ca; @@ -2531,51 +1177,13 @@ _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp) imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca; imp->combine_32_ca[PIXMAN_OP_XOR] = combine_xor_ca; imp->combine_32_ca[PIXMAN_OP_ADD] = combine_add_ca; - imp->combine_32_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca; - - /* Disjoint CA */ - imp->combine_32_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca; - - /* Conjoint CA */ - imp->combine_32_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca; imp->combine_32_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca; imp->combine_32_ca[PIXMAN_OP_SCREEN] = combine_screen_ca; imp->combine_32_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca; imp->combine_32_ca[PIXMAN_OP_DARKEN] = combine_darken_ca; imp->combine_32_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca; - imp->combine_32_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca; - imp->combine_32_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca; imp->combine_32_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca; - imp->combine_32_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca; imp->combine_32_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca; imp->combine_32_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca; - - /* It is not clear that these make sense, so make them noops for now */ - imp->combine_32_ca[PIXMAN_OP_HSL_HUE] = combine_dst; - imp->combine_32_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst; - imp->combine_32_ca[PIXMAN_OP_HSL_COLOR] = combine_dst; - imp->combine_32_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst; } diff --git a/pixman/pixman/pixman-general.c b/pixman/pixman/pixman-general.c index 8bce7c006..7cdea2956 100644 --- a/pixman/pixman/pixman-general.c +++ b/pixman/pixman/pixman-general.c @@ -109,6 +109,20 @@ static const op_info_t op_flags[PIXMAN_N_OPERATORS] = #define SCANLINE_BUFFER_LENGTH 8192 +static pixman_bool_t +operator_needs_division (pixman_op_t op) +{ + static const uint8_t needs_division[] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* SATURATE */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* DISJOINT */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* CONJOINT */ + 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, /* blend ops */ + }; + + return needs_division[op]; +} + static void general_composite_rect (pixman_implementation_t *imp, pixman_composite_info_t *info) @@ -124,9 +138,10 @@ general_composite_rect (pixman_implementation_t *imp, int Bpp; int i; - if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) && - (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) && - (dest_image->common.flags & FAST_PATH_NARROW_FORMAT)) + if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) && + (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) && + (dest_image->common.flags & FAST_PATH_NARROW_FORMAT) && + !(operator_needs_division (op))) { width_flag = ITER_NARROW; Bpp = 4; diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources index 2ae5d9f8d..9b520ec42 100644 --- a/pixman/test/Makefile.sources +++ b/pixman/test/Makefile.sources @@ -27,6 +27,7 @@ TESTPROGRAMS = \ scaling-test \ affine-test \ composite \ + tolerance-test \ $(NULL) # Other programs diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c index df8235841..026f4b006 100644 --- a/pixman/test/blitters-test.c +++ b/pixman/test/blitters-test.c @@ -122,6 +122,15 @@ static pixman_op_t op_list[] = { PIXMAN_OP_ATOP_REVERSE, PIXMAN_OP_XOR, PIXMAN_OP_ADD, + PIXMAN_OP_MULTIPLY, + PIXMAN_OP_SCREEN, + PIXMAN_OP_OVERLAY, + PIXMAN_OP_DARKEN, + PIXMAN_OP_LIGHTEN, + PIXMAN_OP_HARD_LIGHT, + PIXMAN_OP_DIFFERENCE, + PIXMAN_OP_EXCLUSION, +#if 0 /* these use floating point math and are not always bitexact on different platforms */ PIXMAN_OP_SATURATE, PIXMAN_OP_DISJOINT_CLEAR, PIXMAN_OP_DISJOINT_SRC, @@ -147,17 +156,8 @@ static pixman_op_t op_list[] = { PIXMAN_OP_CONJOINT_ATOP, PIXMAN_OP_CONJOINT_ATOP_REVERSE, PIXMAN_OP_CONJOINT_XOR, - PIXMAN_OP_MULTIPLY, - PIXMAN_OP_SCREEN, - PIXMAN_OP_OVERLAY, - PIXMAN_OP_DARKEN, - PIXMAN_OP_LIGHTEN, PIXMAN_OP_COLOR_DODGE, PIXMAN_OP_COLOR_BURN, - PIXMAN_OP_HARD_LIGHT, - PIXMAN_OP_DIFFERENCE, - PIXMAN_OP_EXCLUSION, -#if 0 /* these use floating point math and are not always bitexact on different platforms */ PIXMAN_OP_SOFT_LIGHT, PIXMAN_OP_HSL_HUE, PIXMAN_OP_HSL_SATURATION, @@ -394,6 +394,6 @@ main (int argc, const char *argv[]) } return fuzzer_test_main("blitters", 2000000, - 0x63B4E3F3, + 0xCC21DDF0, test_composite, argc, argv); } diff --git a/pixman/test/check-formats.c b/pixman/test/check-formats.c index 7edc198c1..8eb263b77 100644 --- a/pixman/test/check-formats.c +++ b/pixman/test/check-formats.c @@ -146,6 +146,22 @@ static const pixman_op_t op_list[] = PIXMAN_OP_CONJOINT_ATOP, PIXMAN_OP_CONJOINT_ATOP_REVERSE, PIXMAN_OP_CONJOINT_XOR, + + PIXMAN_OP_MULTIPLY, + PIXMAN_OP_SCREEN, + PIXMAN_OP_OVERLAY, + PIXMAN_OP_DARKEN, + PIXMAN_OP_LIGHTEN, + PIXMAN_OP_COLOR_DODGE, + PIXMAN_OP_COLOR_BURN, + PIXMAN_OP_HARD_LIGHT, + PIXMAN_OP_SOFT_LIGHT, + PIXMAN_OP_DIFFERENCE, + PIXMAN_OP_EXCLUSION, + PIXMAN_OP_HSL_HUE, + PIXMAN_OP_HSL_SATURATION, + PIXMAN_OP_HSL_COLOR, + PIXMAN_OP_HSL_LUMINOSITY }; static const pixman_format_code_t format_list[] = diff --git a/pixman/test/pixel-test.c b/pixman/test/pixel-test.c index 8c525d202..7dc0eff3f 100644 --- a/pixman/test/pixel-test.c +++ b/pixman/test/pixel-test.c @@ -33,68 +33,2764 @@ struct pixel_combination_t pixman_op_t op; pixman_format_code_t src_format; uint32_t src_pixel; + pixman_format_code_t mask_format; + uint32_t mask_pixel; pixman_format_code_t dest_format; uint32_t dest_pixel; }; static const pixel_combination_t regressions[] = { + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffc3ff, + PIXMAN_a8, 0x7b, + PIXMAN_a8r8g8b8, 0xff00c300, + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb5, + PIXMAN_a4r4g4b4, 0xe3ff, + PIXMAN_a2r2g2b2, 0x2e + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa6, + PIXMAN_a8r8g8b8, 0x2b00ff00, + PIXMAN_a4r4g4b4, 0x7e + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x27000013, + PIXMAN_a2r2g2b2, 0x80, + PIXMAN_a4r4g4b4, 0x9d + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xe6f7, + PIXMAN_a2r2g2b2, 0xad, + PIXMAN_a4r4g4b4, 0x71 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0xff4f70ff, + PIXMAN_r5g6b5, 0xb828, + PIXMAN_a8r8g8b8, 0xcac400 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa9, + PIXMAN_a4r4g4b4, 0x41c2, + PIXMAN_a8r8g8b8, 0xffff2b + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x89, + PIXMAN_a8r8g8b8, 0x977cff61, + PIXMAN_a4r4g4b4, 0x36 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x81, + PIXMAN_r5g6b5, 0x6f9e, + PIXMAN_a4r4g4b4, 0x1eb + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb5, + PIXMAN_a4r4g4b4, 0xe247, + PIXMAN_a8r8g8b8, 0xffbaff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x97, + PIXMAN_a2r2g2b2, 0x9d, + PIXMAN_a2r2g2b2, 0x21 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb4, + PIXMAN_a2r2g2b2, 0x90, + PIXMAN_a8r8g8b8, 0xc0fd5c + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0xdf00ff70, + PIXMAN_a8r8g8b8, 0x2597ff27, + PIXMAN_a4r4g4b4, 0xf3 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb7, + PIXMAN_r3g3b2, 0xb1, + PIXMAN_a8r8g8b8, 0x9f4bcc + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xf39e, + PIXMAN_r5g6b5, 0x34, + PIXMAN_a8r8g8b8, 0xf6ae00 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x3aff1dff, + PIXMAN_a2r2g2b2, 0x64, + PIXMAN_a8r8g8b8, 0x94ffb4 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa4, + PIXMAN_a2r2g2b2, 0x8a, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa5, + PIXMAN_a4r4g4b4, 0x1a, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb4, + PIXMAN_a2r2g2b2, 0xca, + PIXMAN_a4r4g4b4, 0x7b + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xbd, + PIXMAN_a4r4g4b4, 0xff37, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x96, + PIXMAN_a2r2g2b2, 0xbb, + PIXMAN_a8r8g8b8, 0x96ffff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x89, + PIXMAN_r3g3b2, 0x92, + PIXMAN_a4r4g4b4, 0xa8c + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xa95b, + PIXMAN_a2r2g2b2, 0x68, + PIXMAN_a8r8g8b8, 0x38ff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x90, + PIXMAN_a8r8g8b8, 0x53bd00ef, + PIXMAN_a8r8g8b8, 0xff0003 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1f5ffff, + PIXMAN_r3g3b2, 0x22, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x10000b6, + PIXMAN_a8r8g8b8, 0x9645, + PIXMAN_r5g6b5, 0x6 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x172ff00, + PIXMAN_a4r4g4b4, 0xff61, + PIXMAN_r3g3b2, 0xc + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x281ffc8, + PIXMAN_r5g6b5, 0x39b8, + PIXMAN_r5g6b5, 0x13 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100a2ff, + PIXMAN_a4r4g4b4, 0x6500, + PIXMAN_a2r2g2b2, 0x5 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff51, + PIXMAN_r5g6b5, 0x52ff, + PIXMAN_a2r2g2b2, 0x14 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x150d500, + PIXMAN_a8r8g8b8, 0x6200b7ff, + PIXMAN_a8r8g8b8, 0x1f5200 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2a9a700, + PIXMAN_a8r8g8b8, 0xf7003400, + PIXMAN_a8r8g8b8, 0x2200 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x200ffff, + PIXMAN_r5g6b5, 0x81ff, + PIXMAN_r5g6b5, 0x1f + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ff00ff, + PIXMAN_r5g6b5, 0x3f00, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3ff1aa4, + PIXMAN_a4r4g4b4, 0x2200, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x280ff2c, + PIXMAN_r3g3b2, 0xc6, + PIXMAN_a8r8g8b8, 0xfdfd44fe + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x13aff1d, + PIXMAN_a2r2g2b2, 0x4b, + PIXMAN_r5g6b5, 0x12a1 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2ffff88, + PIXMAN_a8r8g8b8, 0xff3a49, + PIXMAN_r5g6b5, 0xf7df + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1009700, + PIXMAN_a2r2g2b2, 0x56, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1aacbff, + PIXMAN_a4r4g4b4, 0x84, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x100b1ff, + PIXMAN_a2r2g2b2, 0xf5, + PIXMAN_a8r8g8b8, 0xfea89cff + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_r5g6b5, 0x6800, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x10064ff, + PIXMAN_r3g3b2, 0x61, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1bb00ff, + PIXMAN_r5g6b5, 0x76b5, + PIXMAN_a4r4g4b4, 0x500 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ffff41, + PIXMAN_r5g6b5, 0x7100, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ff1231, + PIXMAN_a8r8g8b8, 0x381089, + PIXMAN_r5g6b5, 0x38a5 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x16e5c49, + PIXMAN_a8r8g8b8, 0x4dfa3694, + PIXMAN_a8r8g8b8, 0x211c16 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x134ff62, + PIXMAN_a2r2g2b2, 0x14, + PIXMAN_r3g3b2, 0x8 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x300ffeb, + PIXMAN_r3g3b2, 0xc7, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x3ff8bff, + PIXMAN_r3g3b2, 0x3e, + PIXMAN_a8r8g8b8, 0x3008baa + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_a4r4g4b4, 0x3466, + PIXMAN_a4r4g4b4, 0x406 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ddc027, + PIXMAN_a4r4g4b4, 0x7d00, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x2ffff00, + PIXMAN_a8r8g8b8, 0xc92cfb52, + PIXMAN_a4r4g4b4, 0x200 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ff116a, + PIXMAN_a4r4g4b4, 0x6000, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r5g6b5, 0x2f95, + PIXMAN_r5g6b5, 0x795 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffff00, + PIXMAN_a4r4g4b4, 0x354a, + PIXMAN_r5g6b5, 0x3180 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1d7ff00, + PIXMAN_a4r4g4b4, 0xd6ff, + PIXMAN_a8r8g8b8, 0xffff0700 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1bc5db7, + PIXMAN_r5g6b5, 0x944f, + PIXMAN_a4r4g4b4, 0xff05 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x185ffd9, + PIXMAN_a2r2g2b2, 0x9c, + PIXMAN_r5g6b5, 0x3c07 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1fa7f61, + PIXMAN_a8r8g8b8, 0xff31ff00, + PIXMAN_r3g3b2, 0xd2 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1c4ff00, + PIXMAN_r3g3b2, 0xb, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ff00ff, + PIXMAN_a8r8g8b8, 0x3f3caeda, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_r5g6b5, 0xff, + PIXMAN_r5g6b5, 0xe0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff68ff, + PIXMAN_a4r4g4b4, 0x8046, + PIXMAN_r5g6b5, 0xec + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100ff28, + PIXMAN_a8r8g8b8, 0x4c00, + PIXMAN_r5g6b5, 0x260 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_a4r4g4b4, 0xd92a, + PIXMAN_a8r8g8b8, 0x2200 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100289a, + PIXMAN_a8r8g8b8, 0x74ffb8ff, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1baff00, + PIXMAN_r5g6b5, 0x4e9d, + PIXMAN_r5g6b5, 0x3000 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1fcffad, + PIXMAN_r5g6b5, 0x42d7, + PIXMAN_a8r8g8b8, 0x1c6ffe5 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x183ff00, + PIXMAN_r3g3b2, 0x7e, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x2ff0076, + PIXMAN_a8r8g8b8, 0x2a0000, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3d8bbff, + PIXMAN_r5g6b5, 0x6900, + PIXMAN_a8r8g8b8, 0x35b0000 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x14f00ff, + PIXMAN_r5g6b5, 0xd48, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x28c72df, + PIXMAN_a8r8g8b8, 0xff5cff31, + PIXMAN_a4r4g4b4, 0x2 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffffff, + PIXMAN_a8r8g8b8, 0xffad8020, + PIXMAN_r5g6b5, 0x4 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_a2r2g2b2, 0x76, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1005d00, + PIXMAN_r5g6b5, 0x7b04, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x3cdfc3e, + PIXMAN_a8r8g8b8, 0x69ec21d3, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x200ffff, + PIXMAN_r5g6b5, 0x30ff, + PIXMAN_r5g6b5, 0x60ff + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x532fff4, + PIXMAN_r5g6b5, 0xcb, + PIXMAN_r5g6b5, 0xd9a1 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r3g3b2, 0x5f, + PIXMAN_a2r2g2b2, 0x10 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_a8r8g8b8, 0xffd60052, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ff6491, + PIXMAN_a8r8g8b8, 0x1e53ff00, + PIXMAN_r5g6b5, 0x1862 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_r3g3b2, 0xc7, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x29d0fff, + PIXMAN_a4r4g4b4, 0x25ff, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x141760a, + PIXMAN_a4r4g4b4, 0x7ec2, + PIXMAN_a4r4g4b4, 0x130 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1abedff, + PIXMAN_a8r8g8b8, 0x75520068, + PIXMAN_r3g3b2, 0x87 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_a8r8g8b8, 0xff00e652, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x16006075, + PIXMAN_r5g6b5, 0xc00, + PIXMAN_a8r8g8b8, 0x27f0900 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x200ff00, + PIXMAN_a8r8g8b8, 0xd1b83f57, + PIXMAN_a4r4g4b4, 0xff75 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x14000c4, + PIXMAN_a4r4g4b4, 0x96, + PIXMAN_a2r2g2b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff00d1, + PIXMAN_r3g3b2, 0x79, + PIXMAN_a2r2g2b2, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff00dc, + PIXMAN_a4r4g4b4, 0xc5ff, + PIXMAN_a2r2g2b2, 0x10 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffb2, + PIXMAN_a8r8g8b8, 0x4cff5700, + PIXMAN_r3g3b2, 0x48 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1327482, + PIXMAN_a8r8g8b8, 0x247ff, + PIXMAN_a8r8g8b8, 0x82 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1d0ff00, + PIXMAN_r3g3b2, 0xc9, + PIXMAN_r5g6b5, 0x240 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x13d35ff, + PIXMAN_a2r2g2b2, 0x6d, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffc6b2, + PIXMAN_a8r8g8b8, 0x5abe8e3c, + PIXMAN_r5g6b5, 0x5a27 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x15700ff, + PIXMAN_r3g3b2, 0xdd, + PIXMAN_a8r8g8b8, 0x55 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff11ff, + PIXMAN_r3g3b2, 0x30, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_a2r2g2b2, 0x6d, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1421d5f, + PIXMAN_a4r4g4b4, 0xff85, + PIXMAN_a8r8g8b8, 0x1420f00 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1d2ffff, + PIXMAN_r5g6b5, 0xfc, + PIXMAN_r5g6b5, 0x1c + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffff42, + PIXMAN_a4r4g4b4, 0x7100, + PIXMAN_a4r4g4b4, 0x771 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x25ae3d4, + PIXMAN_a8r8g8b8, 0x39ffc99a, + PIXMAN_a8r8g8b8, 0x14332f + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0643, + PIXMAN_a8r8g8b8, 0x4c000000, + PIXMAN_r5g6b5, 0x4802 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1966a00, + PIXMAN_r3g3b2, 0x46, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x387ff59, + PIXMAN_r5g6b5, 0x512c, + PIXMAN_r5g6b5, 0x120 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1f7ffb0, + PIXMAN_r5g6b5, 0x63b8, + PIXMAN_a8r8g8b8, 0x1000089 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x185841c, + PIXMAN_a2r2g2b2, 0x5c, + PIXMAN_a8r8g8b8, 0x8400 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffc3ff, + PIXMAN_a8r8g8b8, 0xff7b, + PIXMAN_a8r8g8b8, 0xff00c300 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff7500, + PIXMAN_a2r2g2b2, 0x47, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1002361, + PIXMAN_a2r2g2b2, 0x7e, + PIXMAN_r5g6b5, 0x64 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x10000b6, + PIXMAN_a8r8g8b8, 0x59004463, + PIXMAN_a4r4g4b4, 0xffa7 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff5a49, + PIXMAN_a8r8g8b8, 0xff3fff2b, + PIXMAN_a8r8g8b8, 0x13f000c + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x3ffecfc, + PIXMAN_r3g3b2, 0x3c, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1630044, + PIXMAN_a2r2g2b2, 0x63, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1d2ff58, + PIXMAN_a8r8g8b8, 0x8f77ff, + PIXMAN_a4r4g4b4, 0x705 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x14dffff, + PIXMAN_a2r2g2b2, 0x9a, + PIXMAN_a8r8g8b8, 0x1a0000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ff92, + PIXMAN_a4r4g4b4, 0x540c, + PIXMAN_r5g6b5, 0x2a6 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_a4r4g4b4, 0xddd5, + PIXMAN_a4r4g4b4, 0xdd0 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r5g6b5, 0xff8c, + PIXMAN_a4r4g4b4, 0xff0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r3g3b2, 0x66, + PIXMAN_r5g6b5, 0x7d1f + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_a4r4g4b4, 0xff5b, + PIXMAN_a8r8g8b8, 0x5500 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2ed2dff, + PIXMAN_r5g6b5, 0x7ae7, + PIXMAN_r3g3b2, 0xce + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1b13205, + PIXMAN_a8r8g8b8, 0x35ffff00, + PIXMAN_r5g6b5, 0x2040 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1e60dff, + PIXMAN_a4r4g4b4, 0x760f, + PIXMAN_a2r2g2b2, 0x11 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_a4r4g4b4, 0x3, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a8r8g8b8, 0x6600, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x30000fa, + PIXMAN_a4r4g4b4, 0x23b7, + PIXMAN_a8r8g8b8, 0x21 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r3g3b2, 0x60, + PIXMAN_r3g3b2, 0x60 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3b31b30, + PIXMAN_r3g3b2, 0x2e, + PIXMAN_a8r8g8b8, 0x3000c20 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x160ffff, + PIXMAN_a4r4g4b4, 0xff42, + PIXMAN_r3g3b2, 0xed + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x172ffff, + PIXMAN_a4r4g4b4, 0x5100, + PIXMAN_r3g3b2, 0x29 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x16300ff, + PIXMAN_a4r4g4b4, 0x5007, + PIXMAN_a8r8g8b8, 0x77 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x2ffff3a, + PIXMAN_a8r8g8b8, 0x26640083, + PIXMAN_a4r4g4b4, 0x220 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x106ff60, + PIXMAN_r5g6b5, 0xdce, + PIXMAN_a8r8g8b8, 0x100ba00 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100e7ff, + PIXMAN_r5g6b5, 0xa00, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2b500f1, + PIXMAN_a4r4g4b4, 0x7339, + PIXMAN_a8r8g8b8, 0x1000091 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_a4r4g4b4, 0xc863, + PIXMAN_r5g6b5, 0x6 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1ffffca, + PIXMAN_a8r8g8b8, 0x8b4cf000, + PIXMAN_r3g3b2, 0xd2 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1fffe00, + PIXMAN_r3g3b2, 0x88, + PIXMAN_r3g3b2, 0x8 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x16f0000, + PIXMAN_a2r2g2b2, 0x59, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x377ff43, + PIXMAN_a4r4g4b4, 0x2a, + PIXMAN_a8r8g8b8, 0x2d + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x11dffff, + PIXMAN_r3g3b2, 0xcb, + PIXMAN_r3g3b2, 0x8 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_r5g6b5, 0xbdab, + PIXMAN_a4r4g4b4, 0xbb0 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff3343, + PIXMAN_a8r8g8b8, 0x7a00ffff, + PIXMAN_a2r2g2b2, 0xd + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ebff4b, + PIXMAN_r3g3b2, 0x26, + PIXMAN_r3g3b2, 0x24 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2c1b3ff, + PIXMAN_a8r8g8b8, 0x3000152a, + PIXMAN_r3g3b2, 0x24 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1a7ffff, + PIXMAN_r3g3b2, 0x9, + PIXMAN_r5g6b5, 0x24a + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x4ff00ec, + PIXMAN_a8r8g8b8, 0x1da4961e, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff25ff, + PIXMAN_a8r8g8b8, 0x64b0ff00, + PIXMAN_r5g6b5, 0x606c + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1fd62ff, + PIXMAN_a4r4g4b4, 0x76b1, + PIXMAN_r5g6b5, 0x716e + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x194ffde, + PIXMAN_r5g6b5, 0x47ff, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x108ffff, + PIXMAN_a8r8g8b8, 0xffffff66, + PIXMAN_r5g6b5, 0xff0c + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x5ffffff, + PIXMAN_r5g6b5, 0xdf, + PIXMAN_r5g6b5, 0xc0 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ad31, + PIXMAN_a2r2g2b2, 0xc5, + PIXMAN_a4r4g4b4, 0x31 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff34, + PIXMAN_a8r8g8b8, 0x6a57c491, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1fffff1, + PIXMAN_r3g3b2, 0xaf, + PIXMAN_r5g6b5, 0xb01e + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff67ff, + PIXMAN_a4r4g4b4, 0x50ff, + PIXMAN_a8r8g8b8, 0x552255 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x11bffff, + PIXMAN_r5g6b5, 0xef0c, + PIXMAN_r5g6b5, 0xc + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x16cf37d, + PIXMAN_a4r4g4b4, 0xc561, + PIXMAN_r5g6b5, 0x2301 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffff9c, + PIXMAN_a4r4g4b4, 0x2700, + PIXMAN_a8r8g8b8, 0xffff + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x200f322, + PIXMAN_a8r8g8b8, 0xff3c7e, + PIXMAN_r5g6b5, 0x2 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1f14a33, + PIXMAN_a8r8g8b8, 0x26cff79, + PIXMAN_r3g3b2, 0xf9 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x11d922c, + PIXMAN_r3g3b2, 0xab, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a2r2g2b2, 0xf5, + PIXMAN_r3g3b2, 0x9 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x18697ff, + PIXMAN_a4r4g4b4, 0x5700, + PIXMAN_r5g6b5, 0xfa6d + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x12000fc, + PIXMAN_a2r2g2b2, 0x41, + PIXMAN_a8r8g8b8, 0xb0054 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x100ccff, + PIXMAN_a4r4g4b4, 0x657e, + PIXMAN_r5g6b5, 0x3b1 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffff1f, + PIXMAN_a2r2g2b2, 0xa6, + PIXMAN_r5g6b5, 0x2a0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x11fff82, + PIXMAN_a4r4g4b4, 0xff94, + PIXMAN_a8r8g8b8, 0x1010123 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x154bd19, + PIXMAN_a4r4g4b4, 0xb600, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_r5g6b5, 0x8e, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x21aff00, + PIXMAN_r5g6b5, 0x71ff, + PIXMAN_r3g3b2, 0xf2 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ad00a7, + PIXMAN_a4r4g4b4, 0x23, + PIXMAN_a8r8g8b8, 0x21 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_r5g6b5, 0xb343, + PIXMAN_r3g3b2, 0xc + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x3ffa500, + PIXMAN_a8r8g8b8, 0x1af5b4, + PIXMAN_a8r8g8b8, 0xff1abc00 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ffff11, + PIXMAN_a8r8g8b8, 0x9f334f, + PIXMAN_a8r8g8b8, 0x9f0005 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x2c75971, + PIXMAN_a4r4g4b4, 0x3900, + PIXMAN_a4r4g4b4, 0x211 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100ff49, + PIXMAN_a8r8g8b8, 0x813dc25e, + PIXMAN_r5g6b5, 0x667d + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_a4r4g4b4, 0x4bff, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x20ebcff, + PIXMAN_r5g6b5, 0xc9ff, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_r5g6b5, 0x51ff, + PIXMAN_r3g3b2, 0x44 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffd158, + PIXMAN_a8r8g8b8, 0x7d88ffce, + PIXMAN_r3g3b2, 0x6c + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1425e21, + PIXMAN_a2r2g2b2, 0xa5, + PIXMAN_r5g6b5, 0xe1 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x14b00ff, + PIXMAN_a8r8g8b8, 0xbe95004b, + PIXMAN_r5g6b5, 0x9 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x14fc0cd, + PIXMAN_a8r8g8b8, 0x2d12b78b, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff8230, + PIXMAN_a2r2g2b2, 0x4c, + PIXMAN_r3g3b2, 0x44 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff31ff, + PIXMAN_a2r2g2b2, 0x14, + PIXMAN_a8r8g8b8, 0x551000 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x17800ff, + PIXMAN_a4r4g4b4, 0x22, + PIXMAN_a8r8g8b8, 0x22 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x14500ff, + PIXMAN_a4r4g4b4, 0x6400, + PIXMAN_r5g6b5, 0xff78 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ff9d, + PIXMAN_r3g3b2, 0xcd, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x3ff00ff, + PIXMAN_a4r4g4b4, 0xf269, + PIXMAN_a4r4g4b4, 0x200 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff28b8, + PIXMAN_a4r4g4b4, 0x33ff, + PIXMAN_r5g6b5, 0x3000 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1006278, + PIXMAN_a8r8g8b8, 0x8a7f18, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffcb00, + PIXMAN_a4r4g4b4, 0x7900, + PIXMAN_a2r2g2b2, 0x14 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x115ff00, + PIXMAN_a8r8g8b8, 0x508d, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x3ff30b5, + PIXMAN_r5g6b5, 0x2e60, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x182fffb, + PIXMAN_r3g3b2, 0x1, + PIXMAN_a8r8g8b8, 0x1000054 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x16fff00, + PIXMAN_r5g6b5, 0x7bc0, + PIXMAN_a8r8g8b8, 0x367900 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1d95dd8, + PIXMAN_a4r4g4b4, 0xfff5, + PIXMAN_r5g6b5, 0xff09 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff3cdc, + PIXMAN_a8r8g8b8, 0x3bda45ff, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x13900f8, + PIXMAN_a8r8g8b8, 0x7e00ffff, + PIXMAN_a4r4g4b4, 0xff00 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x10ea9ff, + PIXMAN_a8r8g8b8, 0xff34ff22, + PIXMAN_r5g6b5, 0xff52 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2002e99, + PIXMAN_a4r4g4b4, 0x3000, + PIXMAN_r5g6b5, 0x43 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_r5g6b5, 0x19ff, + PIXMAN_r3g3b2, 0x3 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_a8r8g8b8, 0xffff4251, + PIXMAN_a2r2g2b2, 0x4 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x121c9ff, + PIXMAN_a4r4g4b4, 0xd2, + PIXMAN_a4r4g4b4, 0x2 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ff4d, + PIXMAN_a2r2g2b2, 0x5e, + PIXMAN_a2r2g2b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x29ab4ff, + PIXMAN_r3g3b2, 0x47, + PIXMAN_a8r8g8b8, 0x1900 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffc1ac, + PIXMAN_a8r8g8b8, 0xee4ed0ac, + PIXMAN_a8r8g8b8, 0x1009d74 + }, + { PIXMAN_OP_CONJOINT_IN_REVERSE, + PIXMAN_a8r8g8b8, 0x269dffdc, + PIXMAN_a8r8g8b8, 0xff0b00e0, + PIXMAN_a8r8g8b8, 0x2a200ff + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffffff, + PIXMAN_a4r4g4b4, 0x3200, + PIXMAN_r3g3b2, 0x24 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100ffed, + PIXMAN_a8r8g8b8, 0x67004eff, + PIXMAN_a2r2g2b2, 0x5 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2fffd6a, + PIXMAN_a8r8g8b8, 0xc9003bff, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x253ff00, + PIXMAN_r5g6b5, 0xff, + PIXMAN_r5g6b5, 0xe0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x13600ad, + PIXMAN_r5g6b5, 0x35ae, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffa8ff, + PIXMAN_a8r8g8b8, 0xff5f00, + PIXMAN_r3g3b2, 0xe0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x10067ff, + PIXMAN_a4r4g4b4, 0x450d, + PIXMAN_a2r2g2b2, 0x1 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1ff01ff, + PIXMAN_r3g3b2, 0x77, + PIXMAN_r5g6b5, 0x6800 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x11da4ff, + PIXMAN_r5g6b5, 0x83c9, + PIXMAN_a4r4g4b4, 0x44 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffd4ff, + PIXMAN_r3g3b2, 0xaa, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_a8r8g8b8, 0x71002a, + PIXMAN_a4r4g4b4, 0x700 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1d7ffff, + PIXMAN_r5g6b5, 0x3696, + PIXMAN_a4r4g4b4, 0x200 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffffc8, + PIXMAN_r5g6b5, 0xe900, + PIXMAN_a8r8g8b8, 0x2000 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff004a, + PIXMAN_r3g3b2, 0x48, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x3ffe969, + PIXMAN_r5g6b5, 0xff, + PIXMAN_r5g6b5, 0xc0 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x300ff73, + PIXMAN_r5g6b5, 0xff, + PIXMAN_a8r8g8b8, 0x3000073 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff93ff, + PIXMAN_a8r8g8b8, 0x61fc7d2b, + PIXMAN_a4r4g4b4, 0x2 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x11bffff, + PIXMAN_a4r4g4b4, 0xffb4, + PIXMAN_r5g6b5, 0x8 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x1e9e100, + PIXMAN_a2r2g2b2, 0x56, + PIXMAN_a2r2g2b2, 0x14 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x3ffb656, + PIXMAN_r3g3b2, 0x4, + PIXMAN_a4r4g4b4, 0xff99 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_r3g3b2, 0x68, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1006dff, + PIXMAN_a2r2g2b2, 0x5d, + PIXMAN_a8r8g8b8, 0xff00ff55 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x11c00cb, + PIXMAN_a2r2g2b2, 0x44, + PIXMAN_a4r4g4b4, 0x4 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1d0ff86, + PIXMAN_r3g3b2, 0x5c, + PIXMAN_a8r8g8b8, 0x3c0000 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2f25fff, + PIXMAN_r3g3b2, 0x36, + PIXMAN_a8r8g8b8, 0x2a444aa + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x134af85, + PIXMAN_r3g3b2, 0x29, + PIXMAN_r5g6b5, 0xf300 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x13398af, + PIXMAN_r3g3b2, 0xa5, + PIXMAN_a4r4g4b4, 0x13 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff57ff, + PIXMAN_a4r4g4b4, 0x252c, + PIXMAN_r3g3b2, 0x40 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x115ffff, + PIXMAN_r5g6b5, 0xffe3, + PIXMAN_r5g6b5, 0x3303 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffff00, + PIXMAN_r5g6b5, 0x6300, + PIXMAN_r3g3b2, 0x6c + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x4ccff9c, + PIXMAN_r5g6b5, 0xcc, + PIXMAN_a8r8g8b8, 0x400003d + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffc6dd, + PIXMAN_r5g6b5, 0x9bff, + PIXMAN_r5g6b5, 0x5bff + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x14fff95, + PIXMAN_r3g3b2, 0x46, + PIXMAN_a8r8g8b8, 0x1000063 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1e6b700, + PIXMAN_r5g6b5, 0xc1ff, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffff54, + PIXMAN_a8r8g8b8, 0x2e00ff, + PIXMAN_r5g6b5, 0x2800 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3ffffff, + PIXMAN_r5g6b5, 0xff, + PIXMAN_r5g6b5, 0xe0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1003550, + PIXMAN_r5g6b5, 0xffcc, + PIXMAN_r5g6b5, 0x1e0 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffff74, + PIXMAN_r3g3b2, 0x28, + PIXMAN_a8r8g8b8, 0xfe2f49d7 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1e35100, + PIXMAN_r3g3b2, 0x57, + PIXMAN_r5g6b5, 0x4000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x268ffa3, + PIXMAN_a4r4g4b4, 0x30, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x35700f8, + PIXMAN_r5g6b5, 0xa4, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x3ce1dff, + PIXMAN_r5g6b5, 0x2a5e, + PIXMAN_a8r8g8b8, 0x210000 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x494a7ff, + PIXMAN_a8r8g8b8, 0x1bffe400, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x10026d9, + PIXMAN_a8r8g8b8, 0xec00621f, + PIXMAN_r5g6b5, 0x63 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ff99, + PIXMAN_a8r8g8b8, 0xf334ff, + PIXMAN_a4r4g4b4, 0x30 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffc200, + PIXMAN_a8r8g8b8, 0x1e0000ff, + PIXMAN_a8r8g8b8, 0x1e1700 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_r3g3b2, 0x4b, + PIXMAN_r5g6b5, 0x4818 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2e800ff, + PIXMAN_a4r4g4b4, 0xd3, + PIXMAN_a4r4g4b4, 0xec + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x19a001f, + PIXMAN_r3g3b2, 0x76, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1cb00c3, + PIXMAN_a4r4g4b4, 0x5cff, + PIXMAN_r5g6b5, 0x4008 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_r3g3b2, 0x2a, + PIXMAN_r5g6b5, 0xc5fb + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_a8r8g8b8, 0xea005a88, + PIXMAN_r3g3b2, 0xb3 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100ffea, + PIXMAN_a4r4g4b4, 0x54eb, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x179ffff, + PIXMAN_r3g3b2, 0xa4, + PIXMAN_a8r8g8b8, 0x2400 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x17ad226, + PIXMAN_r3g3b2, 0xa4, + PIXMAN_r5g6b5, 0xe0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ff01, + PIXMAN_a2r2g2b2, 0x25, + PIXMAN_a4r4g4b4, 0x50 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x20000ff, + PIXMAN_a8r8g8b8, 0x2b00c127, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x200ff96, + PIXMAN_a4r4g4b4, 0x2300, + PIXMAN_r3g3b2, 0x6 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x200ffff, + PIXMAN_r3g3b2, 0x87, + PIXMAN_r5g6b5, 0x5bc8 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1fffff2, + PIXMAN_r3g3b2, 0x7e, + PIXMAN_a2r2g2b2, 0xe + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1ff8b00, + PIXMAN_a4r4g4b4, 0xd500, + PIXMAN_r3g3b2, 0x40 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffffff, + PIXMAN_a8r8g8b8, 0x1bff38, + PIXMAN_a4r4g4b4, 0xf0 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x158ff39, + PIXMAN_a4r4g4b4, 0x75dd, + PIXMAN_a8r8g8b8, 0xdd31 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1009b70, + PIXMAN_a4r4g4b4, 0xff40, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x12fb43f, + PIXMAN_a4r4g4b4, 0x69ff, + PIXMAN_a2r2g2b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff95, + PIXMAN_a2r2g2b2, 0x84, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x200d188, + PIXMAN_r5g6b5, 0xde6, + PIXMAN_r5g6b5, 0x3 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2c70000, + PIXMAN_r5g6b5, 0x24fa, + PIXMAN_a8r8g8b8, 0x21a0000 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100ff24, + PIXMAN_a4r4g4b4, 0x835, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x10000cd, + PIXMAN_a2r2g2b2, 0x7f, + PIXMAN_a2r2g2b2, 0x1 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x379ffff, + PIXMAN_a8r8g8b8, 0x23ffff00, + PIXMAN_r5g6b5, 0x4eda + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x172e3ff, + PIXMAN_r3g3b2, 0xa6, + PIXMAN_r5g6b5, 0x100 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100f5ad, + PIXMAN_a4r4g4b4, 0x7908, + PIXMAN_a2r2g2b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100fff9, + PIXMAN_a2r2g2b2, 0xf1, + PIXMAN_r3g3b2, 0x1 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1abff00, + PIXMAN_r5g6b5, 0x31ff, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x112ffd1, + PIXMAN_r3g3b2, 0x9, + PIXMAN_a2r2g2b2, 0xdd + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ffbf, + PIXMAN_r3g3b2, 0x2c, + PIXMAN_a4r4g4b4, 0x60 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffb7ff, + PIXMAN_r3g3b2, 0x6b, + PIXMAN_a4r4g4b4, 0x630 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x20005ff, + PIXMAN_a4r4g4b4, 0x8462, + PIXMAN_r5g6b5, 0xb1e8 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff5b00, + PIXMAN_r5g6b5, 0x70ff, + PIXMAN_r3g3b2, 0x60 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffffc3, + PIXMAN_r3g3b2, 0x39, + PIXMAN_a8r8g8b8, 0x200db41 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x306ffff, + PIXMAN_a8r8g8b8, 0xdcffff1f, + PIXMAN_a8r8g8b8, 0x306ff00 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x193daff, + PIXMAN_a8r8g8b8, 0x69000000, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x2a200ff, + PIXMAN_a8r8g8b8, 0x183aff00, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100f1a5, + PIXMAN_a8r8g8b8, 0xb5fc21ff, + PIXMAN_r5g6b5, 0xfe00 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1630019, + PIXMAN_a8r8g8b8, 0x6affc400, + PIXMAN_r5g6b5, 0x56ff + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff8bc2, + PIXMAN_r3g3b2, 0xee, + PIXMAN_r5g6b5, 0x1c0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x260ffff, + PIXMAN_a4r4g4b4, 0x3f00, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x169ffed, + PIXMAN_a8r8g8b8, 0xffffff3f, + PIXMAN_a8r8g8b8, 0x169ff00 + }, + { PIXMAN_OP_CONJOINT_XOR, + PIXMAN_a8r8g8b8, 0x154c181, + PIXMAN_a4r4g4b4, 0x5100, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1e09c00, + PIXMAN_r5g6b5, 0xca00, + PIXMAN_a4r4g4b4, 0xb00 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff8dff, + PIXMAN_a8r8g8b8, 0x610038ff, + PIXMAN_a8r8g8b8, 0x1001f02 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1e400ff, + PIXMAN_a4r4g4b4, 0x66bd, + PIXMAN_r3g3b2, 0x68 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x25362ff, + PIXMAN_a4r4g4b4, 0x31ff, + PIXMAN_a8r8g8b8, 0x111433 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3ad0039, + PIXMAN_r3g3b2, 0x26, + PIXMAN_a8r8g8b8, 0x3000026 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2e442ef, + PIXMAN_r3g3b2, 0x32, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1720000, + PIXMAN_a8r8g8b8, 0x55fdea00, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x14bb0d7, + PIXMAN_a8r8g8b8, 0x7fffff47, + PIXMAN_a2r2g2b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x13dffff, + PIXMAN_a8r8g8b8, 0xa3860672, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x120495a, + PIXMAN_a4r4g4b4, 0x407e, + PIXMAN_a8r8g8b8, 0x54 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff8fff, + PIXMAN_a2r2g2b2, 0x29, + PIXMAN_r5g6b5, 0xa + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100a31a, + PIXMAN_a4r4g4b4, 0xde4c, + PIXMAN_a4r4g4b4, 0x1 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1d4008c, + PIXMAN_r3g3b2, 0x79, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_a4r4g4b4, 0x7de4, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1b27e62, + PIXMAN_a4r4g4b4, 0x7941, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x300ff00, + PIXMAN_a8r8g8b8, 0xfcff255e, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x2ff00b8, + PIXMAN_a8r8g8b8, 0x19ff718d, + PIXMAN_r5g6b5, 0x1802 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x235ff13, + PIXMAN_a8r8g8b8, 0x34bcd9ff, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1006400, + PIXMAN_a4r4g4b4, 0x7000, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff8bff, + PIXMAN_a4r4g4b4, 0xfff4, + PIXMAN_a4r4g4b4, 0xf80 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x24630ff, + PIXMAN_a8r8g8b8, 0x1f00000b, + PIXMAN_a8r8g8b8, 0x9061f + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff8a00, + PIXMAN_a8r8g8b8, 0x79ffab00, + PIXMAN_r5g6b5, 0x7a00 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x19807ff, + PIXMAN_a4r4g4b4, 0x6794, + PIXMAN_a8r8g8b8, 0xff002e00 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x10000da, + PIXMAN_a4r4g4b4, 0xf864, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffffde, + PIXMAN_a2r2g2b2, 0x94, + PIXMAN_a8r8g8b8, 0x1000000 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x200c800, + PIXMAN_r5g6b5, 0xe9d4, + PIXMAN_a8r8g8b8, 0x2c00 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff00c9, + PIXMAN_r3g3b2, 0x4c, + PIXMAN_r5g6b5, 0x4800 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x122d5ff, + PIXMAN_r5g6b5, 0x418b, + PIXMAN_a4r4g4b4, 0x25 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ffff55, + PIXMAN_a2r2g2b2, 0x1c, + PIXMAN_a8r8g8b8, 0xff00 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x135ffff, + PIXMAN_r5g6b5, 0x39c4, + PIXMAN_r5g6b5, 0xb7 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x100d2c3, + PIXMAN_r3g3b2, 0x2a, + PIXMAN_a8r8g8b8, 0x3c00 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x17268ff, + PIXMAN_a8r8g8b8, 0x7c00ffff, + PIXMAN_r5g6b5, 0x318f + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff00ff, + PIXMAN_r3g3b2, 0x68, + PIXMAN_r3g3b2, 0xb4 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x200ffff, + PIXMAN_r5g6b5, 0xff86, + PIXMAN_a8r8g8b8, 0x200f300 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x18a23ff, + PIXMAN_a2r2g2b2, 0x44, + PIXMAN_a4r4g4b4, 0x205 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x16bff23, + PIXMAN_a8r8g8b8, 0x31fd00ff, + PIXMAN_r3g3b2, 0x7 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x137d1ff, + PIXMAN_a4r4g4b4, 0x56c1, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff5bff, + PIXMAN_a4r4g4b4, 0xfff4, + PIXMAN_a4r4g4b4, 0xf50 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x15c6b00, + PIXMAN_a8r8g8b8, 0x7d008a, + PIXMAN_a4r4g4b4, 0x200 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x12091ff, + PIXMAN_a8r8g8b8, 0xb74cff6b, + PIXMAN_a2r2g2b2, 0x8 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff5bff, + PIXMAN_a8r8g8b8, 0xff6ddce8, + PIXMAN_a2r2g2b2, 0x10 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a4r4g4b4, 0xffb7, + PIXMAN_a4r4g4b4, 0xb0 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x173ffff, + PIXMAN_r5g6b5, 0xff2c, + PIXMAN_a4r4g4b4, 0x6 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x17102ff, + PIXMAN_a8r8g8b8, 0x955bff66, + PIXMAN_a8r8g8b8, 0x280066 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x3c7ff24, + PIXMAN_r5g6b5, 0xc4, + PIXMAN_r5g6b5, 0x163 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100c2a6, + PIXMAN_r5g6b5, 0xa9b9, + PIXMAN_a4r4g4b4, 0x8 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x26049ff, + PIXMAN_a4r4g4b4, 0xb2, + PIXMAN_r5g6b5, 0x8904 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2f100ff, + PIXMAN_r3g3b2, 0x30, + PIXMAN_a8r8g8b8, 0x2220100 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffff88, + PIXMAN_r3g3b2, 0x7e, + PIXMAN_r3g3b2, 0x60 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x153ffab, + PIXMAN_a8r8g8b8, 0xfd10725a, + PIXMAN_r3g3b2, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff00d2, + PIXMAN_r5g6b5, 0xff6b, + PIXMAN_a8r8g8b8, 0x101014a + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x100d965, + PIXMAN_a8r8g8b8, 0xff007b00, + PIXMAN_r3g3b2, 0xc + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ec0000, + PIXMAN_r5g6b5, 0x6fff, + PIXMAN_r5g6b5, 0x6000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x19d59a2, + PIXMAN_a8r8g8b8, 0x4a00ff7a, + PIXMAN_a8r8g8b8, 0x2e1a2f + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1eb0000, + PIXMAN_a4r4g4b4, 0x72bc, + PIXMAN_r5g6b5, 0x1800 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a4r4g4b4, 0xc034, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x195ff15, + PIXMAN_a4r4g4b4, 0xb7b1, + PIXMAN_r5g6b5, 0x4000 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffdf94, + PIXMAN_a4r4g4b4, 0x78, + PIXMAN_r3g3b2, 0xc + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x26f00ff, + PIXMAN_a4r4g4b4, 0xff93, + PIXMAN_r5g6b5, 0x1dd2 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x2ff3fc5, + PIXMAN_r3g3b2, 0x2f, + PIXMAN_a8r8g8b8, 0x240000 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1ff696e, + PIXMAN_a4r4g4b4, 0x22ff, + PIXMAN_r5g6b5, 0x34d + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x10033d9, + PIXMAN_a8r8g8b8, 0x38650000, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffff00, + PIXMAN_a4r4g4b4, 0x2070, + PIXMAN_r5g6b5, 0x2100 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1008746, + PIXMAN_a8r8g8b8, 0xb56971, + PIXMAN_r5g6b5, 0xc25c + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x144d200, + PIXMAN_a4r4g4b4, 0xff42, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1ffffd0, + PIXMAN_r5g6b5, 0x5b00, + PIXMAN_r3g3b2, 0x4c + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x10000ff, + PIXMAN_a8r8g8b8, 0xff006f, + PIXMAN_r5g6b5, 0xd + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x10666ff, + PIXMAN_a4r4g4b4, 0x39b2, + PIXMAN_r5g6b5, 0xa6 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x11a007d, + PIXMAN_r3g3b2, 0xf9, + PIXMAN_a8r8g8b8, 0x11a0000 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1eb90ee, + PIXMAN_r5g6b5, 0xd, + PIXMAN_a2r2g2b2, 0x1 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ff42d5, + PIXMAN_a4r4g4b4, 0x3400, + PIXMAN_r3g3b2, 0x40 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1dfff00, + PIXMAN_a8r8g8b8, 0x3ffff9d2, + PIXMAN_r5g6b5, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff6500, + PIXMAN_a2r2g2b2, 0x56, + PIXMAN_r3g3b2, 0x44 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x119ffe6, + PIXMAN_r3g3b2, 0x8d, + PIXMAN_a4r4g4b4, 0xff00 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x100cd00, + PIXMAN_r5g6b5, 0x33ff, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x569ffd7, + PIXMAN_r5g6b5, 0x8cc, + PIXMAN_r5g6b5, 0xc0 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100876a, + PIXMAN_a8r8g8b8, 0x575447a5, + PIXMAN_r5g6b5, 0x164 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x12d00ff, + PIXMAN_a4r4g4b4, 0x3fff, + PIXMAN_a4r4g4b4, 0x0 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff953b, + PIXMAN_a4r4g4b4, 0x2914, + PIXMAN_r5g6b5, 0x20a1 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffead4, + PIXMAN_a8r8g8b8, 0xff00ea4e, + PIXMAN_r3g3b2, 0x5a + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x1ff6400, + PIXMAN_a2r2g2b2, 0x99, + PIXMAN_r5g6b5, 0xa620 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x17b0084, + PIXMAN_r3g3b2, 0xbd, + PIXMAN_a4r4g4b4, 0x500 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x4f90bbb, + PIXMAN_a8r8g8b8, 0xff00d21f, + PIXMAN_a8r8g8b8, 0xfb00fc4a + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ffbb1d, + PIXMAN_a8r8g8b8, 0x2dff79ff, + PIXMAN_r5g6b5, 0x2c0 + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ffff, + PIXMAN_a2r2g2b2, 0x43, + PIXMAN_a4r4g4b4, 0x6f + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1f000ff, + PIXMAN_a4r4g4b4, 0xb393, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1c60020, + PIXMAN_a8r8g8b8, 0x6bffffff, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1727d00, + PIXMAN_a2r2g2b2, 0x67, + PIXMAN_a4r4g4b4, 0x400 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x14a5194, + PIXMAN_a4r4g4b4, 0xd7ff, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x20003fa, + PIXMAN_a4r4g4b4, 0x24ff, + PIXMAN_a8r8g8b8, 0xffff1550 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1a6ff83, + PIXMAN_a4r4g4b4, 0xf400, + PIXMAN_r5g6b5, 0x2800 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ffcf00, + PIXMAN_r5g6b5, 0x71ff, + PIXMAN_a4r4g4b4, 0x30 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x333ffff, + PIXMAN_a4r4g4b4, 0x2c00, + PIXMAN_r3g3b2, 0x4 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1c2ffe8, + PIXMAN_r5g6b5, 0xc200, + PIXMAN_a8r8g8b8, 0xfeca41ff + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a2r2g2b2, 0x47, + PIXMAN_a8r8g8b8, 0x2ffff00, + PIXMAN_a8r8g8b8, 0x3aa0102 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffeb00, + PIXMAN_a4r4g4b4, 0xb493, + PIXMAN_a4r4g4b4, 0x400 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2afffff, + PIXMAN_r5g6b5, 0xcb, + PIXMAN_r5g6b5, 0xc0 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x183ff00, + PIXMAN_r3g3b2, 0x87, + PIXMAN_r5g6b5, 0xae91 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x3ffff00, + PIXMAN_a4r4g4b4, 0x2ba4, + PIXMAN_r5g6b5, 0x2100 + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x215cbc2, + PIXMAN_a4r4g4b4, 0xafd3, + PIXMAN_a8r8g8b8, 0x115b000 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1853f65, + PIXMAN_a8r8g8b8, 0xc68cdc41, + PIXMAN_r5g6b5, 0x3 + }, + { PIXMAN_OP_CONJOINT_IN, + PIXMAN_a8r8g8b8, 0x3ffff8f, + PIXMAN_a4r4g4b4, 0x8824, + PIXMAN_a4r4g4b4, 0x20 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x28e08e6, + PIXMAN_a8r8g8b8, 0x2cffff31, + PIXMAN_r5g6b5, 0x1805 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x1b500be, + PIXMAN_r5g6b5, 0xd946, + PIXMAN_r5g6b5, 0x9800 + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x133ffb3, + PIXMAN_a2r2g2b2, 0x42, + PIXMAN_a8r8g8b8, 0x11553c + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x21aff81, + PIXMAN_r3g3b2, 0xc7, + PIXMAN_r5g6b5, 0x120 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x12e004f, + PIXMAN_a4r4g4b4, 0xf617, + PIXMAN_a4r4g4b4, 0x102 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x164861f, + PIXMAN_r3g3b2, 0x4e, + PIXMAN_r5g6b5, 0x19c0 + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0eff, + PIXMAN_a8r8g8b8, 0xff5c00aa, + PIXMAN_r5g6b5, 0x5800 + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x1e4c60f, + PIXMAN_a8r8g8b8, 0x38ff0e0c, + PIXMAN_a4r4g4b4, 0xff2a + }, + { PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0000, + PIXMAN_a8r8g8b8, 0x9f3d6700, + PIXMAN_r5g6b5, 0xf3ff + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x205ffd0, + PIXMAN_a8r8g8b8, 0xffc22b3b, + PIXMAN_a8r8g8b8, 0x2040000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x1ff0059, + PIXMAN_r5g6b5, 0x74ff, + PIXMAN_a8r8g8b8, 0x1730101 + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x29affb8, + PIXMAN_r5g6b5, 0xff, + PIXMAN_a8r8g8b8, 0x2d25cff + }, + { PIXMAN_OP_DISJOINT_OUT, + PIXMAN_a8r8g8b8, 0x1ffff8b, + PIXMAN_a4r4g4b4, 0xff7b, + PIXMAN_r5g6b5, 0x3a0 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x2a86ad7, + PIXMAN_a4r4g4b4, 0xdc22, + PIXMAN_a8r8g8b8, 0x2860000 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x3ff00ff, + PIXMAN_r3g3b2, 0x33, + PIXMAN_r5g6b5, 0x2000 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1e50063, + PIXMAN_a8r8g8b8, 0x35ff95d7, + PIXMAN_r3g3b2, 0x20 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x2ffe6ff, + PIXMAN_a8r8g8b8, 0x153ef297, + PIXMAN_r5g6b5, 0x6d2 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x34ffeff, + PIXMAN_a4r4g4b4, 0x2e, + PIXMAN_r5g6b5, 0x1d + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2ffeada, + PIXMAN_r5g6b5, 0xabc6, + PIXMAN_a8r8g8b8, 0xfd15b256 + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x100ff00, + PIXMAN_a8r8g8b8, 0xcff3f32, + PIXMAN_a8r8g8b8, 0x3f00 + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x1e1b0f1, + PIXMAN_a8r8g8b8, 0xff63ff54, + PIXMAN_r3g3b2, 0x5d + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0x2ffff23, + PIXMAN_a8r8g8b8, 0x380094ff, + PIXMAN_r5g6b5, 0x3a4b + }, + { PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_a4r4g4b4, 0x1000, + PIXMAN_r5g6b5, 0xca, + PIXMAN_a8r8g8b8, 0x3434500 + }, + { PIXMAN_OP_DISJOINT_IN, + PIXMAN_a8r8g8b8, 0x195ffe5, + PIXMAN_a4r4g4b4, 0x3a29, + PIXMAN_a8r8g8b8, 0x0 + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a8r8g8b8, 0x139007a, + PIXMAN_a4r4g4b4, 0x4979, + PIXMAN_r5g6b5, 0x84 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa9, + PIXMAN_a4r4g4b4, 0xfa18, + PIXMAN_a8r8g8b8, 0xabff67ff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x94, + PIXMAN_a4r4g4b4, 0x5109, + PIXMAN_a8r8g8b8, 0x3affffff + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r5g6b5, 0xd038, + PIXMAN_r5g6b5, 0xff00, + PIXMAN_r5g6b5, 0xf9a5 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x543128ff, + PIXMAN_a8r8g8b8, 0x7029ff, + PIXMAN_a8r8g8b8, 0x316b1d7 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_r5g6b5, 0x53ff, + PIXMAN_r5g6b5, 0x72ff, + PIXMAN_a8r8g8b8, 0xffffdeff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x5b00002b, + PIXMAN_a4r4g4b4, 0xc3, + PIXMAN_a8r8g8b8, 0x23530be + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0xcefc0041, + PIXMAN_a8r8g8b8, 0xf60d02, + PIXMAN_a8r8g8b8, 0x1f2ffe5 + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_r5g6b5, 0xffdb, + PIXMAN_r5g6b5, 0xc700, + PIXMAN_r5g6b5, 0x654 + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_r5g6b5, 0xffc6, + PIXMAN_r5g6b5, 0xff09, + PIXMAN_r5g6b5, 0xfe58 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x95, + PIXMAN_r5g6b5, 0x1b4a, + PIXMAN_a8r8g8b8, 0xab234cff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x95, + PIXMAN_a4r4g4b4, 0x5e99, + PIXMAN_a8r8g8b8, 0x3b1c1cdd + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r5g6b5, 0x22, + PIXMAN_r5g6b5, 0xd00, + PIXMAN_r5g6b5, 0xfbb1 + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_r5g6b5, 0xffc8, + PIXMAN_a8r8g8b8, 0xa1a3ffff, + PIXMAN_r5g6b5, 0x44a + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0xffff7cff, + PIXMAN_r5g6b5, 0x900, + PIXMAN_a8r8g8b8, 0xffff94ec + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xa7, + PIXMAN_r5g6b5, 0xff, + PIXMAN_a8r8g8b8, 0xaa00cffe + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0x85, + PIXMAN_r5g6b5, 0xffb3, + PIXMAN_a8r8g8b8, 0xaaffff4a + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a8r8g8b8, 0x3500a118, + PIXMAN_a4r4g4b4, 0x9942, + PIXMAN_a8r8g8b8, 0x01ff405e + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xb5, + PIXMAN_x4a4, 0xe, + PIXMAN_a8r8g8b8, 0xffbaff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xe872, + PIXMAN_x2r10g10b10, 0xa648ff00, + PIXMAN_a2r10g10b10, 0x14ff00e8, + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x4d2db34, + PIXMAN_a8, 0x19, + PIXMAN_r5g6b5, 0x9700, + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x2ff0076, + PIXMAN_a8r8g8b8, 0x2a0000, + PIXMAN_r3g3b2, 0x0, + }, + { PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_a8r8g8b8, 0x14f00ff, + PIXMAN_r5g6b5, 0xd48, + PIXMAN_a4r4g4b4, 0x0, + }, + { PIXMAN_OP_CONJOINT_OUT, + PIXMAN_a8r8g8b8, 0x3d8bbff, + PIXMAN_r5g6b5, 0x6900, + PIXMAN_a8r8g8b8, 0x0, + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x2ff00ff, + PIXMAN_a4r4g4b4, 0x2300, + PIXMAN_r3g3b2, 0x0, + }, + { PIXMAN_OP_SATURATE, + PIXMAN_a8r8g8b8, 0x4d2db34, + PIXMAN_a8r8g8b8, 0xff0019ff, + PIXMAN_r5g6b5, 0x9700, + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0x100ac05, + PIXMAN_r3g3b2, 0xef, + PIXMAN_a2r2g2b2, 0xff, + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0xbf, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x7e + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r5g6b5, 0xffff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x33 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a8r8g8b8, 0x84c4ffd7, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xffddff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a8r8g8b8, 0xff6e56, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x20ff1ade + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a4r4g4b4, 0xfe0, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xbdff + }, + { PIXMAN_OP_SCREEN, + PIXMAN_a8r8g8b8, 0x9671ff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x43 + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x39ff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_r5g6b5, 0xffff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x1968 + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a4r4g4b4, 0x4247, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xd8ffff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_r5g6b5, 0xff00, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x79 + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r3g3b2, 0xe0, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x39 + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a8r8g8b8, 0xfff8, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0xff + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_r5g6b5, 0x75fc, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x11ff, + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r3g3b2, 0x52, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0xc627 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0x9f2b, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x4b00e7f5 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0x00dfff5c, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x5e0f, + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_a8r8g8b8, 0xff00121b, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x3776 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_r5g6b5, 0x03e0, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x01003c00, + }, { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 0x0f00c300, + PIXMAN_null, 0x00, PIXMAN_x14r6g6b6, 0x003c0, }, { PIXMAN_OP_DISJOINT_XOR, PIXMAN_a4r4g4b4, 0xd0c0, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x5300ea00, }, { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 0x20c6bf00, + PIXMAN_null, 0x00, PIXMAN_r5g6b5, 0xb9ff }, { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, 0x204ac7ff, + PIXMAN_null, 0x00, PIXMAN_r5g6b5, 0xc1ff }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0xffc3, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x102d00dd }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0x1f00, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x1bdf0c89 }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0xf9d2, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x1076bcf7 }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0x00c3, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x1bfe9ae5 }, { PIXMAN_OP_OVER_REVERSE, PIXMAN_r5g6b5, 0x09ff, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x0b00c16c }, { PIXMAN_OP_DISJOINT_ATOP, PIXMAN_a2r2g2b2, 0xbc, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x9efff1ff }, { PIXMAN_OP_DISJOINT_ATOP, PIXMAN_a4r4g4b4, 0xae5f, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0xf215b675 }, { PIXMAN_OP_DISJOINT_ATOP_REVERSE, PIXMAN_a8r8g8b8, 0xce007980, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x80ffe4ad }, { PIXMAN_OP_DISJOINT_XOR, PIXMAN_a8r8g8b8, 0xb8b07bea, + PIXMAN_null, 0x00, PIXMAN_a4r4g4b4, 0x939c }, { PIXMAN_OP_CONJOINT_ATOP_REVERSE, PIXMAN_r5g6b5, 0x0063, + PIXMAN_null, 0x00, PIXMAN_a8r8g8b8, 0x10bb1ed7, }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0xbf, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x7e + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a8r8g8b8, 0xffffff, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xff3fffff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_r3g3b2, 0x38, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x5b + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_a8r8g8b8, 0x2e9effff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x77 + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r5g6b5, 0xffff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x33 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0xd0089ff, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0xb1 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_r3g3b2, 0x8a, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xcd0004 + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_a8r8g8b8, 0xffff1e3a, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xcf00 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a8r8g8b8, 0x84c4ffd7, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xffddff + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_a4r4g4b4, 0xfd75, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x7f + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_r3g3b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x63ff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a8r8g8b8, 0xff6e56, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x20ff1ade + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a4r4g4b4, 0xfe0, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xbdff + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_r5g6b5, 0x9799, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x8d + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a8r8g8b8, 0xe8ff1c33, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0x6200 + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_a8r8g8b8, 0x22ffffff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x63 + }, + { PIXMAN_OP_SCREEN, + PIXMAN_a8r8g8b8, 0x9671ff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x43 + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a2r2g2b2, 0x83, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0xff + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_r3g3b2, 0x0, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x97 + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_r5g6b5, 0xb900, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x6800ff00 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a4r4g4b4, 0xff, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0x8e + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xff00, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0xbc + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r5g6b5, 0xfffe, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x90 + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_r3g3b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xc35f + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x39ff + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a2r2g2b2, 0x1e, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xbaff + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a8r8g8b8, 0xb4ffff26, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0xff + }, + { PIXMAN_OP_COLOR_DODGE, + PIXMAN_a4r4g4b4, 0xe3ff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x878b + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0xff700044, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x6 + }, + { PIXMAN_OP_DARKEN, + PIXMAN_a2r2g2b2, 0xb6, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xcd00 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a2r2g2b2, 0xfe, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x12 + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a8r8g8b8, 0xb1ff006c, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xff7c + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r3g3b2, 0x4e, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x3c + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_r5g6b5, 0xffff, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0x1968 + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r3g3b2, 0xe7, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x8cced6ac + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a4r4g4b4, 0xa500, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x1bff009d + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r5g6b5, 0x45ff, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x32 + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a2r2g2b2, 0x18, + PIXMAN_null, 0x00, + PIXMAN_r5g6b5, 0xdc00 + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a4r4g4b4, 0x4247, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xd8ffff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_r5g6b5, 0xff00, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x79 + }, + { PIXMAN_OP_COLOR_BURN, + PIXMAN_r3g3b2, 0xf, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x9fff00ff + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a2r2g2b2, 0x93, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xff + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a2r2g2b2, 0xa3, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0xca + }, + { PIXMAN_OP_DIFFERENCE, + PIXMAN_r3g3b2, 0xe0, + PIXMAN_null, 0x00, + PIXMAN_a2r2g2b2, 0x39 + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r3g3b2, 0x16, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x98ffff + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_r3g3b2, 0x96, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0x225f6c + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_a4r4g4b4, 0x12c7, + PIXMAN_null, 0x00, + PIXMAN_a4r4g4b4, 0xb100 + }, + { PIXMAN_OP_LIGHTEN, + PIXMAN_a8r8g8b8, 0xffda91, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0x6a + }, + { PIXMAN_OP_EXCLUSION, + PIXMAN_a8r8g8b8, 0xfff8, + PIXMAN_null, 0x00, + PIXMAN_r3g3b2, 0xff + }, + { PIXMAN_OP_SOFT_LIGHT, + PIXMAN_a2r2g2b2, 0xff, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xf0ff48ca + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xf1ff, + PIXMAN_r5g6b5, 0x6eff, + PIXMAN_a8r8g8b8, 0xffffff, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xf1ff, + PIXMAN_a8, 0xdf, + PIXMAN_a8r8g8b8, 0xffffff, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xf1ff, + PIXMAN_null, 0x00, + PIXMAN_a8r8g8b8, 0xffffff, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xb867, + PIXMAN_a4r4g4b4, 0x82d9, + PIXMAN_a8r8g8b8, 0xffc5, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xa9f5, + PIXMAN_r5g6b5, 0xadff, + PIXMAN_a8r8g8b8, 0xffff00, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0x4900, + PIXMAN_r5g6b5, 0x865c, + PIXMAN_a8r8g8b8, 0xebff, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xd9ff, + PIXMAN_a8r8g8b8, 0xffffffff, + PIXMAN_a8r8g8b8, 0x8ff0d, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0x41ff, + PIXMAN_a4r4g4b4, 0xcff, + PIXMAN_a8r8g8b8, 0xe1ff00, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0x91ff, + PIXMAN_a2r2g2b2, 0xf3, + PIXMAN_a8r8g8b8, 0xe4ffb4, + }, + { PIXMAN_OP_HARD_LIGHT, + PIXMAN_r5g6b5, 0xb9ff, + PIXMAN_a2r2g2b2, 0xff, + PIXMAN_a8r8g8b8, 0xffff, + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0x473affff, + PIXMAN_r5g6b5, 0x2b00, + PIXMAN_r5g6b5, 0x1ff, + }, + { PIXMAN_OP_OVERLAY, + PIXMAN_a8r8g8b8, 0xe4ff, + PIXMAN_r3g3b2, 0xff, + PIXMAN_r5g6b5, 0x89ff, + }, }; static void @@ -159,35 +2855,59 @@ access (pixman_image_t *image, int x, int y) } static pixman_bool_t -verify (int test_no, const pixel_combination_t *combination, int size) +verify (int test_no, const pixel_combination_t *combination, int size, + pixman_bool_t component_alpha) { - pixman_image_t *src, *dest; - pixel_checker_t src_checker, dest_checker; - color_t source_color, dest_color, reference_color; + pixman_image_t *src, *mask, *dest; + pixel_checker_t src_checker, mask_checker, dest_checker; + color_t source_color, mask_color, dest_color, reference_color; + pixman_bool_t have_mask = (combination->mask_format != PIXMAN_null); pixman_bool_t result = TRUE; int i, j; /* Compute reference color */ pixel_checker_init (&src_checker, combination->src_format); + if (have_mask) + pixel_checker_init (&mask_checker, combination->mask_format); pixel_checker_init (&dest_checker, combination->dest_format); + pixel_checker_convert_pixel_to_color ( &src_checker, combination->src_pixel, &source_color); + if (combination->mask_format != PIXMAN_null) + { + pixel_checker_convert_pixel_to_color ( + &mask_checker, combination->mask_pixel, &mask_color); + } pixel_checker_convert_pixel_to_color ( &dest_checker, combination->dest_pixel, &dest_color); + do_composite (combination->op, - &source_color, NULL, &dest_color, - &reference_color, FALSE); + &source_color, + have_mask? &mask_color : NULL, + &dest_color, + &reference_color, component_alpha); src = pixman_image_create_bits ( combination->src_format, size, size, NULL, -1); + if (have_mask) + { + mask = pixman_image_create_bits ( + combination->mask_format, size, size, NULL, -1); + + pixman_image_set_component_alpha (mask, component_alpha); + } dest = pixman_image_create_bits ( combination->dest_format, size, size, NULL, -1); fill (src, combination->src_pixel); + if (have_mask) + fill (mask, combination->mask_pixel); fill (dest, combination->dest_pixel); pixman_image_composite32 ( - combination->op, src, NULL, dest, 0, 0, 0, 0, 0, 0, size, size); + combination->op, src, + have_mask ? mask : NULL, + dest, 0, 0, 0, 0, 0, 0, size, size); for (j = 0; j < size; ++j) { @@ -200,9 +2920,13 @@ verify (int test_no, const pixel_combination_t *combination, int size) { printf ("----------- Test %d failed ----------\n", test_no); - printf (" operator: %s\n", operator_name (combination->op)); + printf (" operator: %s (%s)\n", operator_name (combination->op), + have_mask? component_alpha ? "component alpha" : "unified alpha" : "no mask"); printf (" src format: %s\n", format_name (combination->src_format)); + if (have_mask != PIXMAN_null) + printf (" mask format: %s\n", format_name (combination->mask_format)); printf (" dest format: %s\n", format_name (combination->dest_format)); + printf (" - source ARGB: %f %f %f %f (pixel: %8x)\n", source_color.a, source_color.r, source_color.g, source_color.b, combination->src_pixel); @@ -210,6 +2934,16 @@ verify (int test_no, const pixel_combination_t *combination, int size) &a, &r, &g, &b); printf (" %8d %8d %8d %8d\n", a, r, g, b); + if (have_mask) + { + printf (" - mask ARGB: %f %f %f %f (pixel: %8x)\n", + mask_color.a, mask_color.r, mask_color.g, mask_color.b, + combination->mask_pixel); + pixel_checker_split_pixel (&mask_checker, combination->mask_pixel, + &a, &r, &g, &b); + printf (" %8d %8d %8d %8d\n", a, r, g, b); + } + printf (" - dest ARGB: %f %f %f %f (pixel: %8x)\n", dest_color.a, dest_color.r, dest_color.g, dest_color.b, combination->dest_pixel); @@ -248,19 +2982,41 @@ main (int argc, char **argv) { int result = 0; int i, j; + int lo, hi; + + if (argc > 1) + { + lo = atoi (argv[1]); + hi = lo + 1; + } + else + { + lo = 0; + hi = ARRAY_LENGTH (regressions); + } - for (i = 0; i < ARRAY_LENGTH (regressions); ++i) + for (i = lo; i < hi; ++i) { const pixel_combination_t *combination = &(regressions[i]); for (j = 1; j < 34; ++j) { - if (!verify (i, combination, j)) + int k, ca; + + ca = combination->mask_format == PIXMAN_null ? 1 : 2; + + for (k = 0; k < ca; ++k) { - result = 1; - break; + if (!verify (i, combination, j, k)) + { + result = 1; + goto next_regression; + } } } + + next_regression: + ; } return result; diff --git a/pixman/test/thread-test.c b/pixman/test/thread-test.c index 0b07b269d..1c2f0407a 100644 --- a/pixman/test/thread-test.c +++ b/pixman/test/thread-test.c @@ -38,38 +38,11 @@ static const pixman_op_t operators[] = PIXMAN_OP_ATOP_REVERSE, PIXMAN_OP_XOR, PIXMAN_OP_ADD, - PIXMAN_OP_SATURATE, - PIXMAN_OP_DISJOINT_CLEAR, - PIXMAN_OP_DISJOINT_SRC, - PIXMAN_OP_DISJOINT_DST, - PIXMAN_OP_DISJOINT_OVER, - PIXMAN_OP_DISJOINT_OVER_REVERSE, - PIXMAN_OP_DISJOINT_IN, - PIXMAN_OP_DISJOINT_IN_REVERSE, - PIXMAN_OP_DISJOINT_OUT, - PIXMAN_OP_DISJOINT_OUT_REVERSE, - PIXMAN_OP_DISJOINT_ATOP, - PIXMAN_OP_DISJOINT_ATOP_REVERSE, - PIXMAN_OP_DISJOINT_XOR, - PIXMAN_OP_CONJOINT_CLEAR, - PIXMAN_OP_CONJOINT_SRC, - PIXMAN_OP_CONJOINT_DST, - PIXMAN_OP_CONJOINT_OVER, - PIXMAN_OP_CONJOINT_OVER_REVERSE, - PIXMAN_OP_CONJOINT_IN, - PIXMAN_OP_CONJOINT_IN_REVERSE, - PIXMAN_OP_CONJOINT_OUT, - PIXMAN_OP_CONJOINT_OUT_REVERSE, - PIXMAN_OP_CONJOINT_ATOP, - PIXMAN_OP_CONJOINT_ATOP_REVERSE, - PIXMAN_OP_CONJOINT_XOR, PIXMAN_OP_MULTIPLY, PIXMAN_OP_SCREEN, PIXMAN_OP_OVERLAY, PIXMAN_OP_DARKEN, PIXMAN_OP_LIGHTEN, - PIXMAN_OP_COLOR_DODGE, - PIXMAN_OP_COLOR_BURN, PIXMAN_OP_HARD_LIGHT, PIXMAN_OP_DIFFERENCE, PIXMAN_OP_EXCLUSION, @@ -183,7 +156,7 @@ main (void) crc32 = compute_crc32 (0, crc32s, sizeof crc32s); -#define EXPECTED 0xE299B18E +#define EXPECTED 0x82C4D9FB if (crc32 != EXPECTED) { diff --git a/pixman/test/tolerance-test.c b/pixman/test/tolerance-test.c new file mode 100644 index 000000000..562563026 --- /dev/null +++ b/pixman/test/tolerance-test.c @@ -0,0 +1,360 @@ +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <float.h> +#include <math.h> +#include "utils.h" + +#define MAX_WIDTH 16 +#define MAX_HEIGHT 16 +#define MAX_STRIDE 4 + +static const pixman_format_code_t formats[] = +{ + PIXMAN_a2r10g10b10, + PIXMAN_x2r10g10b10, + PIXMAN_a8r8g8b8, + PIXMAN_a4r4g4b4, + PIXMAN_a2r2g2b2, + PIXMAN_r5g6b5, + PIXMAN_r3g3b2, +}; + +static const pixman_op_t operators[] = +{ + PIXMAN_OP_CLEAR, + PIXMAN_OP_SRC, + PIXMAN_OP_DST, + PIXMAN_OP_OVER, + PIXMAN_OP_OVER_REVERSE, + PIXMAN_OP_IN, + PIXMAN_OP_IN_REVERSE, + PIXMAN_OP_OUT, + PIXMAN_OP_OUT_REVERSE, + PIXMAN_OP_ATOP, + PIXMAN_OP_ATOP_REVERSE, + PIXMAN_OP_XOR, + PIXMAN_OP_ADD, + PIXMAN_OP_SATURATE, + + PIXMAN_OP_DISJOINT_CLEAR, + PIXMAN_OP_DISJOINT_SRC, + PIXMAN_OP_DISJOINT_DST, + PIXMAN_OP_DISJOINT_OVER, + PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_OP_DISJOINT_IN, + PIXMAN_OP_DISJOINT_IN_REVERSE, + PIXMAN_OP_DISJOINT_OUT, + PIXMAN_OP_DISJOINT_OUT_REVERSE, + PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_OP_DISJOINT_XOR, + + PIXMAN_OP_CONJOINT_CLEAR, + PIXMAN_OP_CONJOINT_SRC, + PIXMAN_OP_CONJOINT_DST, + PIXMAN_OP_CONJOINT_OVER, + PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_OP_CONJOINT_IN, + PIXMAN_OP_CONJOINT_IN_REVERSE, + PIXMAN_OP_CONJOINT_OUT, + PIXMAN_OP_CONJOINT_OUT_REVERSE, + PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_OP_CONJOINT_XOR, + + PIXMAN_OP_MULTIPLY, + PIXMAN_OP_SCREEN, + PIXMAN_OP_OVERLAY, + PIXMAN_OP_DARKEN, + PIXMAN_OP_LIGHTEN, + PIXMAN_OP_COLOR_DODGE, + PIXMAN_OP_COLOR_BURN, + PIXMAN_OP_HARD_LIGHT, + PIXMAN_OP_SOFT_LIGHT, + PIXMAN_OP_DIFFERENCE, + PIXMAN_OP_EXCLUSION, +}; + +#define RANDOM_ELT(array) \ + (array[prng_rand_n (ARRAY_LENGTH (array))]) + +static void +free_bits (pixman_image_t *image, void *data) +{ + free (image->bits.bits); +} + +static pixman_image_t * +create_image (pixman_image_t **clone) +{ + pixman_format_code_t format = RANDOM_ELT (formats); + pixman_image_t *image; + int width = prng_rand_n (MAX_WIDTH); + int height = prng_rand_n (MAX_HEIGHT); + int stride = ((width * (PIXMAN_FORMAT_BPP (format) / 8)) + 3) & ~3; + uint32_t *bytes = malloc (stride * height); + + prng_randmemset (bytes, stride * height, RANDMEMSET_MORE_00_AND_FF); + + image = pixman_image_create_bits ( + format, width, height, bytes, stride); + + pixman_image_set_destroy_function (image, free_bits, NULL); + + assert (image); + + if (clone) + { + uint32_t *bytes_dup = malloc (stride * height); + + memcpy (bytes_dup, bytes, stride * height); + + *clone = pixman_image_create_bits ( + format, width, height, bytes_dup, stride); + + pixman_image_set_destroy_function (*clone, free_bits, NULL); + } + + return image; +} + +static pixman_bool_t +access (pixman_image_t *image, int x, int y, uint32_t *pixel) +{ + int bytes_per_pixel; + int stride; + uint8_t *location; + + if (x < 0 || x >= image->bits.width || y < 0 || y >= image->bits.height) + return FALSE; + + bytes_per_pixel = PIXMAN_FORMAT_BPP (image->bits.format) / 8; + stride = image->bits.rowstride * 4; + + location = (uint8_t *)image->bits.bits + y * stride + x * bytes_per_pixel; + + if (bytes_per_pixel == 4) + *pixel = *(uint32_t *)location; + else if (bytes_per_pixel == 2) + *pixel = *(uint16_t *)location; + else if (bytes_per_pixel == 1) + *pixel = *(uint8_t *)location; + else + assert (0); + + return TRUE; +} + +static void +get_color (pixel_checker_t *checker, + pixman_image_t *image, + int x, int y, + color_t *color, + uint32_t *pixel) +{ + if (!access (image, x, y, pixel)) + { + color->a = 0.0; + color->r = 0.0; + color->g = 0.0; + color->b = 0.0; + } + else + { + pixel_checker_convert_pixel_to_color ( + checker, *pixel, color); + } +} + +static pixman_bool_t +verify (int test_no, + pixman_op_t op, + pixman_image_t *source, + pixman_image_t *mask, + pixman_image_t *dest, + pixman_image_t *orig_dest, + int x, int y, + int width, int height, + pixman_bool_t component_alpha) +{ + pixel_checker_t dest_checker, src_checker, mask_checker; + int i, j; + + pixel_checker_init (&src_checker, source->bits.format); + pixel_checker_init (&dest_checker, dest->bits.format); + pixel_checker_init (&mask_checker, mask->bits.format); + + assert (dest->bits.format == orig_dest->bits.format); + + for (j = y; j < y + height; ++j) + { + for (i = x; i < x + width; ++i) + { + color_t src_color, mask_color, orig_dest_color, result; + uint32_t dest_pixel, orig_dest_pixel, src_pixel, mask_pixel; + + access (dest, i, j, &dest_pixel); + + get_color (&src_checker, + source, i - x, j - y, + &src_color, &src_pixel); + + get_color (&mask_checker, + mask, i - x, j - y, + &mask_color, &mask_pixel); + + get_color (&dest_checker, + orig_dest, i, j, + &orig_dest_color, &orig_dest_pixel); + + do_composite (op, + &src_color, &mask_color, &orig_dest_color, + &result, component_alpha); + + if (!pixel_checker_check (&dest_checker, dest_pixel, &result)) + { + int a, r, g, b; + + printf ("--------- Test 0x%x failed ---------\n", test_no); + + printf (" operator: %s (%s alpha)\n", operator_name (op), + component_alpha? "component" : "unified"); + printf (" dest_x, dest_y: %d %d\n", x, y); + printf (" width, height: %d %d\n", width, height); + printf (" source: format: %-14s size: %2d x %2d\n", + format_name (source->bits.format), + source->bits.width, source->bits.height); + printf (" mask: format: %-14s size: %2d x %2d\n", + format_name (mask->bits.format), + mask->bits.width, mask->bits.height); + printf (" dest: format: %-14s size: %2d x %2d\n", + format_name (dest->bits.format), + dest->bits.width, dest->bits.height); + printf (" -- Failed pixel: (%d, %d) --\n", i, j); + printf (" source ARGB: %f %f %f %f (pixel: %x)\n", + src_color.a, src_color.r, src_color.g, src_color.b, + src_pixel); + printf (" mask ARGB: %f %f %f %f (pixel: %x)\n", + mask_color.a, mask_color.r, mask_color.g, mask_color.b, + mask_pixel); + printf (" dest ARGB: %f %f %f %f (pixel: %x)\n", + orig_dest_color.a, orig_dest_color.r, orig_dest_color.g, orig_dest_color.b, + orig_dest_pixel); + printf (" expected ARGB: %f %f %f %f\n", + result.a, result.r, result.g, result.b); + + pixel_checker_get_min (&dest_checker, &result, &a, &r, &g, &b); + printf (" min acceptable: %8d %8d %8d %8d\n", a, r, g, b); + + pixel_checker_split_pixel (&dest_checker, dest_pixel, &a, &r, &g, &b); + printf (" got: %8d %8d %8d %8d (pixel: %x)\n", a, r, g, b, dest_pixel); + + pixel_checker_get_max (&dest_checker, &result, &a, &r, &g, &b); + printf (" max acceptable: %8d %8d %8d %8d\n", a, r, g, b); + printf ("\n"); + printf (" { %s,\n", operator_name (op)); + printf (" PIXMAN_%s,\t0x%x,\n", format_name (source->bits.format), src_pixel); + printf (" PIXMAN_%s,\t0x%x,\n", format_name (mask->bits.format), mask_pixel); + printf (" PIXMAN_%s,\t0x%x\n", format_name (dest->bits.format), orig_dest_pixel); + printf (" },\n"); + return FALSE; + } + } + } + + return TRUE; +} + +static pixman_bool_t +do_check (int i) +{ + pixman_image_t *source, *dest, *mask; + pixman_op_t op; + int x, y, width, height; + pixman_image_t *dest_copy; + pixman_bool_t result = TRUE; + pixman_bool_t component_alpha; + + prng_srand (i); + op = RANDOM_ELT (operators); + x = prng_rand_n (MAX_WIDTH); + y = prng_rand_n (MAX_HEIGHT); + width = prng_rand_n (MAX_WIDTH) + 4; + height = prng_rand_n (MAX_HEIGHT) + 4; + + source = create_image (NULL); + mask = create_image (NULL); + dest = create_image (&dest_copy); + + if (x >= dest->bits.width) + x = dest->bits.width / 2; + if (y >= dest->bits.height) + y = dest->bits.height / 2; + if (x + width > dest->bits.width) + width = dest->bits.width - x; + if (y + height > dest->bits.height) + height = dest->bits.height - y; + + component_alpha = prng_rand_n (2); + + pixman_image_set_component_alpha (mask, component_alpha); + + pixman_image_composite32 (op, source, mask, dest, + 0, 0, 0, 0, + x, y, width, height); + + if (!verify (i, op, source, mask, dest, dest_copy, + x, y, width, height, component_alpha)) + { + result = FALSE; + } + + pixman_image_unref (source); + pixman_image_unref (mask); + pixman_image_unref (dest); + pixman_image_unref (dest_copy); + + return result; +} + +#define N_TESTS 10000000 + +int +main (int argc, const char *argv[]) +{ + int i; + int result = 0; + + if (argc == 2) + { + if (strcmp (argv[1], "--forever") == 0) + { + uint32_t n; + + prng_srand (time (0)); + + n = prng_rand(); + + for (;;) + do_check (n++); + } + else + { + do_check (strtol (argv[1], NULL, 0)); + } + } + else + { +#ifdef USE_OPENMP +# pragma omp parallel for default(none) shared(i) private (result) +#endif + for (i = 0; i < N_TESTS; ++i) + { + if (!do_check (i)) + result = 1; + } + } + + return result; +} diff --git a/pixman/test/utils.c b/pixman/test/utils.c index ebe0ccc09..188841783 100644 --- a/pixman/test/utils.c +++ b/pixman/test/utils.c @@ -4,6 +4,7 @@ #include <math.h> #include <signal.h> #include <stdlib.h> +#include <float.h> #ifdef HAVE_GETTIMEOFDAY #include <sys/time.h> @@ -1099,6 +1100,152 @@ format_name (pixman_format_code_t format) return "<unknown format>"; }; +#define IS_ZERO(f) (-DBL_MIN < (f) && (f) < DBL_MIN) + +typedef double (* blend_func_t) (double as, double s, double ad, double d); + +static force_inline double +blend_multiply (double sa, double s, double da, double d) +{ + return d * s; +} + +static force_inline double +blend_screen (double sa, double s, double da, double d) +{ + return d * sa + s * da - s * d; +} + +static force_inline double +blend_overlay (double sa, double s, double da, double d) +{ + if (2 * d < da) + return 2 * s * d; + else + return sa * da - 2 * (da - d) * (sa - s); +} + +static force_inline double +blend_darken (double sa, double s, double da, double d) +{ + s = s * da; + d = d * sa; + + if (s > d) + return d; + else + return s; +} + +static force_inline double +blend_lighten (double sa, double s, double da, double d) +{ + s = s * da; + d = d * sa; + + if (s > d) + return s; + else + return d; +} + +static force_inline double +blend_color_dodge (double sa, double s, double da, double d) +{ + if (IS_ZERO (d)) + return 0.0f; + else if (d * sa >= sa * da - s * da) + return sa * da; + else if (IS_ZERO (sa - s)) + return sa * da; + else + return sa * sa * d / (sa - s); +} + +static force_inline double +blend_color_burn (double sa, double s, double da, double d) +{ + if (d >= da) + return sa * da; + else if (sa * (da - d) >= s * da) + return 0.0f; + else if (IS_ZERO (s)) + return 0.0f; + else + return sa * (da - sa * (da - d) / s); +} + +static force_inline double +blend_hard_light (double sa, double s, double da, double d) +{ + if (2 * s < sa) + return 2 * s * d; + else + return sa * da - 2 * (da - d) * (sa - s); +} + +static force_inline double +blend_soft_light (double sa, double s, double da, double d) +{ + if (2 * s <= sa) + { + if (IS_ZERO (da)) + return d * sa; + else + return d * sa - d * (da - d) * (sa - 2 * s) / da; + } + else + { + if (IS_ZERO (da)) + { + return d * sa; + } + else + { + if (4 * d <= da) + return d * sa + (2 * s - sa) * d * ((16 * d / da - 12) * d / da + 3); + else + return d * sa + (sqrt (d * da) - d) * (2 * s - sa); + } + } +} + +static force_inline double +blend_difference (double sa, double s, double da, double d) +{ + double dsa = d * sa; + double sda = s * da; + + if (sda < dsa) + return dsa - sda; + else + return sda - dsa; +} + +static force_inline double +blend_exclusion (double sa, double s, double da, double d) +{ + return s * da + d * sa - 2 * d * s; +} + +static double +clamp (double d) +{ + if (d > 1.0) + return 1.0; + else if (d < 0.0) + return 0.0; + else + return d; +} + +static double +blend_channel (double as, double s, double ad, double d, + blend_func_t blend) +{ + return clamp ((1 - ad) * s + (1 - as) * d + blend (as, s, ad, d)); +} + static double calc_op (pixman_op_t op, double src, double dst, double srca, double dsta) { @@ -1336,6 +1483,21 @@ do_composite (pixman_op_t op, { color_t srcval, srcalpha; + static const blend_func_t blend_funcs[] = + { + blend_multiply, + blend_screen, + blend_overlay, + blend_darken, + blend_lighten, + blend_color_dodge, + blend_color_burn, + blend_hard_light, + blend_soft_light, + blend_difference, + blend_exclusion, + }; + if (mask == NULL) { srcval = *src; @@ -1370,10 +1532,22 @@ do_composite (pixman_op_t op, srcalpha.a = src->a * mask->a; } - result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a); - result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a); - result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a); - result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a); + if (op >= PIXMAN_OP_MULTIPLY) + { + blend_func_t func = blend_funcs[op - PIXMAN_OP_MULTIPLY]; + + result->a = srcalpha.a + dst->a - srcalpha.a * dst->a; + result->r = blend_channel (srcalpha.r, srcval.r, dst->a, dst->r, func); + result->g = blend_channel (srcalpha.g, srcval.g, dst->a, dst->g, func); + result->b = blend_channel (srcalpha.b, srcval.b, dst->a, dst->b, func); + } + else + { + result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a); + result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a); + result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a); + result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a); + } } static double @@ -1580,7 +1754,7 @@ get_limits (const pixel_checker_t *checker, double limit, /* The acceptable deviation in units of [0.0, 1.0] */ -#define DEVIATION (0.0064) +#define DEVIATION (0.0128) void pixel_checker_get_max (const pixel_checker_t *checker, color_t *color, |