Does OpenGL use Xlib to draw windows and render things, or is it the other way around?

前端 未结 3 719
谎友^
谎友^ 2021-02-01 10:26

I want to render fonts and lines on a window using either OpenGL or Xlib, but I\'d like to know which one is \"more fundamental\".

Usin

相关标签:
3条回答
  • 2021-02-01 10:45

    Xlib drawing commands send obsolete requests over a network socket. The original drawing commands are obsolete, e.g. current toolkits don't use the text-specific X requests. It looks like the (anti-aliased) XRender extension is still used. The X server can implement requests using whatever method it likes. See: glamor, XRender implemented using opengl.

    OpenGL is equally an API, not a specific implementation.

    • It is implemented on platforms which do not rely on X11, including Windows. (In this case X11 is available as third-party software).
    • It is also implemented on Wayland, the successor to X11 on Linux, which otherwise has no equivalent to XRender.
    • When opengl hardware acceleration is not available, opengl might render in software.

    There is no answer to this question, and you can easily construct situations which work either way around, or where only one of the two is available, or where both implement hardware acceleration and don't use the other, etc.

    OpenGL provides access to a greater range of GPU capabilities, e.g. shader programming. In that sense, it allows more full control of the hardware.

    aside: opengl has a text drawing api?? i am confused.

    Perhaps the author of this question intended to include a linux tag.

    Quickly googling, the most recent article I found here. I expect there's better somewhere. There's also a Wikipedia page on GLX

    0 讨论(0)
  • 2021-02-01 10:58

    WARNING: Wall of text coming in!

    @sourcejedi already gave an answer but there are some inaccuracies in it – that are not hurtful, but may be confusing.

    First and foremost OpenGL and Xlib are orthogonal with each other. Neither depends on the other one and you can use them independently. There is a dependency on Xlib by GLX (which is, why you can't fully ditch Xlib in favor of Xcb if you want to GLX), but the surface area of that dependency is small enough, so that you can use Xcb for the most part and use the Xlib-on-Xcb wrapper for the few parts where you have to use GLX. Now I've dropped a few acronyms here, so let's categorize them first:

    Xlib & Xcb are both libraries that implement the client side of the X11 protocol. Technically you could talk to a X11 server without them, by implementing the protocol "yourself" (in fact there is an ongoing effort to autogenerate Haskell code from the same specification files that are also used to generate Xcb code). X11 is transferred over sockets, so if you can somehow transfer that socket and some internal state between bindings you can even mix and match bindings, if you're careful where you tread.

    OpenGL itself is a pure low level (low level in the sense of which primitives it offers: points, lines and triangles) drawing tool, and there is no concept of "windows" in it. With the introduction of framebuffer objects, in principle you can create a headless OpenGL context and operate entirely within the bounds of self-managed image surfaces. But often (but certainly not always) you want your drawing(s) to be visible immediately on a display. That's where a window system interface (WSI) comes into play. OpenGL and thereby the whole support structure around it is quite old though, so not a lot of thought has been put into the whole WSI business, which led to a rather, well… actually there's no cleanly defined interface for this at all, so far, it all happens circumstancial. The usual way is "here I've got some preexisting image surface curtsey of the display system, I can haz OpenGL on that please?" Which brings us to the rather ad-hoc window system APIs for OpenGL. GLX for X11 and WGL for Win32; Apple is a whole chapter of its own…

    GLX is two things: First it's a X11 extension, i.e. it uses X11 transport to create a channel for a new set of commands in the X11 server. These commands are the OpenGL functions as specified for versions 1.1 through 2.1 (GLX has not yet been specified for 3.x onward). In that regard GLX places a OpenGL implementation on the X11 server side and GLX opcodes are used for remote procedure call toward the OpenGL context running server side. Second a GLX client side implementation that's housed in the libGL.so OpenGL API access library.

    In addition to that GLX implements a few "convenience" functions, like creating OpenGL display-listed rasterop "fonts" from X11 server side fonts; works only for the old-and-busted bitmap fonts that have been around with X11 core since ever. Doesn't antialias and don't look particularly good on low pixel density displays (if you have a high pixel density output device you can get away without antialiasing and high resolution bitmap fonts actually look excellent, case in point: laser printers). WGL followed GLX's lead and did the same for Windows bitmap fonts. That's the only "kind-of" font rendering support that's built directly into the OpenGL ecosystem. But it's pretty much useless for anything outside the 7-bit printable ASCII set. And it totally lacks a layout engine that would properly format the text (left, right, center aligned, justified or whatever). And it completely relies on display lists and OpenGL raster ops which have caveats like "the whole thing won't even go to work if the starting position of the first character happens to lie outside the viewport". So don't bother even trying to use it.

    With GLX you can take an existing X11 window and send the X11 server commands that set up this window for use with OpenGL. Also with GLX you can send the X11 server commands that ask it to create a OpenGL context. A OpenGL context is not tied to a particular X11 drawable. You can attach and detach it freely, as long as the drawable you're intending to attach it is compatible with that context (i.e. has been configured for the particular framebuffer format, that context expects for its main framebuffer). Then when you make OpenGL calls, GLX wraps them up into opcodes and sends them over the socket connection to the X11 server where they're executed.

    Of course all that de-/serialization incurs some non insignificant execution cost, hence very quickly a special mode called "direct context" was introduced, where the GLX/X11-server combo are used only to setup the OpenGL context and making it current on X11 drawables and for the rest the program is working directly against the OpenGL implementation, thereby avoiding all that serialization and even getting direct access to address space where bulk data objects (textures, buffer objects, etc.) reside. This is why in a X11 based environment you can find instances of a OpenGL implementation for the same direct connection context to actually be present in two processes: The X11 server and the client using it.

    As I already mentioned above Xlib, Xcb & co are just client side implementations of the X11 protocol. The server side of X11 provides a basic set of graphics functions. X11 core has some limited bitmap font drawing capabilities, along with functions for drawing points, lines, arcs, (rounded) rectangles, circles and polygons. Drawing and filling happens with a solid pen or hatching pattern; there's no interpolation or gradients going on. Depending on the kind of image you want to draw this is rather limiting. Between the years 2000 to 2010 everybody wanted to draw colourful UIs with lots of gradients and fancy borders and whatnot (personally I never liked those), but in past years semi-/flat UI designs have become a trend and those you could actually draw rather well with X11 core (sans the antialiased text). Eventually people wanted to be able to draw gradients X11 side, so the XRender extension was introduced, which gives you what is essentially the 2D equivalent of OpenGL's GL_TRIANGLES primitive, without shaders, textures and illumination; you get color interpolation, gradients and antialiasing though. As a sidetrack the Xft library (important, that's a library, not a X11 server thing), was created that piggybacks on XRender to load a bunch of client side rasterized font glyphs to the server so that you could with that onto a drawable "antialiased" text. That's about the drawing capabilities of a X11 server. How these drawing capabilities are actually implemented in the X11 server is unspecified and completely depend on the implementation and more importantly on the device dependent X code (DDX) aka the X graphics driver! It could be done purely in software (often the case, currently through a server side component based on the pixman render library), but as well GPU accelerated or even based on the server side part of the used OpenGL implementation (glamor).

    Which one should I use if I want more "low-level" control over the rendering and display?

    That depends entirely on your target application.

    If you're aiming for doing something that's not doing a lot of graphics-graphics (text editor, chat program or so) and you're okay with being tied to X11 then probably X11 through Xlib or Xcb. Most importantly X11 gives you something that pretends to be half-way reasonable text drawing functions that at least work in predictable ways.

    OpenGL is the proper choice if you're aiming for doing graphics-graphics work (image manipulation, CAD, desktop publishing, also web browsers), but it means that you're "on your own" for anything that goes beyond points, lines and triangles.

    These days it's practically a given that a GPU is present. 10 years ago, not so much, so the UI toolkits and graphics backends that were developed back then (and we're still using those) will do most of their work purely in software, on the CPU and transfer the final image to the display device. This was reasonable then. And if the ultimate goal is reproducible, high quality graphics it still is, because GPUs cut a lot of corners for performance and don't behave identically (OpenGL demands that rendering results of the same chain of operations within the same context are 1:1 matches, but change only one bit and they all bets are off).

    The three rendering libraries you can find these days on a modern Linux(!) system (not X11 based in general!) and can be used "stand-alone" are Cairo, Anti-Grain-Geometry (AGG) and pixman. Cairo is used mostly by GDK/GTK+ based programs, pixman in the X11 server (but you can use it in your program, too). AGG is none toolkit's primary graphics kit in particular, but used by a number of programs and libraries (most notably plotting, like matplotlib). One must also not forget the "raster" graphics engine in Qt, but that can be used only within Qt within QPainter (so stand-alone if your program uses Qt, but can't be used without Qt).

    When it comes to AGG vs. Cairo the biggest selling point for Cairo is, that it got a pure C binding. Unfortunately Cairo is not a very fast renderer (it made huge progress in the past 10 years). But it's eating the dust of AGG, which is much faster and (ironically) also produces better quality; unfortunately AGG is a C++ library, so to effectively use it you're bound to use C++, which is a downside. Also the principle developer of AGG sadly passed away a few years ago, which stalled development for some time, but it's been picked up by the community again.

    0 讨论(0)
  • 2021-02-01 11:00

    Regardless of the image engine you finally use (also don't forget Wayland!) you want to talk to harbuzz-ng, freebidi, fontconfig and freetype for text. Unicode and Opentype are moving so fast those days it's not remotely interesting to reimplement the corresponding engines yourself.

    You may think 7-bit ascii is sufficient, but even embedded appliances do more now (if only to render i18n streams, music tags and so on).

    Pango-Cairo used to be the standard way to integrate all of those. But many big apps are moving to skia for speed nowadays.

    0 讨论(0)
提交回复
热议问题