|
| 以 PDF 格式下載這本書
Overview of the XGL Architecture
2
- This chapter presents an overview of the XGL architecture. It provides an introduction to the following topics:
-
- Goals of the architecture
- Overview of the device-independent and device-dependent components of the architecture
- Architecture of the device pipelines
- Role of the software pipeline in the rendering process
- Context state handling
- Window system and device pipeline interaction
- Color
- More detailed information on these and other aspects of the XGL architecture is provided in later chapters of this manual.
- The following terms and acronyms are used in this chapter and throughout the remainder of this book in discussions of the XGL architecture: Core and DI refer to the device-independent parts of XGL; device pipeline (Dp) refers to the device-dependent parts of XGL.
XGL Architecture Design Goals
- The XGL architecture enables independent software vendors (ISVs) and independent hardware vendors (IHVs) to port XGL to a wide range of graphics applications and hardware platforms. The XGL architecture was designed to fulfill the following goals:
-
- Define a graphics porting interface (GPI) that enables structured porting of XGL to new display devices (frame buffers, accelerators, etc.).
- Clearly define the relationships between internal objects.
- Optimize XGL device-independent performance to ensure that graphics accelerators are able to achieve their maximum possible performance.
- The XGL library does not contain any device-dependent code. It contains only device-independent code and utilities (such as lighting calculations). The device-dependent code, which controls graphics hardware, resides in separate files called device pipelines.
Basic Components of the XGL Architecture
- At the most basic level, XGL has two components: the device-independent component and the device-dependent graphics pipelines. The device-independent code functions as the interface between the application program and the graphics pipelines. The pipelines turn geometric primitives and their state attributes into pixel data that is displayed on a graphics hardware device or written into memory. These basic components are illustrated in Figure 2-1:

Figure 2-1
Device-Independent Library
- The device-independent component of the library contains class hierarchies for internal and API objects and abstract pipeline class interfaces to the underlying pipeline operations. It takes care of a variety of device-independent tasks, including:
-
- Mapping XGL C API function calls to internal C++ functions
- Creating and managing API graphics objects
- Providing utility functions to facilitate the implementation of device pipelines
Graphics Pipelines
- The graphics pipelines include one or more device pipelines and a software pipeline. The device pipeline code resides in libraries that are dynamically loaded at runtime. When an XGL application begins execution, XGL determines what device the application is running on and loads the pipeline library needed to control that device. Thus, device support is not contained within XGL but is loadable at runtime.
- The XGL graphics porting interface consists of three layers of pipeline interface, with each layer responsible for specific rendering functions. The top layer, Loadable Interface 1 (LI-1), specifies the interface that lies directly below the XGL API. Functions in this layer take the points defining the primitive and transform, light (in the 3D case), and clip the geometry in preparation for the rendering operations in the next layer. The second layer (LI-2) is responsible for scan converting more complex primitives like polygons and polylines. The third layer (LI-3) is responsible for rendering pixels, individually or in spans on the device. The way that these layers are implemented differs between the device pipelines and the software pipeline.
Device Pipelines
- Device pipelines written at the LI-1 layer typically implement the full graphics pipeline for each primitive. An LI-1 pipeline takes the points defining a primitive and transforms, lights (in the 3D case) and clips the geometry, performs scan conversion, and renders pixels on the device. Thus, an LI-1 pipeline will normally start the processing of geometry at the LI-1 layer and continue, including all the functionality below LI-1. Device pipelines written at
- the second layer (LI-2) perform scan conversion and render pixels on the device. A device pipeline port to the lowest layer (LI-3) is responsible only for rendering pixels. IHVs can implement different GPI functions at different layers to tailor a port for a particular device.
-
Figure 2-2 illustrates the loadable interface layers.

Figure 2-2
XGL Software Pipeline
- The XGL product provides a software implementation of most of the primitives in the LI-1 and LI-2 layers. This allows IHVs to port to the level of functionality appropriate to a device. IHVs can make full use of the capabilities of their device and use the XGL software pipeline for functionality that the device lacks.
- The software pipeline consists of functions that implement the geometry pipeline and scan conversion functions in software. The functions in the top layer (LI-1) of the software pipeline take the points defining the primitive and transform, light (if necessary), and clip the geometry. The second layer (LI-2) is responsible for scan converting more complex primitives like polygons and
- polylines. The software pipeline does not include LI-3 functions, since these are device dependent. Therefore, at a minimum, an IHV must provide a set of LI-3 functions for a device.
How the Device Pipeline and Software Pipeline Work Together
- At rendering time, if the device pipeline has implemented an LI-1 function, the flow of control first goes to the device pipeline at the LI-1 level. The pipeline determines from the setting of API attributes whether it can or cannot render the primitive at that level. If it can render the primitive, it will generally perform all the operations necessary for rendering from the LI-1 level to the hardware. However, the architecture allows the flow of control to go to the device pipeline at LI-1 for part of the work and go to the software pipeline to complete LI-1 operations or to do LI-2 level processing. In general, when a device pipeline implements an LI-1 primitive, there is a match between the primitive-attribute combinations and what the accelerator can do.
- As with LI-1, if the device pipeline receives a primitive at the LI-2 level, the flow of control will usually stay within the device pipeline until the primitive is rendered. A typical scenario for a device pipeline is that it will support some combinations of primitives and attributes at the LI-1 level, some at the LI-2 level, and some at the LI-3 level. For example, the pipeline might accelerate solid lines at LI-1 but support dashed lines at LI-2. To render dashed lines, the device pipeline would let the software pipeline handle the LI-1 layer geometry operations, and it would take over the rendering operations at the LI-2 layer.
- By allowing the device to switch to the software pipeline, XGL provides a device pipeline with flexibility in how it renders a primitive. The pipeline can be written to fully accelerate a primitive from model coordinates to device coordinates, to partially accelerate a primitive and fall back on the software pipeline for some of the rendering tasks, or to not accelerate the primitive and let the software pipeline perform all but the most basic rendering tasks. Whenever a primitive or a rendering attribute for a primitive is not supported by the hardware, the device pipeline can fall back to the software pipeline for some or all of the processing for rendering. This dynamic decision making is one of the primary design features of the XGL architecture.
Writing a Device Pipeline
- The task of writing device pipeline functions at different levels varies in complexity. Writing functions at the LI-1 layer is complex and may require a significant amount of time. Table 2-1 summarizes the functionality of a device pipeline port at a particular layer.
-
Table 2-1
| Layer | Responsibilities |
| LI-1 | Must handle all aspects of processing an XGL primitive and all rendering operations, including scan conversion and pixel painting. |
| LI-2 | Assumes responsibility for rendering but leaves geometry processing operations to the XGL software version of the LI-1 layer. |
| LI-3 | Requires implementing span and dot renderers, but all other operations needed to process a primitive and reduce it to the pixel level are provided by XGL's default software implementation. |
- As mentioned above, a minimal port of XGL to a device must include functions at the LI-3 layer, since functions at this layer are not provided by the software pipeline. However, XGL provides a utility object called RefDpCtx (Reference Device Pipeline Context) that can help a pipeline writer quickly implement LI-3 functions. See the XGL Device Pipeline Porting Guide for information on RefDpCtx.
-
Figure 2-3 on page 27 illustrates the stages of the device and software pipelines as well as some of the components of the XGL core. For more information on the architecture of the device pipelines, turn to page 28.

Figure 2-3
-
Note - The XGL library provides a Stream device that supports output to a file; however, the bulk of this chapter assumes that you are writing to a pixel-based frame buffer.
Overview of the Device Pipeline Architecture
- Because XGL runs in a workstation windowing environment, it must provide support for applications with multiple windows, for multiple applications per frame buffer, and for multiple physical display devices. It must also include support for a range of hardware devices. The XGL loadable pipeline architecture was developed to explicitly address the wide range of geometry-oriented graphics devices currently in use and to provide a foundation for future display technology.
- To provide the support necessary for a variety of hardware devices, XGL includes a set of well-defined, abstract interfaces that link the device pipelines with the XGL core. The XGL graphics library does not contain any device-dependent code and hence cannot render directly to a frame buffer itself. To access a frame buffer, XGL loads the device pipeline appropriate for that frame buffer. Although the term pipeline traditionally refers to the steps in the rendering process, in XGL the design of the loadable pipelines includes components that serve as the framework connecting the device-independent code to the device pipeline code.
- The device pipeline is made up of a number of C++ classes. The classes are abstract classes in that they define a set of functions that must be implemented by the device pipeline. As part of the process of writing a device pipeline, the implementor must subclass the XGL-provided abstract classes and implement them to provide device-specific classes and objects.
Architecture at the API Level
- At the API level, XGL has two primary entities that are responsible for rendering: the Context object and the Device object. The Context object is the central object for the application program; it acts as a clearing house for attribute information and does the work of drawing graphics. Geometry and related attributes are rendered through the Context object to the physical device via the Device object. Multiple Context objects can be set up for each Device object, as would be the case if an application program wanted to render 2D and 3D geometry. Figure 2-4 shows a possible set of Context and Device objects that might be attached to one window of an application program. The Window Raster Device object represents application window 1.

Figure 2-4
Internal Pipeline Architecture
- Internally, XGL uses a set of objects to connect the device-independent Context and Device objects with the device-specific pipeline code. These objects are:
-
- Device pipeline context object
- Device pipeline device object
- Device pipeline manager object
- Device pipeline library object
- The sections that follow introduce and illustrate these objects.
Device Pipeline Context Object
- The device pipeline-context (DpCtx) object is the device-dependent representation of a Context object for a specific hardware device. When the application program associates a Context object with a Device object, XGL creates a DpCtx object for the Device and Context pair.
- The DpCtx object contains the actual rendering functions for a device and keeps track of Context state. Figure 2-5 shows the DpCtx objects that represent two Contexts associated with the Window Raster Device object. In this figure, the objects in the pipeline framework are shown as ovals with dark borders.

Figure 2-5
Device Pipeline Device Object
-
Figure 2-6 introduces the device pipeline device object (DpDev). This object manages the DpCtx objects corresponding to each Device object. The DpDev object is the device-dependent part of the XGL Device object, and it is used to manage the device dependencies of the DpCtx objects.

Figure 2-6
Device Pipeline Manager Object
-
Figure 2-7 presents the device pipeline manager (DpMgr) object. This object handles various categories of devices, such as frame buffers. The DpMgr object is unique in that is does not have a corresponding API-visible object, whereas the DpDev object corresponds to the API Device object, and the DpCtx object corresponds to the associated API Device and Context objects.
- The DpMgr object manages the DpDev objects for the device. If the category is a frame buffer, the DpMgr initializes the frame buffer. Figure 2-7 shows a single DpMgr object for the two DpDev objects that represent two application windows.

Figure 2-7
Device Pipeline Library Object
- The device pipeline library (DpLib) object represents the shared library for the device pipeline. Figure 2-8 shows the DpLib object in a system with two frame buffers of the same type. In this diagram, a single application has opened two windows on one screen and one window on another screen. The DpLib object allows more than one DpMgr to share hardware and software resources. For more information on the pipeline framework, see the subsequent chapters of this book and the XGL Device Pipeline Porting Guide.

Figure 2-8
Software Pipeline and Pipeline Switching
- For all geometry primitives, XGL includes a complete software implementation of the top two layers of the rendering pipeline interfaces. Device pipeline implementors writing for a specific graphics hardware device can choose to interpose their own functions for the interfaces that exist at the top two pipeline layers, or they can let the XGL-supplied software pipeline perform the tasks. Even if the device pipeline provides its own implementation of pipeline interfaces, it can call the software pipeline at the LI-1 or LI-2 layers to continue processing the data.
- The lowest layer of loadable interfaces, which is responsible for writing pixels to the device, is device dependent. This layer does not exist in software, although there is a set of utilities in software that implements most of LI-3. A device pipeline must include functions for this lowest layer of the pipeline.
Handling Context State Changes
- An application program can cause the state of a single XGL Context object to change in two ways:
-
- The application can set attributes to explicitly change the state of an XGL Context object.
- The application can change objects associated with the Context, such as a Transform object. This indirectly causes Context state to change.
- Changes in the state of a Context object resulting from attribute setting on the Context or on an object associated with the Context are passed directly to the device pipeline by the XGL device-independent code. However, because of the various models of hardware context switching, changes to Context state resulting from intraprocess Context switching (in other words, the application switches the XGL Context it is using to render) are left to the device pipeline implementor to manage.
First Things First: What Is Context?
- Before examining how the XGL core handles Context state changes, it might be helpful to look at the different uses of the term context. From the point of view of XGL, context can refer to the XGL API Context object, to the context of a UNIX(R) process, or to a hardware context. In a broad sense, context refers to a set of persistent state that controls an executing entity. We might apply this definition to the types of context as follows:
-
| XGL Context | The set of state that controls rendering of XGL primitives, such as line color or transforms. |
| Process context | The set of state that controls a UNIX process, such as the program counter, the signal mask, or file descriptors. This state also includes memory mapping for devices. |
| Hardware context | The set of state that controls the rendering on graphics accelerators, for example line color or raster operation register values. |
- The problem for the device pipeline writer is to map these different sets of state to the graphics hardware. This mapping is potentially complex, since the following points should be considered:
-
- Thus, the challenge for the device pipeline writer is to map an arbitrary number of XGL Context objects onto the number of hardware contexts supported by the graphics accelerator.
Explicit XGL State Changes
- Operations required for keeping track of the XGL Context attribute state are handled by the Context object in a device-independent manner. These operations include the getting and setting of attribute values and the storing of values. Information on attribute changes is passed directly to the pipelines. When the device pipeline is first associated with an XGL Context object, it gets the current values of the attributes and sets up the hardware. During program execution, the pipeline is notified of attribute changes as the changes occur, and it has the option of updating the hardware each time changes occur or of noting that changes occurred and updating the hardware at a later time.
- The mechanism that notifies the pipeline of attribute changes is an array defined in the device-independent XglDpCtx object and managed by the pipeline in its device's specific XglDpCtx object. This array serves as the means of communication between the device-independent code and the device pipeline.
Intraprocess State Changes
- When an application switches from drawing through one Context to drawing through another, state information must be saved in the graphics pipeline and the hardware. Because the XGL system cannot know what the state requirements for a particular hardware device are, how many hardware contexts are available, or how expensive it is to swap hardware contexts, XGL has left it up to the device pipeline implementor to handle state changes resulting from intraprocess context switching.
- XGL defines the basic components of the device pipeline, but the pipeline writer must complete the task of mapping XGL state to the hardware. For example, a pipeline for a frame buffer with one hardware context might decide that it needs a concept of a current XGL Context. To implement this, it may use one of the device pipeline interface objects to keep track of which Context object is the current Context.
- The pipeline architecture provides four places for the device pipeline implementor to insert device-dependent information for a specific hardware device. Depending on the requirements of the hardware, the device pipeline writer can include data in the pipeline interface objects:
-
- DpCtx object - Include data relevant to state information
- DpDev object - Include data relevant to the device or window
- DpMgr object - Include data relevant to the physical device
- DpLib object - Include data relevant to the pipeline library as a whole
- By providing a variety of locations for device-dependent information, the XGL architecture has given the device pipeline writer the flexibility to support different hardware state models.
Window System Interaction
- The XGL system uses Sun's DGA technology to accelerate XGL applications that are running under the OpenWindows server. DGA is a set of mechanisms that enables OpenWindows client processes to directly drive a graphics device when the client and server are on the same machine.
- The current implementation of DGA uses shared memory as the means of coordinating information between the client and the server. The shared memory contains information about the window, such as the window's size and position on the screen. DGA includes a client library of functions that enable the client program to get information about the window from the shared memory and to lock the window so that the client can render. The client library is part of the OpenWindows product and includes functions that provide access to the window, manage rapid color map changes, perform multibuffering, support windows with backing store, and handle software cursors when rendering.
- To provide the device pipelines with a way to manage window system interaction and with an interface to the DGA client library, the XGL architecture provides the XglDrawable object. The XglDrawable conceptualizes the sharing of a device with another entity, most often the window system, but possibly also a Memory Raster or a stream device. If the other entity is the window system, the XglDrawable manages the sharing of information through DGA (for local rendering) or through PEXlib/Xlib (for remote rendering). For example, when the window clip list changes, the two entities that are sharing the device must each be made aware of the changes and must cooperate to manage the changes.
- The XglDrawable object provides a high-level abstraction of the window for the variety of devices that XGL has to deal with. The goals of the XglDrawable are to:
-
- Encapsulate the DGA interface within the XglDrawable object. This allows the specifics of the sharing of the device and the other entity to be hidden from the pipeline.
- Hide window system dependencies and actual device interaction from the XGL core.
- Hide the differences in client- and server-mode DGA interactions from the device pipelines.
- Hide the handling of backing store from the device pipelines.
- The XglDrawable class derives to objects that reflect the type of device the application is rendering on. For a Window Raster Device, the XglDrawable object embeds the DGA client library, libdga,as an underlying layer, thus providing the device pipelines with the DGA window-locking mechanism for rendering and enabling the pipelines to determine whether the window clip list has changed. The Memory Raster Drawable object contains information on the user clip list and on the depth of the window but does not embed DGA calls or workstation clip list information.
- XglDrawable objects can be created for Xlib rendering, for rendering to a backing store, and potentially for other types of rendering, such as rendering to a raw frame buffer. The instantiation of the appropriate XglDrawable object for a device is handled automatically by the XGL device-independent code. Once the object is instantiated, the XGL core does not need to check the device or Drawable type before invoking a window system operation.
Color
- XGL supports both indexed and RGB color models, and it allows an application to use either color model without requiring the application to take into account the color model of the hardware that it is running on. XGL manages the mapping of color values to the underlying hardware for the application. At device creation time, XGL determines the real color type of the device and maps the color type that the application specified for the API Device object to the actual color type of the hardware. In this mapping, XGL must take into account these four cases:
-
- Indexed application color model on indexed hardware device
- Indexed application color model on RGB hardware device
- RGB application color model on indexed hardware device
- RGB application color model on RGB hardware device
- The mapping consists of translating XGL colors into pixel values (in the case of the X window system, into X pixel values), such that the final device color format represents a color as close as possible to the original XGL color. The process of color translation into X pixel values is shown in Figure 2-9.

Figure 2-9
- For window rasters, the translation scheme depends on the hardware but the goal is the same: the visible color should be as close as possible to the requested color.
- To manage the relationship between the XGL Color Map object (defining the application color type) and the XGL window raster, XGL provides the XglCmapDrawable object. This object encapsulates color handling and hides the sharing of colors between XGL and the window system.
- The XglCmapDrawable object is instantiated by the XGL core during Window Raster creation. It is associated with both the Window Raster object and the Color Map object. Note that, unlike the XglDrawable object, there is no need for XglCmapDrawable objects for Memory Raster devices or Stream devices.
|
|