void xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi) { struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); boolean ret; ret = xmesa_st_framebuffer_display(stfbi, ST_ATTACHMENT_BACK_LEFT); if (ret) { struct pipe_resource **front, **back, *tmp; front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT]; back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT]; /* swap textures only if the front texture has been allocated */ if (*front) { tmp = *front; *front = *back; *back = tmp; /* the current context should validate the buffer after swapping */ if (!xmesa_strict_invalidate) xmesa_notify_invalid_buffer(xstfb->buffer); } if (xmesa_strict_invalidate) xmesa_check_buffer_size(xstfb->buffer); } }
/** * Check that a framebuffer's attachments match the window's size. * * Called via st_framebuffer_iface::validate() * * \param statts array of framebuffer attachments * \param count number of framebuffer attachments in statts[] * \param out returns resources for each of the attachments */ static boolean xmesa_st_framebuffer_validate(struct st_context_iface *stctx, struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts, unsigned count, struct pipe_resource **out) { struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); unsigned statt_mask, new_mask, i; boolean resized; boolean ret; /* build mask of ST_ATTACHMENT bits */ statt_mask = 0x0; for (i = 0; i < count; i++) statt_mask |= 1 << statts[i]; /* record newly allocated textures */ new_mask = statt_mask & ~xstfb->texture_mask; /* If xmesa_strict_invalidate is not set, we will not yet have * called XGetGeometry(). Do so here: */ if (!xmesa_strict_invalidate) xmesa_check_buffer_size(xstfb->buffer); resized = (xstfb->buffer->width != xstfb->texture_width || xstfb->buffer->height != xstfb->texture_height); /* revalidate textures */ if (resized || new_mask) { ret = xmesa_st_framebuffer_validate_textures(stfbi, xstfb->buffer->width, xstfb->buffer->height, statt_mask); if (!ret) return ret; if (!resized) { enum st_attachment_type back, front; back = ST_ATTACHMENT_BACK_LEFT; front = ST_ATTACHMENT_FRONT_LEFT; /* copy the contents if front is newly allocated and back is not */ if ((statt_mask & (1 << back)) && (new_mask & (1 << front)) && !(new_mask & (1 << back))) { xmesa_st_framebuffer_copy_textures(stfbi, back, front, 0, 0, xstfb->texture_width, xstfb->texture_height); } } } for (i = 0; i < count; i++) { out[i] = NULL; pipe_resource_reference(&out[i], xstfb->textures[statts[i]]); } return TRUE; }
/* * Bind buffer b to context c and make c the current rendering context. */ PUBLIC GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, XMesaBuffer readBuffer ) { XMesaContext old_ctx = XMesaGetCurrentContext(); if (old_ctx && old_ctx != c) { XMesaFlush(old_ctx); old_ctx->xm_buffer = NULL; old_ctx->xm_read_buffer = NULL; } if (c) { if (!drawBuffer || !readBuffer) return GL_FALSE; /* must specify buffers! */ if (c == old_ctx && c->xm_buffer == drawBuffer && c->xm_read_buffer == readBuffer) return GL_TRUE; xmesa_check_buffer_size(drawBuffer); if (readBuffer != drawBuffer) xmesa_check_buffer_size(readBuffer); c->xm_buffer = drawBuffer; c->xm_read_buffer = readBuffer; stapi->make_current(stapi, c->st, drawBuffer->stfb, readBuffer->stfb); /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ drawBuffer->wasCurrent = GL_TRUE; } else { /* Detach */ stapi->make_current(stapi, NULL, NULL, NULL); } return GL_TRUE; }
/** * Called via st_framebuffer_iface::flush_front() */ static boolean xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, enum st_attachment_type statt) { struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); boolean ret; ret = xmesa_st_framebuffer_display(stfbi, statt); if (ret && xmesa_strict_invalidate) xmesa_check_buffer_size(xstfb->buffer); return ret; }