13a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**************************************************************************
23a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
33a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
43a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * All Rights Reserved.
53a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
63a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
73a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * copy of this software and associated documentation files (the
83a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * "Software"), to deal in the Software without restriction, including
93a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * permit persons to whom the Software is furnished to do so, subject to
123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * the following conditions:
133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * The above copyright notice and this permission notice (including the
153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * next paragraph) shall be included in all copies or substantial portions
163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * of the Software.
173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org *
263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org **************************************************************************/
273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/* Implement line stipple by cutting lines up into smaller lines.
323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * There are hundreds of ways to implement line stipple, this is one
333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * choice that should work in all situations, requires no state
343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * manipulations, but with a penalty in terms of large amounts of
353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * generated geometry.
363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "pipe/p_defines.h"
403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "pipe/p_shader_tokens.h"
413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "util/u_math.h"
423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "util/u_memory.h"
433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org#include "draw/draw_pipe.h"
453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/** Subclass of draw_stage */
483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct stipple_stage {
493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct draw_stage stage;
503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float counter;
513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   uint pattern;
523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   uint factor;
533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org};
543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic INLINE struct stipple_stage *
573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_stage(struct draw_stage *stage)
583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return (struct stipple_stage *) stage;
603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Compute interpolated vertex attributes for 'dst' at position 't'
653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * between 'v0' and 'v1'.
663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * XXX using linear interpolation for all attribs at this time.
673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgscreen_interp( struct draw_context *draw,
703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               struct vertex_header *dst,
713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               float t,
723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               const struct vertex_header *v0,
733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               const struct vertex_header *v1 )
743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   uint attr;
76760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   int num_outputs = draw_current_shader_outputs(draw);
77760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   for (attr = 0; attr < num_outputs; attr++) {
783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      const float *val0 = v0->data[attr];
793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      const float *val1 = v1->data[attr];
803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      float *newv = dst->data[attr];
813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      uint i;
823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      for (i = 0; i < 4; i++) {
833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         newv[i] = val0[i] + t * (val1[i] - val0[i]);
843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgemit_segment(struct draw_stage *stage, struct prim_header *header,
913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org             float t0, float t1)
923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct vertex_header *v0new = dup_vert(stage, header->v[0], 0);
943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct vertex_header *v1new = dup_vert(stage, header->v[1], 1);
953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct prim_header newprim = *header;
963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (t0 > 0.0) {
983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] );
993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      newprim.v[0] = v0new;
1003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (t1 < 1.0) {
1033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] );
1043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      newprim.v[1] = v1new;
1053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->next->line( stage->next, &newprim );
1083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic INLINE unsigned
1123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_test(int counter, ushort pattern, int factor)
1133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   int b = (counter / factor) & 0xf;
1153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return (1 << b) & pattern;
1163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
1203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_line(struct draw_stage *stage, struct prim_header *header)
1213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct stipple_stage *stipple = stipple_stage(stage);
1233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct vertex_header *v0 = header->v[0];
1243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct vertex_header *v1 = header->v[1];
125760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   const unsigned pos = draw_current_shader_position_output(stage->draw);
1263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   const float *pos0 = v0->data[pos];
1273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   const float *pos1 = v1->data[pos];
1283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float start = 0;
1293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   int state = 0;
1303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float x0 = pos0[0];
1323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float x1 = pos1[0];
1333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float y0 = pos0[1];
1343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float y1 = pos1[1];
1353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float dx = x0 > x1 ? x0 - x1 : x1 - x0;
1373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float dy = y0 > y1 ? y0 - y1 : y1 - y0;
1383a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1393a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   float length = MAX2(dx, dy);
1403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   int i;
1413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (header->flags & DRAW_PIPE_RESET_STIPPLE)
1433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      stipple->counter = 0;
1443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table.
1473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org    */
1483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   for (i = 0; i < length; i++) {
1493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      int result = stipple_test( (int) stipple->counter+i,
1503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org                                 (ushort) stipple->pattern, stipple->factor );
1513a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      if (result != state) {
1523a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org         /* changing from "off" to "on" or vice versa */
1533a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	 if (state) {
1543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	    if (start != i) {
1553a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org               /* finishing an "on" segment */
1563a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	       emit_segment( stage, header, start / length, i / length );
1573a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            }
1583a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	 }
1593a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	 else {
1603a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org            /* starting an "on" segment */
1613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	    start = (float) i;
1623a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	 }
1633a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org	 state = result;
1643a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      }
1653a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   }
1663a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1673a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   if (state && start < length)
1683a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org      emit_segment( stage, header, start / length, 1.0 );
1693a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1703a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->counter += length;
1713a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1723a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1733a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1743a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
1753a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgreset_stipple_counter(struct draw_stage *stage)
1763a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1773a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct stipple_stage *stipple = stipple_stage(stage);
1783a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->counter = 0;
1793a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->next->reset_stipple_counter( stage->next );
1803a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1813a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1823a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
1833a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_reset_point(struct draw_stage *stage, struct prim_header *header)
1843a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1853a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct stipple_stage *stipple = stipple_stage(stage);
1863a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->counter = 0;
1873a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->next->point(stage->next, header);
1883a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1893a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1903a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
1913a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_reset_tri(struct draw_stage *stage, struct prim_header *header)
1923a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
1933a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct stipple_stage *stipple = stipple_stage(stage);
1943a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->counter = 0;
1953a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->next->tri(stage->next, header);
1963a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
1973a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1983a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
1993a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
2003a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_first_line(struct draw_stage *stage,
2013a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org		   struct prim_header *header)
2023a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2033a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct stipple_stage *stipple = stipple_stage(stage);
2043a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct draw_context *draw = stage->draw;
2053a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2063a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->pattern = draw->rasterizer->line_stipple_pattern;
2073a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->factor = draw->rasterizer->line_stipple_factor + 1;
2083a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2093a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->line = stipple_line;
2103a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->line( stage, header );
2113a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2123a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2133a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2143a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
2153a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_flush(struct draw_stage *stage, unsigned flags)
2163a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2173a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->line = stipple_first_line;
2183a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stage->next->flush( stage->next, flags );
2193a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2203a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2213a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2223a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2233a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2243a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstatic void
2253a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstipple_destroy( struct draw_stage *stage )
2263a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2273a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   draw_free_temp_verts( stage );
2283a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   FREE( stage );
2293a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
2303a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2313a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2323a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org/**
2333a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org * Create line stippler stage
2343a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org */
2353a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.orgstruct draw_stage *draw_stipple_stage( struct draw_context *draw )
2363a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org{
2373a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage);
238760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (stipple == NULL)
239760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      goto fail;
2403a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
2413a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.draw = draw;
2423a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.name = "stipple";
2433a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.next = NULL;
2443a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.point = stipple_reset_point;
2453a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.line = stipple_first_line;
2463a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.tri = stipple_reset_tri;
2473a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.reset_stipple_counter = reset_stipple_counter;
2483a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.flush = stipple_flush;
2493a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   stipple->stage.destroy = stipple_destroy;
2503a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org
251760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (!draw_alloc_temp_verts( &stipple->stage, 2 ))
252760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      goto fail;
253760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
2543a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org   return &stipple->stage;
255760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
256760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgfail:
257760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   if (stipple)
258760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org      stipple->stage.destroy( &stipple->stage );
259760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org
260760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org   return NULL;
2613a0db227ffe90888ad760c61a63226988c974e0apatrick@chromium.org}
262