diff options
-rw-r--r-- | src/sna/Makefile.am | 2 | ||||
-rw-r--r-- | src/sna/gen2_render.c | 14 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 175 | ||||
-rw-r--r-- | src/sna/gen4_source.c | 179 | ||||
-rw-r--r-- | src/sna/gen4_source.h | 22 | ||||
-rw-r--r-- | src/sna/gen4_vertex.c | 189 | ||||
-rw-r--r-- | src/sna/gen4_vertex.h | 26 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 161 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 164 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 165 | ||||
-rw-r--r-- | src/sna/sna_render.h | 6 |
11 files changed, 451 insertions, 652 deletions
diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am index 8b654d76..bcf757ef 100644 --- a/src/sna/Makefile.am +++ b/src/sna/Makefile.am @@ -73,6 +73,8 @@ libsna_la_SOURCES = \ gen3_render.h \ gen4_render.c \ gen4_render.h \ + gen4_source.c \ + gen4_source.h \ gen4_vertex.c \ gen4_vertex.h \ gen5_render.c \ diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c index c5ad07a6..b539e278 100644 --- a/src/sna/gen2_render.c +++ b/src/sna/gen2_render.c @@ -762,9 +762,9 @@ gen2_emit_composite_linear(struct sna *sna, { float v; - v = (x * channel->u.gen2.linear_dx + - y * channel->u.gen2.linear_dy + - channel->u.gen2.linear_offset); + v = (x * channel->u.linear.dx + + y * channel->u.linear.dy + + channel->u.linear.offset); DBG(("%s: (%d, %d) -> %f\n", __FUNCTION__, x, y, v)); VERTEX(v); VERTEX(v); @@ -1262,12 +1262,12 @@ gen2_composite_linear_init(struct sna *sna, dx /= sf; dy /= sf; - channel->u.gen2.linear_dx = dx; - channel->u.gen2.linear_dy = dy; - channel->u.gen2.linear_offset = -dx*(x0+dst_x-x) + -dy*(y0+dst_y-y); + channel->u.linear.dx = dx; + channel->u.linear.dy = dy; + channel->u.linear.offset = -dx*(x0+dst_x-x) + -dy*(y0+dst_y-y); DBG(("%s: dx=%f, dy=%f, offset=%f\n", - __FUNCTION__, dx, dy, channel->u.gen2.linear_offset)); + __FUNCTION__, dx, dy, channel->u.linear.offset)); return channel->bo != NULL; } diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 893c5ee0..ac099a53 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -42,6 +42,7 @@ #include "brw/brw.h" #include "gen4_render.h" +#include "gen4_source.h" #include "gen4_vertex.h" /* gen4 has a serious issue with its shaders that we need to flush @@ -1333,141 +1334,6 @@ gen4_render_video(struct sna *sna, return true; } -static bool -gen4_composite_solid_init(struct sna *sna, - struct sna_composite_channel *channel, - uint32_t color) -{ - channel->filter = PictFilterNearest; - channel->repeat = RepeatNormal; - channel->is_affine = true; - channel->is_solid = true; - channel->transform = NULL; - channel->width = 1; - channel->height = 1; - channel->card_format = GEN4_SURFACEFORMAT_B8G8R8A8_UNORM; - - channel->bo = sna_render_get_solid(sna, color); - - channel->scale[0] = channel->scale[1] = 1; - channel->offset[0] = channel->offset[1] = 0; - return channel->bo != NULL; -} - -static bool -gen4_composite_linear_init(struct sna *sna, - PicturePtr picture, - struct sna_composite_channel *channel, - int x, int y, - int w, int h, - int dst_x, int dst_y) -{ - PictLinearGradient *linear = - (PictLinearGradient *)picture->pSourcePict; - pixman_fixed_t tx, ty; - float x0, y0, sf; - float dx, dy; - - DBG(("%s: p1=(%f, %f), p2=(%f, %f), src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", - __FUNCTION__, - pixman_fixed_to_double(linear->p1.x), pixman_fixed_to_double(linear->p1.y), - pixman_fixed_to_double(linear->p2.x), pixman_fixed_to_double(linear->p2.y), - x, y, dst_x, dst_y, w, h)); - - if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y) - return 0; - - if (!sna_transform_is_affine(picture->transform)) { - DBG(("%s: fallback due to projective transform\n", - __FUNCTION__)); - return sna_render_picture_fixup(sna, picture, channel, - x, y, w, h, dst_x, dst_y); - } - - channel->bo = sna_render_get_gradient(sna, (PictGradient *)linear); - if (!channel->bo) - return 0; - - channel->filter = PictFilterNearest; - channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; - channel->width = channel->bo->pitch / 4; - channel->height = 1; - channel->pict_format = PICT_a8r8g8b8; - - channel->scale[0] = channel->scale[1] = 1; - channel->offset[0] = channel->offset[1] = 0; - - if (sna_transform_is_translation(picture->transform, &tx, &ty)) { - dx = pixman_fixed_to_double(linear->p2.x - linear->p1.x); - dy = pixman_fixed_to_double(linear->p2.y - linear->p1.y); - - x0 = pixman_fixed_to_double(linear->p1.x); - y0 = pixman_fixed_to_double(linear->p1.y); - - if (tx | ty) { - x0 -= pixman_fixed_to_double(tx); - y0 -= pixman_fixed_to_double(ty); - } - } else { - struct pixman_f_vector p1, p2; - struct pixman_f_transform m, inv; - - pixman_f_transform_from_pixman_transform(&m, picture->transform); - DBG(("%s: transform = [%f %f %f, %f %f %f, %f %f %f]\n", - __FUNCTION__, - m.m[0][0], m.m[0][1], m.m[0][2], - m.m[1][0], m.m[1][1], m.m[1][2], - m.m[2][0], m.m[2][1], m.m[2][2])); - if (!pixman_f_transform_invert(&inv, &m)) - return 0; - - p1.v[0] = pixman_fixed_to_double(linear->p1.x); - p1.v[1] = pixman_fixed_to_double(linear->p1.y); - p1.v[2] = 1.; - pixman_f_transform_point(&inv, &p1); - - p2.v[0] = pixman_fixed_to_double(linear->p2.x); - p2.v[1] = pixman_fixed_to_double(linear->p2.y); - p2.v[2] = 1.; - pixman_f_transform_point(&inv, &p2); - - DBG(("%s: untransformed: p1=(%f, %f, %f), p2=(%f, %f, %f)\n", - __FUNCTION__, - p1.v[0], p1.v[1], p1.v[2], - p2.v[0], p2.v[1], p2.v[2])); - - dx = p2.v[0] - p1.v[0]; - dy = p2.v[1] - p1.v[1]; - - x0 = p1.v[0]; - y0 = p1.v[1]; - } - - sf = dx*dx + dy*dy; - dx /= sf; - dy /= sf; - - channel->embedded_transform.matrix[0][0] = pixman_double_to_fixed(dx); - channel->embedded_transform.matrix[0][1] = pixman_double_to_fixed(dy); - channel->embedded_transform.matrix[0][2] = -pixman_double_to_fixed(dx*(x0+dst_x-x) + dy*(y0+dst_y-y)); - - channel->embedded_transform.matrix[1][0] = 0; - channel->embedded_transform.matrix[1][1] = 0; - channel->embedded_transform.matrix[1][2] = pixman_double_to_fixed(.5); - - channel->embedded_transform.matrix[2][0] = 0; - channel->embedded_transform.matrix[2][1] = 0; - channel->embedded_transform.matrix[2][2] = pixman_fixed_1; - - channel->transform = &channel->embedded_transform; - channel->is_affine = 1; - - DBG(("%s: dx=%f, dy=%f, offset=%f\n", - __FUNCTION__, dx, dy, -dx*(x0-x+dst_x) + -dy*(y0-y+dst_y))); - - return channel->bo != NULL; -} - static int gen4_composite_picture(struct sna *sna, PicturePtr picture, @@ -1488,16 +1354,16 @@ gen4_composite_picture(struct sna *sna, channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) - return gen4_composite_solid_init(sna, channel, color); + return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) - return gen4_composite_linear_init(sna, picture, channel, - x, y, - w, h, - dst_x, dst_y); + return gen4_channel_init_linear(sna, picture, channel, + x, y, + w, h, + dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; @@ -1845,7 +1711,7 @@ reuse_source(struct sna *sna, } if (sna_picture_is_solid(mask, &color)) - return gen4_composite_solid_init(sna, mc, color); + return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; @@ -1937,7 +1803,7 @@ gen4_render_composite(struct sna *sna, DBG(("%s: failed to prepare source\n", __FUNCTION__)); goto cleanup_dst; case 0: - if (!gen4_composite_solid_init(sna, &tmp->src, 0)) + if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: @@ -1989,7 +1855,7 @@ gen4_render_composite(struct sna *sna, DBG(("%s: failed to prepare mask\n", __FUNCTION__)); goto cleanup_src; case 0: - if (!gen4_composite_solid_init(sna, &tmp->mask, 0)) + if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: @@ -2000,7 +1866,6 @@ gen4_render_composite(struct sna *sna, tmp->is_affine &= tmp->mask.is_affine; } - gen4_choose_composite_emitter(tmp); /* XXX using more then one thread causes corruption? */ tmp->u.gen4.sf = (tmp->mask.bo == NULL && @@ -2012,7 +1877,7 @@ gen4_render_composite(struct sna *sna, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine); - tmp->u.gen4.ve_id = gen4_choose_composite_vertex_buffer(tmp); + tmp->u.gen4.ve_id = gen4_choose_composite_emitter(tmp); tmp->blt = gen4_render_composite_blt; tmp->box = gen4_render_composite_box; @@ -2189,7 +2054,7 @@ gen4_render_composite_spans(struct sna *sna, case -1: goto cleanup_dst; case 0: - if (!gen4_composite_solid_init(sna, &tmp->base.src, 0)) + if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: @@ -2204,10 +2069,8 @@ gen4_render_composite_spans(struct sna *sna, tmp->base.need_magic_ca_pass = false; tmp->base.u.gen4.sf = !tmp->base.src.is_solid; - gen4_choose_spans_emitter(tmp); - + tmp->base.u.gen4.ve_id = gen4_choose_spans_emitter(tmp); tmp->base.u.gen4.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine; - tmp->base.u.gen4.ve_id = gen4_choose_spans_vertex_buffer(&tmp->base); tmp->box = gen4_render_composite_spans_box; tmp->boxes = gen4_render_composite_spans_boxes; @@ -2634,7 +2497,7 @@ gen4_render_fill_boxes(struct sna *sna, tmp.dst.format = format; tmp.dst.bo = dst_bo; - gen4_composite_solid_init(sna, &tmp.src, pixel); + gen4_channel_init_solid(sna, &tmp.src, pixel); tmp.is_affine = true; tmp.floats_per_vertex = 2; @@ -2792,9 +2655,9 @@ gen4_render_fill(struct sna *sna, uint8_t alu, op->base.need_magic_ca_pass = 0; op->base.has_component_alpha = 0; - gen4_composite_solid_init(sna, &op->base.src, - sna_rgba_for_color(color, - dst->drawable.depth)); + gen4_channel_init_solid(sna, &op->base.src, + sna_rgba_for_color(color, + dst->drawable.depth)); op->base.mask.bo = NULL; op->base.is_affine = true; @@ -2869,9 +2732,9 @@ gen4_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; - gen4_composite_solid_init(sna, &tmp.src, - sna_rgba_for_color(color, - dst->drawable.depth)); + gen4_channel_init_solid(sna, &tmp.src, + sna_rgba_for_color(color, + dst->drawable.depth)); tmp.mask.bo = NULL; tmp.is_affine = true; diff --git a/src/sna/gen4_source.c b/src/sna/gen4_source.c new file mode 100644 index 00000000..8ea16175 --- /dev/null +++ b/src/sna/gen4_source.c @@ -0,0 +1,179 @@ +/* + * Copyright © 2011,2012,2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Chris Wilson <chris@chris-wilson.co.uk> + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "sna.h" +#include "sna_render.h" +#include "sna_render_inline.h" +#include "gen4_source.h" +#include "gen4_render.h" + +bool +gen4_channel_init_solid(struct sna *sna, + struct sna_composite_channel *channel, + uint32_t color) +{ + channel->filter = PictFilterNearest; + channel->repeat = RepeatNormal; + channel->is_affine = true; + channel->is_solid = true; + channel->transform = NULL; + channel->width = 1; + channel->height = 1; + channel->pict_format = PICT_a8r8g8b8; + channel->card_format = GEN4_SURFACEFORMAT_B8G8R8A8_UNORM; + + channel->bo = sna_render_get_solid(sna, color); + + channel->scale[0] = channel->scale[1] = 1; + channel->offset[0] = channel->offset[1] = 0; + return channel->bo != NULL; +} + + +bool +gen4_channel_init_linear(struct sna *sna, + PicturePtr picture, + struct sna_composite_channel *channel, + int x, int y, + int w, int h, + int dst_x, int dst_y) +{ + PictLinearGradient *linear = + (PictLinearGradient *)picture->pSourcePict; + pixman_fixed_t tx, ty; + float x0, y0, sf; + float dx, dy; + + DBG(("%s: p1=(%f, %f), p2=(%f, %f), src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", + __FUNCTION__, + pixman_fixed_to_double(linear->p1.x), pixman_fixed_to_double(linear->p1.y), + pixman_fixed_to_double(linear->p2.x), pixman_fixed_to_double(linear->p2.y), + x, y, dst_x, dst_y, w, h)); + + if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y) + return 0; + + if (!sna_transform_is_affine(picture->transform)) { + DBG(("%s: fallback due to projective transform\n", + __FUNCTION__)); + return sna_render_picture_fixup(sna, picture, channel, + x, y, w, h, dst_x, dst_y); + } + + channel->bo = sna_render_get_gradient(sna, (PictGradient *)linear); + if (!channel->bo) + return 0; + + channel->filter = PictFilterNearest; + channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; + channel->width = channel->bo->pitch / 4; + channel->height = 1; + channel->pict_format = PICT_a8r8g8b8; + channel->card_format = GEN4_SURFACEFORMAT_B8G8R8A8_UNORM; + channel->is_linear = 1; + channel->is_affine = 1; + + channel->scale[0] = channel->scale[1] = 1; + channel->offset[0] = channel->offset[1] = 0; + + if (sna_transform_is_translation(picture->transform, &tx, &ty)) { + dx = pixman_fixed_to_double(linear->p2.x - linear->p1.x); + dy = pixman_fixed_to_double(linear->p2.y - linear->p1.y); + + x0 = pixman_fixed_to_double(linear->p1.x); + y0 = pixman_fixed_to_double(linear->p1.y); + + if (tx | ty) { + x0 -= pixman_fixed_to_double(tx); + y0 -= pixman_fixed_to_double(ty); + } + } else { + struct pixman_f_vector p1, p2; + struct pixman_f_transform m, inv; + + pixman_f_transform_from_pixman_transform(&m, picture->transform); + DBG(("%s: transform = [%f %f %f, %f %f %f, %f %f %f]\n", + __FUNCTION__, + m.m[0][0], m.m[0][1], m.m[0][2], + m.m[1][0], m.m[1][1], m.m[1][2], + m.m[2][0], m.m[2][1], m.m[2][2])); + if (!pixman_f_transform_invert(&inv, &m)) + return 0; + + p1.v[0] = pixman_fixed_to_double(linear->p1.x); + p1.v[1] = pixman_fixed_to_double(linear->p1.y); + p1.v[2] = 1.; + pixman_f_transform_point(&inv, &p1); + + p2.v[0] = pixman_fixed_to_double(linear->p2.x); + p2.v[1] = pixman_fixed_to_double(linear->p2.y); + p2.v[2] = 1.; + pixman_f_transform_point(&inv, &p2); + + DBG(("%s: untransformed: p1=(%f, %f, %f), p2=(%f, %f, %f)\n", + __FUNCTION__, + p1.v[0], p1.v[1], p1.v[2], + p2.v[0], p2.v[1], p2.v[2])); + + dx = p2.v[0] - p1.v[0]; + dy = p2.v[1] - p1.v[1]; + + x0 = p1.v[0]; + y0 = p1.v[1]; + } + + sf = dx*dx + dy*dy; + dx /= sf; + dy /= sf; + + channel->u.linear.dx = dx; + channel->u.linear.dy = dy; + channel->u.linear.offset = -dx*(x0+dst_x-x) + -dy*(y0+dst_y-y); + + channel->embedded_transform.matrix[0][0] = pixman_double_to_fixed(dx); + channel->embedded_transform.matrix[0][1] = pixman_double_to_fixed(dy); + channel->embedded_transform.matrix[0][2] = pixman_double_to_fixed(channel->u.linear.offset); + + channel->embedded_transform.matrix[1][0] = 0; + channel->embedded_transform.matrix[1][1] = 0; + channel->embedded_transform.matrix[1][2] = pixman_double_to_fixed(.5); + + channel->embedded_transform.matrix[2][0] = 0; + channel->embedded_transform.matrix[2][1] = 0; + channel->embedded_transform.matrix[2][2] = pixman_fixed_1; + + channel->transform = &channel->embedded_transform; + + DBG(("%s: dx=%f, dy=%f, offset=%f\n", + __FUNCTION__, dx, dy, channel->u.linear.offset)); + + return channel->bo != NULL; +} diff --git a/src/sna/gen4_source.h b/src/sna/gen4_source.h new file mode 100644 index 00000000..c73afaca --- /dev/null +++ b/src/sna/gen4_source.h @@ -0,0 +1,22 @@ +#ifndef GEN4_SOURCE_H +#define GEN4_SOURCE_H + +#include "compiler.h" + +#include "sna.h" +#include "sna_render.h" + +bool +gen4_channel_init_solid(struct sna *sna, + struct sna_composite_channel *channel, + uint32_t color); + +bool +gen4_channel_init_linear(struct sna *sna, + PicturePtr picture, + struct sna_composite_channel *channel, + int x, int y, + int w, int h, + int dst_x, int dst_y); + +#endif /* GEN4_SOURCE_H */ diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c index ba88ca51..f8becce3 100644 --- a/src/sna/gen4_vertex.c +++ b/src/sna/gen4_vertex.c @@ -223,6 +223,15 @@ void gen4_vertex_close(struct sna *sna) #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) /* XXX assert(!too_large(x, y)); */ #define OUT_VERTEX_F(v) vertex_emit(sna, v) +inline static float +compute_linear(const struct sna_composite_channel *channel, + int16_t x, int16_t y) +{ + return ((x+channel->offset[0]) * channel->u.linear.dx + + (y+channel->offset[1]) * channel->u.linear.dy + + channel->u.linear.offset); +} + inline static void emit_texcoord(struct sna *sna, const struct sna_composite_channel *channel, @@ -346,6 +355,36 @@ emit_primitive_solid(struct sna *sna, } fastcall static void +emit_primitive_linear(struct sna *sna, + const struct sna_composite_op *op, + const struct sna_composite_rectangles *r) +{ + float *v; + union { + struct sna_coordinate p; + float f; + } dst; + + assert(op->floats_per_rect == 6); + assert((sna->render.vertex_used % 2) == 0); + v = sna->render.vertices + sna->render.vertex_used; + sna->render.vertex_used += 6; + assert(sna->render.vertex_used <= sna->render.vertex_size); + + dst.p.x = r->dst.x + r->width; + dst.p.y = r->dst.y + r->height; + v[0] = dst.f; + dst.p.x = r->dst.x; + v[2] = dst.f; + dst.p.y = r->dst.y; + v[4] = dst.f; + + v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); + v[3] = compute_linear(&op->src, r->src.x, r->src.y+r->height); + v[5] = compute_linear(&op->src, r->src.x, r->src.y); +} + +fastcall static void emit_primitive_identity_source(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) @@ -499,6 +538,51 @@ emit_primitive_identity_mask(struct sna *sna, } fastcall static void +emit_primitive_linear_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; + + DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n", + __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h)); + + assert(op->floats_per_rect == 12); + assert((sna->render.vertex_used % 4) == 0); + v = sna->render.vertices + sna->render.vertex_used; + sna->render.vertex_used += 12; + + dst.p.x = r->dst.x + r->width; + dst.p.y = r->dst.y + r->height; + v[0] = dst.f; + v[2] = (msk_x + w) * op->mask.scale[0]; + v[7] = v[3] = (msk_y + h) * op->mask.scale[1]; + + dst.p.x = r->dst.x; + v[4] = dst.f; + v[10] = v[6] = msk_x * op->mask.scale[0]; + + dst.p.y = r->dst.y; + v[8] = dst.f; + v[11] = msk_y * op->mask.scale[1]; + + v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); + v[5] = compute_linear(&op->src, r->src.x, r->src.y+r->height); + v[9] = compute_linear(&op->src, r->src.x, r->src.y); +} + +fastcall static void emit_primitive_identity_source_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) @@ -661,20 +745,28 @@ emit_composite_texcoord_affine(struct sna *sna, OUT_VERTEX_F(t[1] * channel->scale[1]); } -void gen4_choose_composite_emitter(struct sna_composite_op *tmp) + +unsigned gen4_choose_composite_emitter(struct sna_composite_op *tmp) { - tmp->prim_emit = emit_primitive; - tmp->floats_per_vertex = 1 + (tmp->src.is_solid ? 1 : 2 + !tmp->src.is_affine); + unsigned vb; + if (tmp->mask.bo) { - tmp->floats_per_vertex += 2 + !tmp->mask.is_affine; - tmp->prim_emit = emit_primitive_mask; if (tmp->mask.transform == NULL) { if (tmp->src.is_solid) { DBG(("%s: solid, identity mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_identity_mask; + tmp->floats_per_vertex = 4; + vb = 1 | 2 << 2; + } else if (tmp->src.is_linear) { + DBG(("%s: linear, identity mask\n", __FUNCTION__)); + tmp->prim_emit = emit_primitive_linear_identity_mask; + tmp->floats_per_vertex = 4; + vb = 1 | 2 << 2; } else if (tmp->src.transform == NULL) { DBG(("%s: identity source, identity mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_identity_source_mask; + tmp->floats_per_vertex = 5; + vb = 2 << 2 | 2; } else if (tmp->src.is_affine) { tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; @@ -685,7 +777,19 @@ void gen4_choose_composite_emitter(struct sna_composite_op *tmp) DBG(("%s: affine src, identity mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_affine_source_identity; } + tmp->floats_per_vertex = 5; + vb = 2 << 2 | 2; + } else { + tmp->prim_emit = emit_primitive_mask; + tmp->floats_per_vertex = 6; + vb = 2 << 2 | 3; } + } else { + tmp->prim_emit = emit_primitive_mask; + tmp->floats_per_vertex = 1; + tmp->floats_per_vertex += 2 + !tmp->mask.is_affine; + tmp->floats_per_vertex += 2 + !tmp->src.is_affine; + vb = (2 + !tmp->src.is_affine) | (2 + !tmp->mask.is_affine) << 2; } } else { if (tmp->src.is_solid) { @@ -693,9 +797,17 @@ void gen4_choose_composite_emitter(struct sna_composite_op *tmp) tmp->prim_emit = emit_primitive_solid; if (tmp->src.is_opaque && tmp->op == PictOpOver) tmp->op = PictOpSrc; + tmp->floats_per_vertex = 2; + vb = 1; + } else if (tmp->src.is_linear) { + tmp->prim_emit = emit_primitive_linear; + tmp->floats_per_vertex = 2; + vb = 1; } else if (tmp->src.transform == NULL) { DBG(("%s: identity src, no mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_identity_source; + tmp->floats_per_vertex = 3; + vb = 2; } else if (tmp->src.is_affine) { tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; @@ -706,9 +818,17 @@ void gen4_choose_composite_emitter(struct sna_composite_op *tmp) DBG(("%s: affine src, no mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_affine_source; } + tmp->floats_per_vertex = 3; + vb = 2; + } else { + tmp->prim_emit = emit_primitive; + tmp->floats_per_vertex = 4; + vb = 3; } } tmp->floats_per_rect = 3 * tmp->floats_per_vertex; + + return vb; } inline static void @@ -896,15 +1016,63 @@ emit_spans_affine(struct sna *sna, v[11] = v[7] = v[3] = opacity; } -void gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp) +fastcall static void +emit_spans_linear(struct sna *sna, + const struct sna_composite_spans_op *op, + const BoxRec *box, + float opacity) { - tmp->prim_emit = emit_composite_spans_primitive; + union { + struct sna_coordinate p; + float f; + } dst; + float *v; + + assert(op->base.floats_per_rect == 9); + assert((sna->render.vertex_used % 3) == 0); + v = sna->render.vertices + sna->render.vertex_used; + sna->render.vertex_used += 9; + + dst.p.x = box->x2; + dst.p.y = box->y2; + v[0] = dst.f; + dst.p.x = box->x1; + v[3] = dst.f; + dst.p.y = box->y1; + v[6] = dst.f; + + v[1] = compute_linear(&op->base.src, box->x2, box->y2); + v[4] = compute_linear(&op->base.src, box->x1, box->y2); + v[7] = compute_linear(&op->base.src, box->x1, box->y1); + + v[8] = v[5] = v[2] = opacity; +} + +inline inline static uint32_t +gen4_choose_spans_vertex_buffer(const struct sna_composite_op *op) +{ + int id = op->src.is_solid ? 1 : 2 + !op->src.is_affine; + DBG(("%s: id=%x (%d, 1)\n", __FUNCTION__, 1 << 2 | id, id)); + return 1 << 2 | id; +} + + +unsigned gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp) +{ + unsigned vb; + if (tmp->base.src.is_solid) { tmp->prim_emit = emit_spans_solid; tmp->base.floats_per_vertex = 3; + vb = 1 << 2 | 1; + } else if (tmp->base.src.is_linear) { + tmp->prim_emit = emit_spans_linear; + tmp->base.floats_per_vertex = 3; + vb = 1 << 2 | 1; } else if (tmp->base.src.transform == NULL) { tmp->prim_emit = emit_spans_identity; tmp->base.floats_per_vertex = 4; + vb = 1 << 2 | 2; } else if (tmp->base.is_affine) { tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2]; tmp->base.src.scale[1] /= tmp->base.src.transform->matrix[2][2]; @@ -913,7 +1081,12 @@ void gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp) else tmp->prim_emit = emit_spans_affine; tmp->base.floats_per_vertex = 4; - } else + vb = 1 << 2 | 2; + } else { + tmp->prim_emit = emit_composite_spans_primitive; tmp->base.floats_per_vertex = 5; + vb = 1 << 2 | 3; + } tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex; + return vb; } diff --git a/src/sna/gen4_vertex.h b/src/sna/gen4_vertex.h index b6d13748..431b545e 100644 --- a/src/sna/gen4_vertex.h +++ b/src/sna/gen4_vertex.h @@ -10,29 +10,7 @@ void gen4_vertex_flush(struct sna *sna); int gen4_vertex_finish(struct sna *sna); void gen4_vertex_close(struct sna *sna); -inline static uint32_t -gen4_choose_composite_vertex_buffer(const struct sna_composite_op *op) -{ - int id = op->src.is_solid ? 1 : 2 + !op->src.is_affine; - if (op->mask.bo) - id |= (2 + !op->mask.is_affine) << 2; - DBG(("%s: id=%x (%d, %d)\n", __FUNCTION__, id, - op->src.is_solid ? 1 : 2 + !op->src.is_affine, - op->mask.bo ? 2 + !op->mask.is_affine : 0)); - assert(id > 0 && id < 16); - return id; -} - -inline inline static uint32_t -gen4_choose_spans_vertex_buffer(const struct sna_composite_op *op) -{ - int id = op->src.is_solid ? 1 : 2 + !op->src.is_affine; - DBG(("%s: id=%x (%d, 1)\n", __FUNCTION__, 1 << 2 | id, id)); - return 1 << 2 | id; -} - -void gen4_choose_composite_emitter(struct sna_composite_op *tmp); -void gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp); - +unsigned gen4_choose_composite_emitter(struct sna_composite_op *tmp); +unsigned gen4_choose_spans_emitter(struct sna_composite_spans_op *tmp); #endif /* GEN4_VERTEX_H */ diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index 15f5f58b..2e64b8e9 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -42,6 +42,7 @@ #include "brw/brw.h" #include "gen5_render.h" +#include "gen4_source.h" #include "gen4_vertex.h" #define NO_COMPOSITE 0 @@ -1321,141 +1322,6 @@ gen5_render_video(struct sna *sna, return true; } -static bool -gen5_composite_solid_init(struct sna *sna, - struct sna_composite_channel *channel, - uint32_t color) -{ - channel->filter = PictFilterNearest; - channel->repeat = RepeatNormal; - channel->is_affine = true; - channel->is_solid = true; - channel->transform = NULL; - channel->width = 1; - channel->height = 1; - channel->card_format = GEN5_SURFACEFORMAT_B8G8R8A8_UNORM; - - channel->bo = sna_render_get_solid(sna, color); - - channel->scale[0] = channel->scale[1] = 1; - channel->offset[0] = channel->offset[1] = 0; - return channel->bo != NULL; -} - -static bool -gen5_composite_linear_init(struct sna *sna, - PicturePtr picture, - struct sna_composite_channel *channel, - int x, int y, - int w, int h, - int dst_x, int dst_y) -{ - PictLinearGradient *linear = - (PictLinearGradient *)picture->pSourcePict; - pixman_fixed_t tx, ty; - float x0, y0, sf; - float dx, dy; - - DBG(("%s: p1=(%f, %f), p2=(%f, %f), src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", - __FUNCTION__, - pixman_fixed_to_double(linear->p1.x), pixman_fixed_to_double(linear->p1.y), - pixman_fixed_to_double(linear->p2.x), pixman_fixed_to_double(linear->p2.y), - x, y, dst_x, dst_y, w, h)); - - if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y) - return 0; - - if (!sna_transform_is_affine(picture->transform)) { - DBG(("%s: fallback due to projective transform\n", - __FUNCTION__)); - return sna_render_picture_fixup(sna, picture, channel, - x, y, w, h, dst_x, dst_y); - } - - channel->bo = sna_render_get_gradient(sna, (PictGradient *)linear); - if (!channel->bo) - return 0; - - channel->filter = PictFilterNearest; - channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; - channel->width = channel->bo->pitch / 4; - channel->height = 1; - channel->pict_format = PICT_a8r8g8b8; - - channel->scale[0] = channel->scale[1] = 1; - channel->offset[0] = channel->offset[1] = 0; - - if (sna_transform_is_translation(picture->transform, &tx, &ty)) { - dx = pixman_fixed_to_double(linear->p2.x - linear->p1.x); - dy = pixman_fixed_to_double(linear->p2.y - linear->p1.y); - - x0 = pixman_fixed_to_double(linear->p1.x); - y0 = pixman_fixed_to_double(linear->p1.y); - - if (tx | ty) { - x0 -= pixman_fixed_to_double(tx); - y0 -= pixman_fixed_to_double(ty); - } - } else { - struct pixman_f_vector p1, p2; - struct pixman_f_transform m, inv; - - pixman_f_transform_from_pixman_transform(&m, picture->transform); - DBG(("%s: transform = [%f %f %f, %f %f %f, %f %f %f]\n", - __FUNCTION__, - m.m[0][0], m.m[0][1], m.m[0][2], - m.m[1][0], m.m[1][1], m.m[1][2], - m.m[2][0], m.m[2][1], m.m[2][2])); - if (!pixman_f_transform_invert(&inv, &m)) - return 0; - - p1.v[0] = pixman_fixed_to_double(linear->p1.x); - p1.v[1] = pixman_fixed_to_double(linear->p1.y); - p1.v[2] = 1.; - pixman_f_transform_point(&inv, &p1); - - p2.v[0] = pixman_fixed_to_double(linear->p2.x); - p2.v[1] = pixman_fixed_to_double(linear->p2.y); - p2.v[2] = 1.; - pixman_f_transform_point(&inv, &p2); - - DBG(("%s: untransformed: p1=(%f, %f, %f), p2=(%f, %f, %f)\n", - __FUNCTION__, - p1.v[0], p1.v[1], p1.v[2], - p2.v[0], p2.v[1], p2.v[2])); - - dx = p2.v[0] - p1.v[0]; - dy = p2.v[1] - p1.v[1]; - - x0 = p1.v[0]; - y0 = p1.v[1]; - } - - sf = dx*dx + dy*dy; - dx /= sf; - dy /= sf; - - channel->embedded_transform.matrix[0][0] = pixman_double_to_fixed(dx); - channel->embedded_transform.matrix[0][1] = pixman_double_to_fixed(dy); - channel->embedded_transform.matrix[0][2] = -pixman_double_to_fixed(dx*(x0+dst_x-x) + dy*(y0+dst_y-y)); - - channel->embedded_transform.matrix[1][0] = 0; - channel->embedded_transform.matrix[1][1] = 0; - channel->embedded_transform.matrix[1][2] = pixman_double_to_fixed(.5); - - channel->embedded_transform.matrix[2][0] = 0; - channel->embedded_transform.matrix[2][1] = 0; - channel->embedded_transform.matrix[2][2] = pixman_fixed_1; - - channel->transform = &channel->embedded_transform; - channel->is_affine = 1; - - DBG(("%s: dx=%f, dy=%f, offset=%f\n", - __FUNCTION__, dx, dy, -dx*(x0-x+dst_x) + -dy*(y0-y+dst_y))); - - return channel->bo != NULL; -} - static int gen5_composite_picture(struct sna *sna, PicturePtr picture, @@ -1476,16 +1342,16 @@ gen5_composite_picture(struct sna *sna, channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) - return gen5_composite_solid_init(sna, channel, color); + return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) - return gen5_composite_linear_init(sna, picture, channel, - x, y, - w, h, - dst_x, dst_y); + return gen4_channel_init_linear(sna, picture, channel, + x, y, + w, h, + dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; @@ -1826,7 +1692,7 @@ reuse_source(struct sna *sna, } if (sna_picture_is_solid(mask, &color)) - return gen5_composite_solid_init(sna, mc, color); + return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; @@ -1921,7 +1787,7 @@ gen5_render_composite(struct sna *sna, DBG(("%s: failed to prepare source picture\n", __FUNCTION__)); goto cleanup_dst; case 0: - if (!gen5_composite_solid_init(sna, &tmp->src, 0)) + if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: @@ -1972,7 +1838,7 @@ gen5_render_composite(struct sna *sna, DBG(("%s: failed to prepare mask picture\n", __FUNCTION__)); goto cleanup_src; case 0: - if (!gen5_composite_solid_init(sna, &tmp->mask, 0)) + if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: @@ -1983,14 +1849,13 @@ gen5_render_composite(struct sna *sna, tmp->is_affine &= tmp->mask.is_affine; } - gen4_choose_composite_emitter(tmp); tmp->u.gen5.wm_kernel = gen5_choose_composite_kernel(tmp->op, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine); - tmp->u.gen5.ve_id = gen4_choose_composite_vertex_buffer(tmp); + tmp->u.gen5.ve_id = gen4_choose_composite_emitter(tmp); tmp->blt = gen5_render_composite_blt; tmp->box = gen5_render_composite_box; @@ -2162,7 +2027,7 @@ gen5_render_composite_spans(struct sna *sna, case -1: goto cleanup_dst; case 0: - if (!gen5_composite_solid_init(sna, &tmp->base.src, 0)) + if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: @@ -2176,10 +2041,8 @@ gen5_render_composite_spans(struct sna *sna, tmp->base.has_component_alpha = false; tmp->base.need_magic_ca_pass = false; - gen4_choose_spans_emitter(tmp); - + tmp->base.u.gen5.ve_id = gen4_choose_spans_emitter(tmp); tmp->base.u.gen5.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine; - tmp->base.u.gen5.ve_id = gen4_choose_spans_vertex_buffer(&tmp->base); tmp->box = gen5_render_composite_spans_box; tmp->boxes = gen5_render_composite_spans_boxes; diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index d484ddeb..77bd8536 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -42,6 +42,7 @@ #include "brw/brw.h" #include "gen6_render.h" +#include "gen4_source.h" #include "gen4_vertex.h" #define NO_COMPOSITE 0 @@ -1602,144 +1603,6 @@ gen6_render_video(struct sna *sna, return true; } -static bool -gen6_composite_solid_init(struct sna *sna, - struct sna_composite_channel *channel, - uint32_t color) -{ - DBG(("%s: color=%x\n", __FUNCTION__, color)); - - channel->filter = PictFilterNearest; - channel->repeat = RepeatNormal; - channel->is_affine = true; - channel->is_solid = true; - channel->is_opaque = (color >> 24) == 0xff; - channel->transform = NULL; - channel->width = 1; - channel->height = 1; - channel->card_format = GEN6_SURFACEFORMAT_B8G8R8A8_UNORM; - - channel->bo = sna_render_get_solid(sna, color); - - channel->scale[0] = channel->scale[1] = 1; - channel->offset[0] = channel->offset[1] = 0; - return channel->bo != NULL; -} - -static bool -gen6_composite_linear_init(struct sna *sna, - PicturePtr picture, - struct sna_composite_channel *channel, - int x, int y, - int w, int h, - int dst_x, int dst_y) -{ - PictLinearGradient *linear = - (PictLinearGradient *)picture->pSourcePict; - pixman_fixed_t tx, ty; - float x0, y0, sf; - float dx, dy; - - DBG(("%s: p1=(%f, %f), p2=(%f, %f), src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", - __FUNCTION__, - pixman_fixed_to_double(linear->p1.x), pixman_fixed_to_double(linear->p1.y), - pixman_fixed_to_double(linear->p2.x), pixman_fixed_to_double(linear->p2.y), - x, y, dst_x, dst_y, w, h)); - - if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y) - return 0; - - if (!sna_transform_is_affine(picture->transform)) { - DBG(("%s: fallback due to projective transform\n", - __FUNCTION__)); - return sna_render_picture_fixup(sna, picture, channel, - x, y, w, h, dst_x, dst_y); - } - - channel->bo = sna_render_get_gradient(sna, (PictGradient *)linear); - if (!channel->bo) - return 0; - - channel->filter = PictFilterNearest; - channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; - channel->width = channel->bo->pitch / 4; - channel->height = 1; - channel->pict_format = PICT_a8r8g8b8; - - channel->scale[0] = channel->scale[1] = 1; - channel->offset[0] = channel->offset[1] = 0; - - if (sna_transform_is_translation(picture->transform, &tx, &ty)) { - dx = pixman_fixed_to_double(linear->p2.x - linear->p1.x); - dy = pixman_fixed_to_double(linear->p2.y - linear->p1.y); - - x0 = pixman_fixed_to_double(linear->p1.x); - y0 = pixman_fixed_to_double(linear->p1.y); - - if (tx | ty) { - x0 -= pixman_fixed_to_double(tx); - y0 -= pixman_fixed_to_double(ty); - } - } else { - struct pixman_f_vector p1, p2; - struct pixman_f_transform m, inv; - - pixman_f_transform_from_pixman_transform(&m, picture->transform); - DBG(("%s: transform = [%f %f %f, %f %f %f, %f %f %f]\n", - __FUNCTION__, - m.m[0][0], m.m[0][1], m.m[0][2], - m.m[1][0], m.m[1][1], m.m[1][2], - m.m[2][0], m.m[2][1], m.m[2][2])); - if (!pixman_f_transform_invert(&inv, &m)) - return 0; - - p1.v[0] = pixman_fixed_to_double(linear->p1.x); - p1.v[1] = pixman_fixed_to_double(linear->p1.y); - p1.v[2] = 1.; - pixman_f_transform_point(&inv, &p1); - - p2.v[0] = pixman_fixed_to_double(linear->p2.x); - p2.v[1] = pixman_fixed_to_double(linear->p2.y); - p2.v[2] = 1.; - pixman_f_transform_point(&inv, &p2); - - DBG(("%s: untransformed: p1=(%f, %f, %f), p2=(%f, %f, %f)\n", - __FUNCTION__, - p1.v[0], p1.v[1], p1.v[2], - p2.v[0], p2.v[1], p2.v[2])); - - dx = p2.v[0] - p1.v[0]; - dy = p2.v[1] - p1.v[1]; - - x0 = p1.v[0]; - y0 = p1.v[1]; - } - - sf = dx*dx + dy*dy; - dx /= sf; - dy /= sf; - - channel->embedded_transform.matrix[0][0] = pixman_double_to_fixed(dx); - channel->embedded_transform.matrix[0][1] = pixman_double_to_fixed(dy); - channel->embedded_transform.matrix[0][2] = -pixman_double_to_fixed(dx*(x0+dst_x-x) + dy*(y0+dst_y-y)); - - channel->embedded_transform.matrix[1][0] = 0; - channel->embedded_transform.matrix[1][1] = 0; - channel->embedded_transform.matrix[1][2] = pixman_double_to_fixed(.5); - - channel->embedded_transform.matrix[2][0] = 0; - channel->embedded_transform.matrix[2][1] = 0; - channel->embedded_transform.matrix[2][2] = pixman_fixed_1; - - channel->transform = &channel->embedded_transform; - channel->is_affine = 1; - - DBG(("%s: dx=%f, dy=%f, offset=%f\n", - __FUNCTION__, dx, dy, -dx*(x0-x+dst_x) + -dy*(y0-y+dst_y))); - - return channel->bo != NULL; -} - static int gen6_composite_picture(struct sna *sna, PicturePtr picture, @@ -1760,16 +1623,16 @@ gen6_composite_picture(struct sna *sna, channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) - return gen6_composite_solid_init(sna, channel, color); + return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) - return gen6_composite_linear_init(sna, picture, channel, - x, y, - w, h, - dst_x, dst_y); + return gen4_channel_init_linear(sna, picture, channel, + x, y, + w, h, + dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; @@ -2135,7 +1998,7 @@ reuse_source(struct sna *sna, } if (sna_picture_is_solid(mask, &color)) - return gen6_composite_solid_init(sna, mc, color); + return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; @@ -2242,7 +2105,7 @@ gen6_render_composite(struct sna *sna, case -1: goto cleanup_dst; case 0: - if (!gen6_composite_solid_init(sna, &tmp->src, 0)) + if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: @@ -2295,7 +2158,7 @@ gen6_render_composite(struct sna *sna, case -1: goto cleanup_src; case 0: - if (!gen6_composite_solid_init(sna, &tmp->mask, 0)) + if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: @@ -2306,7 +2169,6 @@ gen6_render_composite(struct sna *sna, tmp->is_affine &= tmp->mask.is_affine; } - gen4_choose_composite_emitter(tmp); tmp->u.gen6.flags = GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter, @@ -2320,7 +2182,7 @@ gen6_render_composite(struct sna *sna, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine), - gen4_choose_composite_vertex_buffer(tmp)); + gen4_choose_composite_emitter(tmp)); tmp->blt = gen6_render_composite_blt; tmp->box = gen6_render_composite_box; @@ -2498,7 +2360,7 @@ gen6_render_composite_spans(struct sna *sna, case -1: goto cleanup_dst; case 0: - if (!gen6_composite_solid_init(sna, &tmp->base.src, 0)) + if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: @@ -2510,8 +2372,6 @@ gen6_render_composite_spans(struct sna *sna, tmp->base.is_affine = tmp->base.src.is_affine; tmp->base.need_magic_ca_pass = false; - gen4_choose_spans_emitter(tmp); - tmp->base.u.gen6.flags = GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter, tmp->base.src.repeat, @@ -2519,7 +2379,7 @@ gen6_render_composite_spans(struct sna *sna, SAMPLER_EXTEND_PAD), gen6_get_blend(tmp->base.op, false, tmp->base.dst.format), GEN6_WM_KERNEL_OPACITY | !tmp->base.is_affine, - gen4_choose_spans_vertex_buffer(&tmp->base)); + gen4_choose_spans_emitter(tmp)); tmp->box = gen6_render_composite_spans_box; tmp->boxes = gen6_render_composite_spans_boxes; diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index 8a1cfff5..478a2525 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -42,6 +42,7 @@ #include "brw/brw.h" #include "gen7_render.h" +#include "gen4_source.h" #include "gen4_vertex.h" #define NO_COMPOSITE 0 @@ -1727,144 +1728,6 @@ gen7_render_video(struct sna *sna, return true; } -static bool -gen7_composite_solid_init(struct sna *sna, - struct sna_composite_channel *channel, - uint32_t color) -{ - DBG(("%s: color=%x\n", __FUNCTION__, color)); - - channel->filter = PictFilterNearest; - channel->repeat = RepeatNormal; - channel->is_affine = true; - channel->is_solid = true; - channel->is_opaque = (color >> 24) == 0xff; - channel->transform = NULL; - channel->width = 1; - channel->height = 1; - channel->card_format = GEN7_SURFACEFORMAT_B8G8R8A8_UNORM; - - channel->bo = sna_render_get_solid(sna, color); - - channel->scale[0] = channel->scale[1] = 1; - channel->offset[0] = channel->offset[1] = 0; - return channel->bo != NULL; -} - -static bool -gen7_composite_linear_init(struct sna *sna, - PicturePtr picture, - struct sna_composite_channel *channel, - int x, int y, - int w, int h, - int dst_x, int dst_y) -{ - PictLinearGradient *linear = - (PictLinearGradient *)picture->pSourcePict; - pixman_fixed_t tx, ty; - float x0, y0, sf; - float dx, dy; - - DBG(("%s: p1=(%f, %f), p2=(%f, %f), src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", - __FUNCTION__, - pixman_fixed_to_double(linear->p1.x), pixman_fixed_to_double(linear->p1.y), - pixman_fixed_to_double(linear->p2.x), pixman_fixed_to_double(linear->p2.y), - x, y, dst_x, dst_y, w, h)); - - if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y) - return 0; - - if (!sna_transform_is_affine(picture->transform)) { - DBG(("%s: fallback due to projective transform\n", - __FUNCTION__)); - return sna_render_picture_fixup(sna, picture, channel, - x, y, w, h, dst_x, dst_y); - } - - channel->bo = sna_render_get_gradient(sna, (PictGradient *)linear); - if (!channel->bo) - return 0; - - channel->filter = PictFilterNearest; - channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; - channel->width = channel->bo->pitch / 4; - channel->height = 1; - channel->pict_format = PICT_a8r8g8b8; - - channel->scale[0] = channel->scale[1] = 1; - channel->offset[0] = channel->offset[1] = 0; - - if (sna_transform_is_translation(picture->transform, &tx, &ty)) { - dx = pixman_fixed_to_double(linear->p2.x - linear->p1.x); - dy = pixman_fixed_to_double(linear->p2.y - linear->p1.y); - - x0 = pixman_fixed_to_double(linear->p1.x); - y0 = pixman_fixed_to_double(linear->p1.y); - - if (tx | ty) { - x0 -= pixman_fixed_to_double(tx); - y0 -= pixman_fixed_to_double(ty); - } - } else { - struct pixman_f_vector p1, p2; - struct pixman_f_transform m, inv; - - pixman_f_transform_from_pixman_transform(&m, picture->transform); - DBG(("%s: transform = [%f %f %f, %f %f %f, %f %f %f]\n", - __FUNCTION__, - m.m[0][0], m.m[0][1], m.m[0][2], - m.m[1][0], m.m[1][1], m.m[1][2], - m.m[2][0], m.m[2][1], m.m[2][2])); - if (!pixman_f_transform_invert(&inv, &m)) - return 0; - - p1.v[0] = pixman_fixed_to_double(linear->p1.x); - p1.v[1] = pixman_fixed_to_double(linear->p1.y); - p1.v[2] = 1.; - pixman_f_transform_point(&inv, &p1); - - p2.v[0] = pixman_fixed_to_double(linear->p2.x); - p2.v[1] = pixman_fixed_to_double(linear->p2.y); - p2.v[2] = 1.; - pixman_f_transform_point(&inv, &p2); - - DBG(("%s: untransformed: p1=(%f, %f, %f), p2=(%f, %f, %f)\n", - __FUNCTION__, - p1.v[0], p1.v[1], p1.v[2], - p2.v[0], p2.v[1], p2.v[2])); - - dx = p2.v[0] - p1.v[0]; - dy = p2.v[1] - p1.v[1]; - - x0 = p1.v[0]; - y0 = p1.v[1]; - } - - sf = dx*dx + dy*dy; - dx /= sf; - dy /= sf; - - channel->embedded_transform.matrix[0][0] = pixman_double_to_fixed(dx); - channel->embedded_transform.matrix[0][1] = pixman_double_to_fixed(dy); - channel->embedded_transform.matrix[0][2] = -pixman_double_to_fixed(dx*(x0+dst_x-x) + dy*(y0+dst_y-y)); - - channel->embedded_transform.matrix[1][0] = 0; - channel->embedded_transform.matrix[1][1] = 0; - channel->embedded_transform.matrix[1][2] = pixman_double_to_fixed(.5); - - channel->embedded_transform.matrix[2][0] = 0; - channel->embedded_transform.matrix[2][1] = 0; - channel->embedded_transform.matrix[2][2] = pixman_fixed_1; - - channel->transform = &channel->embedded_transform; - channel->is_affine = 1; - - DBG(("%s: dx=%f, dy=%f, offset=%f\n", - __FUNCTION__, dx, dy, -dx*(x0-x+dst_x) + -dy*(y0-y+dst_y))); - - return channel->bo != NULL; -} - static int gen7_composite_picture(struct sna *sna, PicturePtr picture, @@ -1885,16 +1748,16 @@ gen7_composite_picture(struct sna *sna, channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) - return gen7_composite_solid_init(sna, channel, color); + return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) - return gen7_composite_linear_init(sna, picture, channel, - x, y, - w, h, - dst_x, dst_y); + return gen4_channel_init_linear(sna, picture, channel, + x, y, + w, h, + dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; @@ -2259,7 +2122,7 @@ reuse_source(struct sna *sna, } if (sna_picture_is_solid(mask, &color)) - return gen7_composite_solid_init(sna, mc, color); + return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; @@ -2366,7 +2229,7 @@ gen7_render_composite(struct sna *sna, case -1: goto cleanup_dst; case 0: - if (!gen7_composite_solid_init(sna, &tmp->src, 0)) + if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: @@ -2419,7 +2282,7 @@ gen7_render_composite(struct sna *sna, case -1: goto cleanup_src; case 0: - if (!gen7_composite_solid_init(sna, &tmp->mask, 0)) + if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: @@ -2431,8 +2294,6 @@ gen7_render_composite(struct sna *sna, tmp->is_affine &= tmp->mask.is_affine; } - gen4_choose_composite_emitter(tmp); - tmp->u.gen7.flags = GEN7_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter, tmp->src.repeat, @@ -2445,7 +2306,7 @@ gen7_render_composite(struct sna *sna, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine), - gen4_choose_composite_vertex_buffer(tmp)); + gen4_choose_composite_emitter(tmp)); tmp->blt = gen7_render_composite_blt; tmp->box = gen7_render_composite_box; @@ -2603,7 +2464,7 @@ gen7_render_composite_spans(struct sna *sna, case -1: goto cleanup_dst; case 0: - if (!gen7_composite_solid_init(sna, &tmp->base.src, 0)) + if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: @@ -2615,8 +2476,6 @@ gen7_render_composite_spans(struct sna *sna, tmp->base.is_affine = tmp->base.src.is_affine; tmp->base.need_magic_ca_pass = false; - gen4_choose_spans_emitter(tmp); - tmp->base.u.gen7.flags = GEN7_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter, tmp->base.src.repeat, @@ -2624,7 +2483,7 @@ gen7_render_composite_spans(struct sna *sna, SAMPLER_EXTEND_PAD), gen7_get_blend(tmp->base.op, false, tmp->base.dst.format), GEN7_WM_KERNEL_OPACITY | !tmp->base.is_affine, - gen4_choose_spans_vertex_buffer(&tmp->base)); + gen4_choose_spans_emitter(tmp)); tmp->box = gen7_render_composite_spans_box; tmp->boxes = gen7_render_composite_spans_boxes; diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index 55e38069..91b35688 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -69,10 +69,10 @@ struct sna_composite_op { union { struct { + float dx, dy, offset; + } linear; + struct { uint32_t pixel; - float linear_dx; - float linear_dy; - float linear_offset; } gen2; struct gen3_shader_channel { int type; |