[Mesa-dev] Why are pbuffers backed by a pixmaps (Was Re: [PATCH] egl: Fix leak of X11 pixmaps backing pbuffers in DRI3.)

Adam Jackson ajax at redhat.com
Thu Aug 9 19:30:31 UTC 2018

On Thu, 2018-08-09 at 18:22 +0100, Emil Velikov wrote:

> In the GLX case, it's required due to server-side rendering. One needs
> a separate primitive for each pbuffer, thus the information can be
> passed long the wire.

I can't parse this. "Primitive"?

So, backstory time. GLX_SGIX_pbuffer was the genesis of pbuffers.
Here's what it has to say about how a pbuffer is unlike other GLX
drawables (some of which is a comment about how things happened to work
on IRIX):

"GLXPbuffers are equivalent to GLXPixmaps with the following

    1.	There is no associated X pixmap. Also, since a GLXPbuffer is a GLX
        resource, it may not be possible to render to it using X or an 
   	X extension other than GLX.

    2.	The format of the color buffers and the type and size of any
     	associated ancillary buffers for a GLXPbuffer can only be
        described with a GLXFBConfig -- an X Visual cannot be used.

    3.	It is possible to create a GLXPbuffer whose contents may be 
	asynchronously lost at any time.

    4.  GLXPbuffers can be rendered to using either direct or indirect
        rendering contexts.

    5.  The allocation of a GLXPbuffer can fail if there are insufficient
	resources (i.e., all the pbuffer memory has been allocated and 
	the implementation does not virtualize pbuffer memory.)"

In contrast, a GLXPixmap _must_ be renderable by X11, cannot lose its
contents, and _may_ not be renderable by direct contexts. All of this
dates to like 1997, so we didn't have FBOs yet, and any rendering
surface would have been allocated by "the server" [1]. That extension
was merged into GLX 1.3 pretty much unchanged, and GLX 1.3 was 1998. 

Xorg didn't get GLX 1.3 working until like 2007 [2]. As an
implementation choice, Xorg _does_ back pbuffers with pixmaps, both in
that it calls ->CreatePixmap internally to make them and that it tracks
them as actual pixmaps [3]. We never clobber pbuffers, we have no
problem rendering to pbuffers from X11, and we have no problem
rendering to GLXPixmaps from direct contexts. Effectively, other than
the resource type, the difference between a pbuffer and a glxpixmap is
that the latter takes two XIDs and two resource creation calls.

EGL dates to 2003, which means it predates even EXT_framebuffer_object,
so the pbuffer bit of GLX was kept in the new API. The EGL spec says a
pbuffer has no associated native window or native window type - no
kidding, it's not a window - but it does not require that a pbuffer
have no native object backing it at all.

Now, direct rendering in GLX is underspecified; the implementation is
free to use whatever subset of GLX, and whatever private protocol, it
wants. In principle the client could allocate the pbuffer's storage
from the "server" (the drm, here), and pass that handle and its new XID
name to the X server to bind them together so indirect contexts can
name it as well.

An EGL implementation could take even more liberties. Even on an X11
window system there's no intrinsic reason that an EGL pbuffer need to
exist as a native winsys object; all that's required is that pbuffers
work with any API that takes an EGLSurface parameter. You might choose
to mirror EGL surfaces as GLX objects, or not, whatever your
implementation finds convenient. In practice, we back pbuffers with
pixmaps because we also back pixmaps with pixmaps, and there's no
reason to make those paths diverge more than they have to.

[1] - Even in this old IRIXy context, "the server" doesn't necessarily
mean the X server, it means the rendering services provided by the OS;
but as pbuffers have an XID, the X server is where this allocation
happens from the GLX app's perspective, regardless of what OS services
xserver (or libGL) invokes to make that happen.

[2] - Some of that was embarassment, as GLX_EXT_texture_from_pixmap
technically requires 1.3, and we were cheating. Some of it was that the
GLX code at this point was under SGI FreeB 1.1, and we were all
pretending that was okay to distribute, but were hesitant to make
changes due to the license terms being unpleasant.

[3] - XDestroyPixmap(glXCreatePbuffer()) ought to throw GLXBadDrawable,
not succeed, so this latter behavior is a bug and probably a spec

- ajax

More information about the mesa-dev mailing list