static struct vl_dri3_buffer * dri3_get_back_buffer(struct vl_dri3_screen *scrn) { struct vl_dri3_buffer *buffer; struct pipe_resource *texture = NULL; assert(scrn); scrn->cur_back = dri3_find_back(scrn); if (scrn->cur_back < 0) return NULL; buffer = scrn->back_buffers[scrn->cur_back]; if (!buffer || buffer->width != scrn->width || buffer->height != scrn->height) { struct vl_dri3_buffer *new_buffer; new_buffer = dri3_alloc_back_buffer(scrn); if (!new_buffer) return NULL; if (buffer) dri3_free_back_buffer(scrn, buffer); vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->cur_back]); buffer = new_buffer; scrn->back_buffers[scrn->cur_back] = buffer; } pipe_resource_reference(&texture, buffer->texture); xcb_flush(scrn->conn); xshmfence_await(buffer->shm_fence); return buffer; }
static struct vl_dri3_buffer * dri3_get_back_buffer(struct vl_dri3_screen *scrn) { struct vl_dri3_buffer *buffer; struct pipe_resource *texture = NULL; bool allocate_new_buffer = false; int b, id; assert(scrn); scrn->cur_back = dri3_find_back(scrn); if (scrn->cur_back < 0) return NULL; buffer = scrn->back_buffers[scrn->cur_back]; if (scrn->output_texture) { if (!buffer || buffer->width < scrn->width || buffer->height < scrn->height) allocate_new_buffer = true; else if (scrn->is_different_gpu) /* In case of different gpu we can reuse the linear * texture so we only need to set the external * texture for copying */ buffer->texture = scrn->output_texture; else { /* In case of a single gpu we search if the texture is * already present as buffer if not we get the * handle and pixmap for the texture that is set */ for (b = 0; b < BACK_BUFFER_NUM; b++) { id = (b + scrn->cur_back) % BACK_BUFFER_NUM; buffer = scrn->back_buffers[id]; if (buffer && !buffer->busy && buffer->texture == scrn->output_texture) { scrn->cur_back = id; break; } } if (b == BACK_BUFFER_NUM) { allocate_new_buffer = true; scrn->cur_back = scrn->next_back; scrn->next_back = (scrn->next_back + 1) % BACK_BUFFER_NUM; buffer = scrn->back_buffers[scrn->cur_back]; } } } else { if (!buffer || buffer->width != scrn->width || buffer->height != scrn->height) allocate_new_buffer = true; } if (allocate_new_buffer) { struct vl_dri3_buffer *new_buffer; new_buffer = dri3_alloc_back_buffer(scrn); if (!new_buffer) return NULL; if (buffer) dri3_free_back_buffer(scrn, buffer); if (!scrn->output_texture) vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->cur_back]); buffer = new_buffer; scrn->back_buffers[scrn->cur_back] = buffer; } pipe_resource_reference(&texture, buffer->texture); xcb_flush(scrn->conn); xshmfence_await(buffer->shm_fence); return buffer; }