2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
26 #include "main/glheader.h"
27 #include "main/context.h"
28 #include "main/mtypes.h"
29 #include "main/scissor.h"
33 * Set scissor rectangle data directly in ScissorArray
35 * This is an internal function that performs no error checking on the
36 * supplied data. It also does \b not call \c dd_function_table::Scissor.
38 * \sa _mesa_set_scissor
41 set_scissor_no_notify(struct gl_context
*ctx
, unsigned idx
,
42 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
44 if (x
== ctx
->Scissor
.ScissorArray
[idx
].X
&&
45 y
== ctx
->Scissor
.ScissorArray
[idx
].Y
&&
46 width
== ctx
->Scissor
.ScissorArray
[idx
].Width
&&
47 height
== ctx
->Scissor
.ScissorArray
[idx
].Height
)
50 FLUSH_VERTICES(ctx
, _NEW_SCISSOR
);
51 ctx
->Scissor
.ScissorArray
[idx
].X
= x
;
52 ctx
->Scissor
.ScissorArray
[idx
].Y
= y
;
53 ctx
->Scissor
.ScissorArray
[idx
].Width
= width
;
54 ctx
->Scissor
.ScissorArray
[idx
].Height
= height
;
58 * Called via glScissor
61 _mesa_Scissor( GLint x
, GLint y
, GLsizei width
, GLsizei height
)
64 GET_CURRENT_CONTEXT(ctx
);
66 if (MESA_VERBOSE
& VERBOSE_API
)
67 _mesa_debug(ctx
, "glScissor %d %d %d %d\n", x
, y
, width
, height
);
69 if (width
< 0 || height
< 0) {
70 _mesa_error( ctx
, GL_INVALID_VALUE
, "glScissor" );
74 /* The GL_ARB_viewport_array spec says:
76 * "Scissor sets the scissor rectangle for all viewports to the same
77 * values and is equivalent (assuming no errors are generated) to:
79 * for (uint i = 0; i < MAX_VIEWPORTS; i++) {
80 * ScissorIndexed(i, left, bottom, width, height);
83 * Set the scissor rectangle for all of the viewports supported by the
84 * implementation, but only signal the driver once at the end.
86 for (i
= 0; i
< ctx
->Const
.MaxViewports
; i
++)
87 set_scissor_no_notify(ctx
, i
, x
, y
, width
, height
);
89 if (ctx
->Driver
.Scissor
)
90 ctx
->Driver
.Scissor(ctx
);
95 * Define the scissor box.
97 * \param x, y coordinates of the scissor box lower-left corner.
98 * \param width width of the scissor box.
99 * \param height height of the scissor box.
103 * Verifies the parameters and updates __struct gl_contextRec::Scissor. On a
104 * change flushes the vertices and notifies the driver via
105 * the dd_function_table::Scissor callback.
108 _mesa_set_scissor(struct gl_context
*ctx
, unsigned idx
,
109 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
111 set_scissor_no_notify(ctx
, idx
, x
, y
, width
, height
);
113 if (ctx
->Driver
.Scissor
)
114 ctx
->Driver
.Scissor(ctx
);
118 * Define count scissor boxes starting at index.
120 * \param index index of first scissor records to set
121 * \param count number of scissor records to set
122 * \param x, y pointer to array of struct gl_scissor_rects
124 * \sa glScissorArrayv().
126 * Verifies the parameters and call set_scissor_no_notify to do the work.
129 _mesa_ScissorArrayv(GLuint first
, GLsizei count
, const GLint
*v
)
132 struct gl_scissor_rect
*p
= (struct gl_scissor_rect
*) v
;
133 GET_CURRENT_CONTEXT(ctx
);
135 if ((first
+ count
) > ctx
->Const
.MaxViewports
) {
136 _mesa_error(ctx
, GL_INVALID_VALUE
,
137 "glScissorArrayv: first (%d) + count (%d) >= MaxViewports (%d)",
138 first
, count
, ctx
->Const
.MaxViewports
);
142 /* Verify width & height */
143 for (i
= 0; i
< count
; i
++) {
144 if (p
[i
].Width
< 0 || p
[i
].Height
< 0) {
145 _mesa_error(ctx
, GL_INVALID_VALUE
,
146 "glScissorArrayv: index (%d) width or height < 0 (%d, %d)",
147 i
, p
[i
].Width
, p
[i
].Height
);
152 for (i
= 0; i
< count
; i
++)
153 set_scissor_no_notify(ctx
, i
+ first
,
154 p
[i
].X
, p
[i
].Y
, p
[i
].Width
, p
[i
].Height
);
156 if (ctx
->Driver
.Scissor
)
157 ctx
->Driver
.Scissor(ctx
);
161 * Define the scissor box.
163 * \param index index of scissor records to set
164 * \param x, y coordinates of the scissor box lower-left corner.
165 * \param width width of the scissor box.
166 * \param height height of the scissor box.
168 * Verifies the parameters call set_scissor_no_notify to do the work.
171 ScissorIndexed(GLuint index
, GLint left
, GLint bottom
,
172 GLsizei width
, GLsizei height
, const char *function
)
174 GET_CURRENT_CONTEXT(ctx
);
176 if (MESA_VERBOSE
& VERBOSE_API
)
177 _mesa_debug(ctx
, "%s(%d, %d, %d, %d, %d)\n",
178 function
, index
, left
, bottom
, width
, height
);
180 if (index
>= ctx
->Const
.MaxViewports
) {
181 _mesa_error(ctx
, GL_INVALID_VALUE
,
182 "%s: index (%d) >= MaxViewports (%d)",
183 function
, index
, ctx
->Const
.MaxViewports
);
187 if (width
< 0 || height
< 0) {
188 _mesa_error(ctx
, GL_INVALID_VALUE
,
189 "%s: index (%d) width or height < 0 (%d, %d)",
190 function
, index
, width
, height
);
194 set_scissor_no_notify(ctx
, index
, left
, bottom
, width
, height
);
196 if (ctx
->Driver
.Scissor
)
197 ctx
->Driver
.Scissor(ctx
);
201 _mesa_ScissorIndexed(GLuint index
, GLint left
, GLint bottom
,
202 GLsizei width
, GLsizei height
)
204 ScissorIndexed(index
, left
, bottom
, width
, height
, "glScissorIndexd");
208 _mesa_ScissorIndexedv(GLuint index
, const GLint
*v
)
210 ScissorIndexed(index
, v
[0], v
[1], v
[2], v
[3], "glScissorIndexdv");
214 * Initialize the context's scissor state.
215 * \param ctx the GL context.
218 _mesa_init_scissor(struct gl_context
*ctx
)
223 ctx
->Scissor
.EnableFlags
= 0;
225 /* Note: ctx->Const.MaxViewports may not have been set by the driver yet,
226 * so just initialize all of them.
228 for (i
= 0; i
< MAX_VIEWPORTS
; i
++)
229 set_scissor_no_notify(ctx
, i
, 0, 0, 0, 0);