#include "main/glheader.h"
#include "main/context.h"
+#include "main/enums.h"
#include "main/mtypes.h"
#include "main/scissor.h"
height == ctx->Scissor.ScissorArray[idx].Height)
return;
- FLUSH_VERTICES(ctx, _NEW_SCISSOR);
+ FLUSH_VERTICES(ctx, ctx->DriverFlags.NewScissorRect ? 0 : _NEW_SCISSOR);
+ ctx->NewDriverState |= ctx->DriverFlags.NewScissorRect;
+
ctx->Scissor.ScissorArray[idx].X = x;
ctx->Scissor.ScissorArray[idx].Y = y;
ctx->Scissor.ScissorArray[idx].Width = width;
ctx->Scissor.ScissorArray[idx].Height = height;
}
-/**
- * Called via glScissor
- */
-void GLAPIENTRY
-_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height )
+static void
+scissor(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height)
{
unsigned i;
- GET_CURRENT_CONTEXT(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height);
-
- if (width < 0 || height < 0) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" );
- return;
- }
/* The GL_ARB_viewport_array spec says:
*
ctx->Driver.Scissor(ctx);
}
+/**
+ * Called via glScissor
+ */
+void GLAPIENTRY
+_mesa_Scissor_no_error(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ scissor(ctx, x, y, width, height);
+}
+
+void GLAPIENTRY
+_mesa_Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height);
+
+ if (width < 0 || height < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" );
+ return;
+ }
+
+ scissor(ctx, x, y, width, height);
+}
+
/**
* Define the scissor box.
ctx->Driver.Scissor(ctx);
}
+static void
+scissor_array(struct gl_context *ctx, GLuint first, GLsizei count,
+ struct gl_scissor_rect *rect)
+{
+ for (GLsizei i = 0; i < count; i++) {
+ set_scissor_no_notify(ctx, i + first, rect[i].X, rect[i].Y,
+ rect[i].Width, rect[i].Height);
+ }
+
+ if (ctx->Driver.Scissor)
+ ctx->Driver.Scissor(ctx);
+}
+
/**
* Define count scissor boxes starting at index.
*
*
* Verifies the parameters and call set_scissor_no_notify to do the work.
*/
+void GLAPIENTRY
+_mesa_ScissorArrayv_no_error(GLuint first, GLsizei count, const GLint *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_scissor_rect *p = (struct gl_scissor_rect *)v;
+ scissor_array(ctx, first, count, p);
+}
+
void GLAPIENTRY
_mesa_ScissorArrayv(GLuint first, GLsizei count, const GLint *v)
{
}
}
- for (i = 0; i < count; i++)
- set_scissor_no_notify(ctx, i + first,
- p[i].X, p[i].Y, p[i].Width, p[i].Height);
-
- if (ctx->Driver.Scissor)
- ctx->Driver.Scissor(ctx);
+ scissor_array(ctx, first, count, p);
}
/**
* Verifies the parameters call set_scissor_no_notify to do the work.
*/
static void
-ScissorIndexed(GLuint index, GLint left, GLint bottom,
- GLsizei width, GLsizei height, const char *function)
+scissor_indexed_err(struct gl_context *ctx, GLuint index, GLint left,
+ GLint bottom, GLsizei width, GLsizei height,
+ const char *function)
{
- GET_CURRENT_CONTEXT(ctx);
-
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "%s(%d, %d, %d, %d, %d)\n",
function, index, left, bottom, width, height);
return;
}
- set_scissor_no_notify(ctx, index, left, bottom, width, height);
+ _mesa_set_scissor(ctx, index, left, bottom, width, height);
+}
- if (ctx->Driver.Scissor)
- ctx->Driver.Scissor(ctx);
+void GLAPIENTRY
+_mesa_ScissorIndexed_no_error(GLuint index, GLint left, GLint bottom,
+ GLsizei width, GLsizei height)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_set_scissor(ctx, index, left, bottom, width, height);
}
void GLAPIENTRY
_mesa_ScissorIndexed(GLuint index, GLint left, GLint bottom,
GLsizei width, GLsizei height)
{
- ScissorIndexed(index, left, bottom, width, height, "glScissorIndexd");
+ GET_CURRENT_CONTEXT(ctx);
+ scissor_indexed_err(ctx, index, left, bottom, width, height,
+ "glScissorIndexed");
+}
+
+void GLAPIENTRY
+_mesa_ScissorIndexedv_no_error(GLuint index, const GLint *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_set_scissor(ctx, index, v[0], v[1], v[2], v[3]);
}
void GLAPIENTRY
_mesa_ScissorIndexedv(GLuint index, const GLint *v)
{
- ScissorIndexed(index, v[0], v[1], v[2], v[3], "glScissorIndexdv");
+ GET_CURRENT_CONTEXT(ctx);
+ scissor_indexed_err(ctx, index, v[0], v[1], v[2], v[3],
+ "glScissorIndexedv");
+}
+
+void GLAPIENTRY
+_mesa_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box)
+{
+ int i;
+ struct gl_scissor_rect newval[MAX_WINDOW_RECTANGLES];
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glWindowRectanglesEXT(%s, %d, %p)\n",
+ _mesa_enum_to_string(mode), count, box);
+
+ if (mode != GL_INCLUSIVE_EXT && mode != GL_EXCLUSIVE_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glWindowRectanglesEXT(invalid mode 0x%x)", mode);
+ return;
+ }
+
+ if (count < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glWindowRectanglesEXT(count < 0)");
+ return;
+ }
+
+ if (count > ctx->Const.MaxWindowRectangles) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glWindowRectanglesEXT(count >= MaxWindowRectangles (%d)",
+ ctx->Const.MaxWindowRectangles);
+ return;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (box[2] < 0 || box[3] < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glWindowRectanglesEXT(box %d: w < 0 || h < 0)", i);
+ return;
+ }
+ newval[i].X = box[0];
+ newval[i].Y = box[1];
+ newval[i].Width = box[2];
+ newval[i].Height = box[3];
+ box += 4;
+ }
+
+ FLUSH_VERTICES(ctx, 0);
+ ctx->NewDriverState |= ctx->DriverFlags.NewWindowRectangles;
+
+ memcpy(ctx->Scissor.WindowRects, newval,
+ sizeof(struct gl_scissor_rect) * count);
+ ctx->Scissor.NumWindowRects = count;
+ ctx->Scissor.WindowRectMode = mode;
}
+
/**
* Initialize the context's scissor state.
* \param ctx the GL context.
/* Scissor group */
ctx->Scissor.EnableFlags = 0;
+ ctx->Scissor.WindowRectMode = GL_EXCLUSIVE_EXT;
/* Note: ctx->Const.MaxViewports may not have been set by the driver yet,
* so just initialize all of them.