diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 4e8ad578..18a6bf63 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -782,6 +782,45 @@ gen4_emit_composite_primitive_affine_source(struct sna *sna, v[8] *= op->src.scale[1]; } +fastcall static void +gen4_emit_composite_primitive_identity_mask(struct sna *sna, + const struct sna_composite_op *op, + const struct sna_composite_rectangles *r) +{ + union { + struct sna_coordinate p; + float f; + } dst; + float msk_x, msk_y; + float w, h; + float *v; + + msk_x = r->mask.x + op->mask.offset[0]; + msk_y = r->mask.y + op->mask.offset[1]; + w = r->width; + h = r->height; + + v = sna->render.vertices + sna->render.vertex_used; + sna->render.vertex_used += 15; + + dst.p.x = r->dst.x + r->width; + dst.p.y = r->dst.y + r->height; + v[0] = dst.f; + v[3] = (msk_x + w) * op->mask.scale[0]; + v[9] = v[4] = (msk_y + h) * op->mask.scale[1]; + + dst.p.x = r->dst.x; + v[5] = dst.f; + v[13] = v[8] = msk_x * op->mask.scale[0]; + + dst.p.y = r->dst.y; + v[10] = dst.f; + v[14] = msk_y * op->mask.scale[1]; + + v[7] = v[2] = v[1] = 1; + v[12] = v[11] = v[6] = 0; +} + fastcall static void gen4_emit_composite_primitive_identity_source_mask(struct sna *sna, const struct sna_composite_op *op, @@ -2387,8 +2426,12 @@ gen4_render_composite(struct sna *sna, tmp->is_affine &= tmp->mask.is_affine; - if (tmp->src.transform == NULL && tmp->mask.transform == NULL) - tmp->prim_emit = gen4_emit_composite_primitive_identity_source_mask; + if (tmp->src.transform == NULL && tmp->mask.transform == NULL) { + if (tmp->src.is_solid) + tmp->prim_emit = gen4_emit_composite_primitive_identity_mask; + else + tmp->prim_emit = gen4_emit_composite_primitive_identity_source_mask; + } tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine; } else { diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index 49542cc8..284e8da1 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -777,6 +777,45 @@ gen5_emit_composite_primitive_affine_source(struct sna *sna, v[8] *= op->src.scale[1]; } +fastcall static void +gen5_emit_composite_primitive_identity_mask(struct sna *sna, + const struct sna_composite_op *op, + const struct sna_composite_rectangles *r) +{ + union { + struct sna_coordinate p; + float f; + } dst; + float msk_x, msk_y; + float w, h; + float *v; + + msk_x = r->mask.x + op->mask.offset[0]; + msk_y = r->mask.y + op->mask.offset[1]; + w = r->width; + h = r->height; + + v = sna->render.vertices + sna->render.vertex_used; + sna->render.vertex_used += 15; + + dst.p.x = r->dst.x + r->width; + dst.p.y = r->dst.y + r->height; + v[0] = dst.f; + v[3] = (msk_x + w) * op->mask.scale[0]; + v[9] = v[4] = (msk_y + h) * op->mask.scale[1]; + + dst.p.x = r->dst.x; + v[5] = dst.f; + v[13] = v[8] = msk_x * op->mask.scale[0]; + + dst.p.y = r->dst.y; + v[10] = dst.f; + v[14] = msk_y * op->mask.scale[1]; + + v[7] = v[2] = v[1] = 1; + v[12] = v[11] = v[6] = 0; +} + fastcall static void gen5_emit_composite_primitive_identity_source_mask(struct sna *sna, const struct sna_composite_op *op, @@ -2393,8 +2432,12 @@ gen5_render_composite(struct sna *sna, tmp->is_affine &= tmp->mask.is_affine; - if (tmp->src.transform == NULL && tmp->mask.transform == NULL) - tmp->prim_emit = gen5_emit_composite_primitive_identity_source_mask; + if (tmp->src.transform == NULL && tmp->mask.transform == NULL) { + if (tmp->src.is_solid) + tmp->prim_emit = gen5_emit_composite_primitive_identity_mask; + else + tmp->prim_emit = gen5_emit_composite_primitive_identity_source_mask; + } tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine; } else { diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 37064608..6e2242b2 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -1404,6 +1404,45 @@ gen6_emit_composite_primitive_affine_source(struct sna *sna, v[8] *= op->src.scale[1]; } +fastcall static void +gen6_emit_composite_primitive_identity_mask(struct sna *sna, + const struct sna_composite_op *op, + const struct sna_composite_rectangles *r) +{ + union { + struct sna_coordinate p; + float f; + } dst; + float msk_x, msk_y; + float w, h; + float *v; + + msk_x = r->mask.x + op->mask.offset[0]; + msk_y = r->mask.y + op->mask.offset[1]; + w = r->width; + h = r->height; + + v = sna->render.vertices + sna->render.vertex_used; + sna->render.vertex_used += 15; + + dst.p.x = r->dst.x + r->width; + dst.p.y = r->dst.y + r->height; + v[0] = dst.f; + v[3] = (msk_x + w) * op->mask.scale[0]; + v[9] = v[4] = (msk_y + h) * op->mask.scale[1]; + + dst.p.x = r->dst.x; + v[5] = dst.f; + v[13] = v[8] = msk_x * op->mask.scale[0]; + + dst.p.y = r->dst.y; + v[10] = dst.f; + v[14] = msk_y * op->mask.scale[1]; + + v[7] = v[2] = v[1] = 1; + v[12] = v[11] = v[6] = 0; +} + fastcall static void gen6_emit_composite_primitive_identity_source_mask(struct sna *sna, const struct sna_composite_op *op, @@ -2750,8 +2789,12 @@ gen6_render_composite(struct sna *sna, tmp->is_affine &= tmp->mask.is_affine; - if (tmp->src.transform == NULL && tmp->mask.transform == NULL) - tmp->prim_emit = gen6_emit_composite_primitive_identity_source_mask; + if (tmp->src.transform == NULL && tmp->mask.transform == NULL) { + if (tmp->src.is_solid) + tmp->prim_emit = gen6_emit_composite_primitive_identity_mask; + else + tmp->prim_emit = gen6_emit_composite_primitive_identity_source_mask; + } tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine; } else { diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index 18c9036f..575d67af 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -1526,6 +1526,45 @@ gen7_emit_composite_primitive_affine_source(struct sna *sna, v[8] *= op->src.scale[1]; } +fastcall static void +gen7_emit_composite_primitive_identity_mask(struct sna *sna, + const struct sna_composite_op *op, + const struct sna_composite_rectangles *r) +{ + union { + struct sna_coordinate p; + float f; + } dst; + float msk_x, msk_y; + float w, h; + float *v; + + msk_x = r->mask.x + op->mask.offset[0]; + msk_y = r->mask.y + op->mask.offset[1]; + w = r->width; + h = r->height; + + v = sna->render.vertices + sna->render.vertex_used; + sna->render.vertex_used += 15; + + dst.p.x = r->dst.x + r->width; + dst.p.y = r->dst.y + r->height; + v[0] = dst.f; + v[3] = (msk_x + w) * op->mask.scale[0]; + v[9] = v[4] = (msk_y + h) * op->mask.scale[1]; + + dst.p.x = r->dst.x; + v[5] = dst.f; + v[13] = v[8] = msk_x * op->mask.scale[0]; + + dst.p.y = r->dst.y; + v[10] = dst.f; + v[14] = msk_y * op->mask.scale[1]; + + v[7] = v[2] = v[1] = 1; + v[12] = v[11] = v[6] = 0; +} + fastcall static void gen7_emit_composite_primitive_identity_source_mask(struct sna *sna, const struct sna_composite_op *op, @@ -2867,8 +2906,12 @@ gen7_render_composite(struct sna *sna, tmp->is_affine &= tmp->mask.is_affine; - if (tmp->src.transform == NULL && tmp->mask.transform == NULL) - tmp->prim_emit = gen7_emit_composite_primitive_identity_source_mask; + if (tmp->src.transform == NULL && tmp->mask.transform == NULL) { + if (tmp->src.is_solid) + tmp->prim_emit = gen7_emit_composite_primitive_identity_mask; + else + tmp->prim_emit = gen7_emit_composite_primitive_identity_source_mask; + } tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine; } else {