#include "st_context.h"
#include "pipe/p_context.h"
#include "st_atom.h"
+#include "st_util.h"
/**
* Scissor depends on the scissor box, and the framebuffer dimensions.
*/
-static void
-update_scissor( struct st_context *st )
+void
+st_update_scissor( struct st_context *st )
{
struct pipe_scissor_state scissor[PIPE_MAX_VIEWPORTS];
const struct gl_context *ctx = st->ctx;
unsigned i;
bool changed = false;
- for (i = 0 ; i < ctx->Const.MaxViewports; i++) {
+ if (!ctx->Scissor.EnableFlags)
+ return;
+
+ for (i = 0 ; i < st->state.num_viewports; i++) {
scissor[i].minx = 0;
scissor[i].miny = 0;
scissor[i].maxx = fb_width;
/* Now invert Y if needed.
* Gallium drivers use the convention Y=0=top for surfaces.
*/
- if (st_fb_orientation(fb) == Y_0_TOP) {
+ if (st->state.fb_orientation == Y_0_TOP) {
miny = fb->Height - scissor[i].maxy;
maxy = fb->Height - scissor[i].miny;
scissor[i].miny = miny;
changed = true;
}
}
- if (changed)
- st->pipe->set_scissor_states(st->pipe, 0, ctx->Const.MaxViewports, scissor); /* activate */
+
+ if (changed) {
+ struct pipe_context *pipe = st->pipe;
+
+ pipe->set_scissor_states(pipe, 0, st->state.num_viewports, scissor);
+ }
}
+void
+st_update_window_rectangles(struct st_context *st)
+{
+ struct pipe_scissor_state new_rects[PIPE_MAX_WINDOW_RECTANGLES];
+ const struct gl_context *ctx = st->ctx;
+ const struct gl_scissor_attrib *scissor = &ctx->Scissor;
+ unsigned i;
+ bool changed = false;
+ unsigned num_rects = scissor->NumWindowRects;
+ bool include = scissor->WindowRectMode == GL_INCLUSIVE_EXT;
-const struct st_tracked_state st_update_scissor = {
- "st_update_scissor", /* name */
- { /* dirty */
- (_NEW_SCISSOR | _NEW_BUFFERS), /* mesa */
- 0, /* st */
- },
- update_scissor /* update */
-};
+ if (ctx->DrawBuffer == ctx->WinSysDrawBuffer) {
+ num_rects = 0;
+ include = false;
+ }
+ for (i = 0; i < num_rects; i++) {
+ const struct gl_scissor_rect *rect = &scissor->WindowRects[i];
+ new_rects[i].minx = MAX2(rect->X, 0);
+ new_rects[i].miny = MAX2(rect->Y, 0);
+ new_rects[i].maxx = MAX2(rect->X + rect->Width, 0);
+ new_rects[i].maxy = MAX2(rect->Y + rect->Height, 0);
+ }
+ if (num_rects > 0 && memcmp(new_rects, st->state.window_rects.rects,
+ num_rects * sizeof(struct pipe_scissor_state))) {
+ memcpy(st->state.window_rects.rects, new_rects,
+ num_rects * sizeof(struct pipe_scissor_state));
+ changed = true;
+ }
+ if (st->state.window_rects.num != num_rects) {
+ st->state.window_rects.num = num_rects;
+ changed = true;
+ }
+ if (st->state.window_rects.include != include) {
+ st->state.window_rects.include = include;
+ changed = true;
+ }
+ if (changed)
+ st->pipe->set_window_rectangles(
+ st->pipe, include, num_rects, new_rects);
+}