replace _mesa_logbase2 with util_logbase2
[mesa.git] / src / mesa / state_tracker / st_atom_scissor.c
index 605d5cba9e7cebac3e14c60b940943fa991e271b..f0546df6cb3b2fee1311314f886a7bfd31fef5d4 100644 (file)
 #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;
@@ -53,7 +54,10 @@ update_scissor( struct st_context *st )
    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;
@@ -82,7 +86,7 @@ update_scissor( struct st_context *st )
       /* 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;
@@ -95,16 +99,51 @@ update_scissor( struct st_context *st )
          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);
+}