X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_manager.c;h=4ef5429c58baf752f75b9deb109a6ad8aa7d577b;hb=f986741a91b80091b510752b707a82f5b19440ee;hp=73729d745455916352ab0fa7f5c4d45c264b2198;hpb=bc5adc27b5e52d27eca6a61ad1e049b160570c98;p=mesa.git diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index 73729d74545..4ef5429c58b 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -173,6 +173,26 @@ st_context_validate(struct st_context *st, } +void +st_set_ws_renderbuffer_surface(struct st_renderbuffer *strb, + struct pipe_surface *surf) +{ + pipe_surface_reference(&strb->surface_srgb, NULL); + pipe_surface_reference(&strb->surface_linear, NULL); + + if (util_format_is_srgb(surf->format)) + pipe_surface_reference(&strb->surface_srgb, surf); + else + pipe_surface_reference(&strb->surface_linear, surf); + + strb->surface = surf; /* just assign, don't ref */ + pipe_resource_reference(&strb->texture, surf->texture); + + strb->Base.Width = surf->width; + strb->Base.Height = surf->height; +} + + /** * Validate a framebuffer to make sure up-to-date pipe_textures are used. * The context is only used for creating pipe surfaces and for calling @@ -188,7 +208,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; uint width, height; unsigned i; - boolean changed = FALSE; + bool changed = false; int32_t new_stamp; new_stamp = p_atomic_read(&stfb->iface->stamp); @@ -234,20 +254,10 @@ st_framebuffer_validate(struct st_framebuffer *stfb, u_surface_default_template(&surf_tmpl, textures[i]); ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl); if (ps) { - struct pipe_surface **psurf = - util_format_is_srgb(ps->format) ? &strb->surface_srgb : - &strb->surface_linear; - - pipe_surface_reference(psurf, ps); - strb->surface = *psurf; - pipe_resource_reference(&strb->texture, ps->texture); - /* ownership transfered */ + st_set_ws_renderbuffer_surface(strb, ps); pipe_surface_reference(&ps, NULL); - changed = TRUE; - - strb->Base.Width = strb->surface->width; - strb->Base.Height = strb->surface->height; + changed = true; width = strb->Base.Width; height = strb->Base.Height; @@ -293,13 +303,13 @@ st_framebuffer_update_attachments(struct st_framebuffer *stfb) * Add a renderbuffer to the framebuffer. The framebuffer is one that * corresponds to a window and is not a user-created FBO. */ -static boolean +static bool st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb, - gl_buffer_index idx) + gl_buffer_index idx, bool prefer_srgb) { struct gl_renderbuffer *rb; enum pipe_format format; - boolean sw; + bool sw; assert(_mesa_is_winsys_fbo(&stfb->Base)); @@ -310,30 +320,30 @@ st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb, switch (idx) { case BUFFER_DEPTH: format = stfb->iface->visual->depth_stencil_format; - sw = FALSE; + sw = false; break; case BUFFER_ACCUM: format = stfb->iface->visual->accum_format; - sw = TRUE; + sw = true; break; default: format = stfb->iface->visual->color_format; - if (stfb->Base.Visual.sRGBCapable) + if (prefer_srgb) format = util_format_srgb(format); - sw = FALSE; + sw = false; break; } if (format == PIPE_FORMAT_NONE) - return FALSE; + return false; rb = st_new_renderbuffer_fb(format, stfb->iface->visual->samples, sw); if (!rb) - return FALSE; + return false; if (idx != BUFFER_DEPTH) { _mesa_attach_and_own_rb(&stfb->Base, idx, rb); - return TRUE; + return true; } bool rb_ownership_taken = false; @@ -349,7 +359,7 @@ st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb, _mesa_attach_and_own_rb(&stfb->Base, BUFFER_STENCIL, rb); } - return TRUE; + return true; } @@ -436,6 +446,7 @@ st_framebuffer_create(struct st_context *st, struct st_framebuffer *stfb; struct gl_config mode; gl_buffer_index idx; + bool prefer_srgb = false; if (!stfbi) return NULL; @@ -457,14 +468,15 @@ st_framebuffer_create(struct st_context *st, * format such that util_format_srgb(visual->color_format) can be supported * by the pipe driver. We still need to advertise the capability here. * - * For GLES, however, sRGB framebuffer write is controlled only by the - * capability of the framebuffer. There is GL_EXT_sRGB_write_control to - * give applications the control back, but sRGB write is still enabled by - * default. To avoid unexpected results, we should not advertise the - * capability. This could change when we add support for - * EGL_KHR_gl_colorspace. + * For GLES, however, sRGB framebuffer write is initially only controlled + * by the capability of the framebuffer, with GL_EXT_sRGB_write_control + * control is given back to the applications, but GL_FRAMEBUFFER_SRGB is + * still enabled by default since this is the behaviour when + * EXT_sRGB_write_control is not available. Since GL_EXT_sRGB_write_control + * brings GLES on par with desktop GLs EXT_framebuffer_sRGB, in mesa this + * is also expressed by using the same extension flag */ - if (_mesa_is_desktop_gl(st->ctx)) { + if (_mesa_has_EXT_framebuffer_sRGB(st->ctx)) { struct pipe_screen *screen = st->pipe->screen; const enum pipe_format srgb_format = util_format_srgb(stfbi->visual->color_format); @@ -475,8 +487,14 @@ st_framebuffer_create(struct st_context *st, PIPE_TEXTURE_2D, stfbi->visual->samples, stfbi->visual->samples, (PIPE_BIND_DISPLAY_TARGET | - PIPE_BIND_RENDER_TARGET))) + PIPE_BIND_RENDER_TARGET))) { mode.sRGBCapable = GL_TRUE; + /* Since GL_FRAMEBUFFER_SRGB is enabled by default on GLES we must not + * create renderbuffers with an sRGB format derived from the + * visual->color_format, but we still want sRGB for desktop GL. + */ + prefer_srgb = _mesa_is_desktop_gl(st->ctx); + } } _mesa_initialize_window_framebuffer(&stfb->Base, &mode); @@ -487,13 +505,13 @@ st_framebuffer_create(struct st_context *st, /* add the color buffer */ idx = stfb->Base._ColorDrawBufferIndexes[0]; - if (!st_framebuffer_add_renderbuffer(stfb, idx)) { + if (!st_framebuffer_add_renderbuffer(stfb, idx, prefer_srgb)) { free(stfb); return NULL; } - st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH); - st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM); + st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH, false); + st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM, false); stfb->stamp = 0; st_framebuffer_update_attachments(stfb); @@ -528,7 +546,7 @@ st_framebuffer_iface_equal(const void *a, const void *b) } -static boolean +static bool st_framebuffer_iface_lookup(struct st_manager *smapi, const struct st_framebuffer_iface *stfbi) { @@ -547,7 +565,7 @@ st_framebuffer_iface_lookup(struct st_manager *smapi, } -static boolean +static bool st_framebuffer_iface_insert(struct st_manager *smapi, struct st_framebuffer_iface *stfbi) { @@ -672,11 +690,11 @@ st_context_flush(struct st_context_iface *stctxi, unsigned flags, st->gfx_shaders_may_be_dirty = true; } -static boolean +static bool st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type tex_type, int level, enum pipe_format pipe_format, - struct pipe_resource *tex, boolean mipmap) + struct pipe_resource *tex, bool mipmap) { struct st_context *st = (struct st_context *) stctxi; struct gl_context *ctx = st->ctx; @@ -760,7 +778,7 @@ st_context_teximage(struct st_context_iface *stctxi, _mesa_dirty_texobj(ctx, texObj); _mesa_unlock_texture(ctx, texObj); - return TRUE; + return true; } @@ -775,7 +793,7 @@ st_context_copy(struct st_context_iface *stctxi, } -static boolean +static bool st_context_share(struct st_context_iface *stctxi, struct st_context_iface *stsrci) { @@ -1035,14 +1053,14 @@ st_framebuffer_reuse_or_create(struct st_context *st, } -static boolean +static bool st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, struct st_framebuffer_iface *stdrawi, struct st_framebuffer_iface *streadi) { struct st_context *st = (struct st_context *) stctxi; struct st_framebuffer *stdraw, *stread; - boolean ret; + bool ret; if (st) { /* reuse or create the draw fb */ @@ -1085,6 +1103,18 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, st_framebuffers_purge(st); } else { + GET_CURRENT_CONTEXT(ctx); + + if (ctx) { + /* Before releasing the context, release its associated + * winsys buffers first. Then purge the context's winsys buffers list + * to free the resources of any winsys buffers that no longer have + * an existing drawable. + */ + ret = _mesa_make_current(ctx, NULL, NULL); + st_framebuffers_purge(ctx->st); + } + ret = _mesa_make_current(NULL, NULL, NULL); } @@ -1107,9 +1137,19 @@ st_manager_flush_frontbuffer(struct st_context *st) struct st_framebuffer *stfb = st_ws_framebuffer(st->ctx->DrawBuffer); struct st_renderbuffer *strb = NULL; - if (stfb) - strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_FRONT_LEFT]. - Renderbuffer); + if (!stfb) + return; + + /* If the context uses a doublebuffered visual, but the buffer is + * single-buffered, guess that it's a pbuffer, which doesn't need + * flushing. + */ + if (st->ctx->Visual.doubleBufferMode && + !stfb->Base.Visual.doubleBufferMode) + return; + + strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_FRONT_LEFT]. + Renderbuffer); /* Do we have a front color buffer and has it been drawn to since last * frontbuffer flush? @@ -1168,7 +1208,7 @@ st_manager_flush_swapbuffers(void) * Add a color renderbuffer on demand. The FBO must correspond to a window, * not a user-created FBO. */ -boolean +bool st_manager_add_color_renderbuffer(struct st_context *st, struct gl_framebuffer *fb, gl_buffer_index idx) @@ -1177,12 +1217,12 @@ st_manager_add_color_renderbuffer(struct st_context *st, /* FBO */ if (!stfb) - return FALSE; + return false; assert(_mesa_is_winsys_fbo(fb)); if (stfb->Base.Attachment[idx].Renderbuffer) - return TRUE; + return true; switch (idx) { case BUFFER_FRONT_LEFT: @@ -1191,11 +1231,12 @@ st_manager_add_color_renderbuffer(struct st_context *st, case BUFFER_BACK_RIGHT: break; default: - return FALSE; + return false; } - if (!st_framebuffer_add_renderbuffer(stfb, idx)) - return FALSE; + if (!st_framebuffer_add_renderbuffer(stfb, idx, + stfb->Base.Visual.sRGBCapable)) + return false; st_framebuffer_update_attachments(stfb); @@ -1209,7 +1250,7 @@ st_manager_add_color_renderbuffer(struct st_context *st, st_invalidate_buffers(st); - return TRUE; + return true; } @@ -1228,7 +1269,7 @@ get_version(struct pipe_screen *screen, _mesa_init_constants(&consts, api); _mesa_init_extensions(&extensions); - st_init_limits(screen, &consts, &extensions, api); + st_init_limits(screen, &consts, &extensions); st_init_extensions(screen, &consts, &extensions, options, api); return _mesa_get_version(&extensions, &consts, api);