Before: DrawElements (1 VBO, 8 UBO, 8 Tex) w/ viewport change: 3.61 million (43.7%)
After: DrawElements (1 VBO, 8 UBO, 8 Tex) w/ viewport change: 4.95 million (60.2%) Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com> --- src/mesa/main/viewport.c | 89 +++++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c index fc384909e6..ac23f2b93a 100644 --- a/src/mesa/main/viewport.c +++ b/src/mesa/main/viewport.c @@ -35,6 +35,36 @@ #include "mtypes.h" #include "viewport.h" +static bool +is_viewport_equal(struct gl_context *ctx, unsigned idx, + GLfloat x, GLfloat y, GLfloat width, GLfloat height) +{ + return ctx->ViewportArray[idx].X == x && + ctx->ViewportArray[idx].Width == width && + ctx->ViewportArray[idx].Y == y && + ctx->ViewportArray[idx].Height == height; +} + +static void +set_new_viewport(struct gl_context *ctx, unsigned idx, + GLfloat x, GLfloat y, GLfloat width, GLfloat height) +{ + ctx->ViewportArray[idx].X = x; + ctx->ViewportArray[idx].Width = width; + ctx->ViewportArray[idx].Y = y; + ctx->ViewportArray[idx].Height = height; +} + +static void +flush_viewport(struct gl_context *ctx) +{ + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewViewport ? 0 : _NEW_VIEWPORT); + ctx->NewDriverState |= ctx->DriverFlags.NewViewport; + + if (ctx->Driver.Viewport) + ctx->Driver.Viewport(ctx); +} + static void clamp_viewport(struct gl_context *ctx, GLfloat *x, GLfloat *y, GLfloat *width, GLfloat *height) @@ -61,26 +91,6 @@ clamp_viewport(struct gl_context *ctx, GLfloat *x, GLfloat *y, } } -static void -set_viewport_no_notify(struct gl_context *ctx, unsigned idx, - GLfloat x, GLfloat y, - GLfloat width, GLfloat height) -{ - if (ctx->ViewportArray[idx].X == x && - ctx->ViewportArray[idx].Width == width && - ctx->ViewportArray[idx].Y == y && - ctx->ViewportArray[idx].Height == height) - return; - - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewViewport ? 0 : _NEW_VIEWPORT); - ctx->NewDriverState |= ctx->DriverFlags.NewViewport; - - ctx->ViewportArray[idx].X = x; - ctx->ViewportArray[idx].Width = width; - ctx->ViewportArray[idx].Y = y; - ctx->ViewportArray[idx].Height = height; -} - struct gl_viewport_inputs { GLfloat X, Y; /**< position */ GLfloat Width, Height; /**< size */ @@ -95,6 +105,7 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height) { struct gl_viewport_inputs input = { x, y, width, height }; + bool changed = false; /* Clamp the viewport to the implementation dependent values. */ clamp_viewport(ctx, &input.X, &input.Y, &input.Width, &input.Height); @@ -110,11 +121,17 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width, * Set all of the viewports supported by the implementation, but only * signal the driver once at the end. */ - for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) - set_viewport_no_notify(ctx, i, input.X, input.Y, input.Width, input.Height); + for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) { + if (!changed && is_viewport_equal(ctx, i, input.X, input.Y, + input.Width, input.Height)) + continue; - if (ctx->Driver.Viewport) - ctx->Driver.Viewport(ctx); + changed = true; + set_new_viewport(ctx, i, x, y, width, height); + } + + if (changed) + flush_viewport(ctx); } /** @@ -164,26 +181,36 @@ _mesa_set_viewport(struct gl_context *ctx, unsigned idx, GLfloat x, GLfloat y, GLfloat width, GLfloat height) { clamp_viewport(ctx, &x, &y, &width, &height); - set_viewport_no_notify(ctx, idx, x, y, width, height); - if (ctx->Driver.Viewport) - ctx->Driver.Viewport(ctx); + if (is_viewport_equal(ctx, idx, x, y, width, height)) + return; + + set_new_viewport(ctx, idx, x, y, width, height); + flush_viewport(ctx); } static void viewport_array(struct gl_context *ctx, GLuint first, GLsizei count, struct gl_viewport_inputs *inputs) { + bool changed = false; + for (GLsizei i = 0; i < count; i++) { clamp_viewport(ctx, &inputs[i].X, &inputs[i].Y, &inputs[i].Width, &inputs[i].Height); - set_viewport_no_notify(ctx, i + first, inputs[i].X, inputs[i].Y, - inputs[i].Width, inputs[i].Height); + if (!changed && is_viewport_equal(ctx, i + first, + inputs[i].X, inputs[i].Y, + inputs[i].Width, inputs[i].Height)) + continue; + + changed = true; + set_new_viewport(ctx, i + first, inputs[i].X, inputs[i].Y, + inputs[i].Width, inputs[i].Height); } - if (ctx->Driver.Viewport) - ctx->Driver.Viewport(ctx); + if (changed) + flush_viewport(ctx); } void GLAPIENTRY -- 2.13.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev