static boolean dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask, unsigned int *seq_num, struct pipe_resource **textures, int *width, int *height) { struct dri2_surface *dri2surf = dri2_surface(nsurf); if (dri2surf->server_stamp != dri2surf->client_stamp || (dri2surf->valid_mask & attachment_mask) != attachment_mask) { if (!dri2_surface_update_buffers(&dri2surf->base, attachment_mask)) return FALSE; } if (seq_num) *seq_num = dri2surf->client_stamp; if (textures) { int att; for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { if (native_attachment_mask_test(attachment_mask, att)) { struct pipe_resource *ptex = dri2surf->textures[att]; textures[att] = NULL; pipe_resource_reference(&textures[att], ptex); } } } if (width) *width = dri2surf->width; if (height) *height = dri2surf->height; return TRUE; }
static boolean android_surface_validate(struct native_surface *nsurf, uint attachment_mask, unsigned int *seq_num, struct pipe_resource **textures, int *width, int *height) { struct android_surface *asurf = android_surface(nsurf); struct winsys_handle handle; if (!asurf->buf) { if (!android_surface_dequeue_buffer(&asurf->base)) return FALSE; /* color_res must be compatible with buf_res */ if (asurf->color_res && (asurf->color_res->format != asurf->buf_res->format || asurf->color_res->width0 != asurf->buf_res->width0 || asurf->color_res->height0 != asurf->buf_res->height0)) pipe_resource_reference(&asurf->color_res, NULL); } if (textures) { /* we have access to only the back buffer */ const enum native_attachment att = NATIVE_ATTACHMENT_BACK_LEFT; if (native_attachment_mask_test(attachment_mask, att)) { textures[att] = NULL; pipe_resource_reference(&textures[att], (asurf->color_res) ? asurf->color_res : asurf->buf_res); } } if (seq_num) *seq_num = asurf->stamp; if (width) *width = asurf->buf->width; if (height) *height = asurf->buf->height; return TRUE; }
/** * Get the buffers from the server. */ static void dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask) { struct dri2_surface *dri2surf = dri2_surface(nsurf); struct dri2_display *dri2dpy = dri2surf->dri2dpy; unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS * 2]; int num_ins, num_outs, att; struct x11_drawable_buffer *xbufs; uint bpp = util_format_get_blocksizebits(dri2surf->color_format); boolean with_format = FALSE; /* never ask for depth/stencil */ /* We must get the front on servers which doesn't support with format * due to a silly bug in core dri2. You can't copy to/from a buffer * that you haven't requested and you recive BadValue errors */ if (dri2surf->dri2dpy->dri_minor < 1) { with_format = FALSE; buffer_mask |= (1 << NATIVE_ATTACHMENT_FRONT_LEFT); } /* prepare the attachments */ num_ins = 0; for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { if (native_attachment_mask_test(buffer_mask, att)) { unsigned int dri2att; switch (att) { case NATIVE_ATTACHMENT_FRONT_LEFT: dri2att = DRI2BufferFrontLeft; break; case NATIVE_ATTACHMENT_BACK_LEFT: dri2att = DRI2BufferBackLeft; break; case NATIVE_ATTACHMENT_FRONT_RIGHT: dri2att = DRI2BufferFrontRight; break; case NATIVE_ATTACHMENT_BACK_RIGHT: dri2att = DRI2BufferBackRight; break; default: assert(0); dri2att = 0; break; } dri2atts[num_ins++] = dri2att; if (with_format) dri2atts[num_ins++] = bpp; } } if (with_format) num_ins /= 2; xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable, &dri2surf->width, &dri2surf->height, dri2atts, with_format, num_ins, &num_outs); /* we should be able to do better... */ if (xbufs && dri2surf->last_num_xbufs == num_outs && memcmp(dri2surf->last_xbufs, xbufs, sizeof(*xbufs) * num_outs) == 0) { FREE(xbufs); dri2surf->client_stamp = dri2surf->server_stamp; return; } dri2_surface_process_drawable_buffers(&dri2surf->base, xbufs, num_outs); dri2surf->server_stamp++; dri2surf->client_stamp = dri2surf->server_stamp; FREE(dri2surf->last_xbufs); dri2surf->last_xbufs = xbufs; dri2surf->last_num_xbufs = num_outs; }