Louvre  v1.2.1-2
C++ library for Wayland compositors
List of all members | Public Types | Public Member Functions
LOutput Class Reference

#include <LOutput.h>

A display rendering interface. More...

Detailed Description

A display rendering interface.

The LOutput class is responsible for rendering content to a display. It is typically associated with a computer screen, but could also represent a window within an X11 or Wayland desktop, depending on the selected graphic backend.

Access

The graphic backend is responsible for creating each LOutput making a request to the compositor through LCompositor::createOutputRequest().
You can override that virtual constructor to use your own LOutput subclasses.
The LSeat class grants access to all outputs created by the graphic backend through LSeat::outputs() and it also notifies you of hotplugging events (e.g. when connecting or disconnecting a display through an HDMI port).

See also
LSeat::outputPlugged() and LSeat::outputUnplugged()

Initialization

By default, outputs are inactive and cannot be rendered on. To activate an output, use the LCompositor::addOutput() method. This initializes its rendering thread, graphic context, and triggers the initializeGL() event. Subsequently, whenever the repaint() method is called, the rendering thread unblocks, and the paintGL() event is invoked, allowing you perform painting operations.

Note
Louvre by default initializes all available outputs once the compositor is started within the LCompositor::initialized() event.

Uninitialization

If you no longer wish to use an output, call the LCompositor::removeOutput() method to remove it from the compositor. This will only uninitialize it, making it possible to re-initialize it later.
An LOutput is no longer available when its virtual destructor is invoked (LCompositor::destroyOutputRequest()).

Rendering

Painting operations must exclusively take place within a paintGL() event, as rendering elsewhere won't be visible on the screen.
When you call repaint(), Louvre unlocks the output rendering thread and invokes paintGL() just once, regardless of the number of repaint() calls during a frame.
To unlock the rendering thread again, you must call repaint() within or after the last paintGL() event.
The graphic backend is in charge of triggering the initializeGL(), moveGL(), resizeGL(), paintGL(), and uninitializeGL() events, so you must avoid calling them directly.

Context

Each output has its own OpenGL context and its own instance of LPainter, which can be accessed with the painter() method.
You can use the functions provided by LPainter to render colored rects or textures, or use the native OpenGL functions and your own shaders/programs if you wish.

Note
Consider leveraging the LScene and LView classes for rendering, as they automatically calculate and repaint only the portions of an output that require updates. This can significantly enhance the performance of your compositor.

Modes

Each LOutput can have multiple modes. An LOutputMode contains information about the resolution and refresh rate that the output can operate at.
You can access the modes of an output with modes() and set the desired one with setMode().
Outputs by default use the preferredMode(), which typically has the highest refresh rate and resolution.
If you change an output's mode or scale while it's initialized, the resizeGL() event is triggered.

Arrangement

Outputs, like surfaces, have a position and dimensions that allow them to be logically organized in a similar way to how a system settings panel does.
You can adjust the position of an output using the setPos() method, which will, in turn, trigger the moveGL() event when the position changes.

Note
To enable LCursor to transition across different LOutputs, ensure that the outputs are closely arranged side by side.

Scaling

Many screens nowadays are HiDPI, so it is commonly required to apply a scaling factor to prevent content from appearing tiny on the screen. By default, all screens in Louvre have a scaling factor of 1, meaning no scaling is applied. To assign a scale to a screen, you can use setScale(), which modifies the size returned by size() and rect().

In Louvre, you typically work with two coordinate systems: buffer coordinates and surface coordinates.

In buffer coordinates, the scale is not taken into account, and the dimensions always have maximum granularity. For example, if a screen has a resolution of 2000x1000px, its size in buffer coordinates would be the same: 2000x1000px, which is returned by sizeB(). However, the global coordinate space of the compositor uses surface coordinates, which is equal to the size in buffer coordinates divided by the applied scale. Therefore, if a factor of 2 is used, the size in surface coordinates would be 1000x500, which is returned by size().

When arranging displays, both the position and size of the outputs should be considered in surface coordinates.

Let's look at an example to make these concepts clearer:

Let's assume you have two displays, one with a resolution of 1000x500px and another with 2000x1000px (double the resolution), but both with a physical size of 22''. This means that the space occupied by 1px on the blue screen accommodates 4px on the pink screen.

If you were to see it in person, side by side they would look like this:

If you assign the same scaling factor of 1 to both screens, their sizes in surface coordinates would be the same as in buffer coordinates. Therefore, the global coordinate space of the compositor would look like this:

And if you were to see your screens in real life, it would look like the following. In the pink screen, everything would appear tiny, half the size of the blue screen. And as you can see, if you were to drag an application window from one screen to another, it would look somewhat odd.

Now, let's imagine that you assign a scaling factor of 2 to the pink screen. In this case, the global coordinate space of the compositor would look as follows:

And therefore, if you were to see it in real life now, it would appear consistently.

Therefore, in summary, the size of a screen in surface coordinates is determined by dividing its buffer size by the applied scale.

Fractional Scaling

Louvre also supports fractional scaling, albeit with some differences compared to integer scaling. For instance, if you assign a scale of 1.5 using setScale() to the pink screen, the resulting applied scale (obtained with scale()) will be ceil(1.5) = 2. However, the buffer dimensions of the screen will simulate being 2/1.5 times larger than its current mode (rounded), resulting in 2668 x 1334 for this case. Consequently, its size in surface coordinates would be 2668 x 1334 divided by 2. As a result, the compositor coordinate space would appear as follows:

This creates the illusion of rendering on a larger screen, the result of which is actually scaled to the real size, allowing for the desired scaling effect. Rendering using fractional scales, however, can introduce undesired visual effects like aliasing, especially noticeable when moving elements with textures containing fine details. For this reason, Louvre offers the option to render using oversampling, where all the screen content is rendered in a larger buffer, and then that rendered buffer is scaled down to the screen framebuffer. This method almost completely eliminates aliasing but has the disadvantage of consuming more computational power, potentially decreasing performance. Without oversampling the content is directly rendered on the screen, making it efficient but retaining aliasing artifacts. Louvre allows you to toggle oversampling on and off instantly at any time using enableFractionalOversampling(). For example, you could enable it when displaying a desktop with floating windows and disable it when displaying a fullscreen window.

Note
Oversampling is not required and is always disabled when using non-fractional scales. Therefore, as a recommendation, if your monitor supports multiple modes with various resolutions, it is preferable to select one of those modes instead of using fractional scaling.

Clients supporting the fractional scaling protocol are instructed to scale their buffers directly to the fractional scale. On the other hand, clients lacking support for the protocol are advised to use ceil(fractional scale), ensuring a consistently high-detail appearance.

Transforms

Louvre also supports applying transforms to outputs with setTransform(). Let's imagine that you physically rotate the pink monitor 90° clockwise while maintaining the same normal transform on both. What you would see is the following:

Given that you rotated the screen 90° clockwise, it is necessary to apply a transform that rotates the screen 90° counter-clockwise (Louvre::LFramebuffer::Rotated90). If you apply this to the pink screen, then you would see the following:

Note that when applying a transformation containing a 90° or 270° rotation to an output, the components of sizeB(), size() and rect().size() are swapped (their width becomes the height, and the height becomes the width). The global coordinate space of the compositor is structured in such a way that you can continue rendering in the same manner as if the screens were in their normal transform state. Therefore, there's no need to worry about rotating or flipping the elements you draw.

Public Types

enum  State
 Enumeration of possible states for an LOutput. More...
 
enum  SubPixel
 Enumeration describing the subpixel geometry. More...
 

Public Member Functions

 LOutput (const void *params)
 Constructor of the LOutput class. More...
 
virtual ~LOutput ()
 Destructor of the LOutput class. More...
 
State state () const
 Get the current state of the LOutput. More...
 
LFramebufferframebuffer () const
 Return a pointer to the associated framebuffer. More...
 
LFramebuffer::Transform transform () const
 Get the framebuffer transformation. More...
 
void setTransform (LFramebuffer::Transform transform)
 Set the framebuffer transformation. More...
 
Int32 currentBuffer () const
 Return the index of the current buffer. More...
 
UInt32 buffersCount () const
 Return the count of available buffers. More...
 
LTexturebufferTexture (UInt32 bufferIndex)
 Access the texture of a specific buffer. More...
 
bool hasBufferDamageSupport () const
 Check if the output supports buffer damage tracking. More...
 
void setBufferDamage (const LRegion *damage)
 Specify the damaged region of the framebuffer. More...
 
SubPixel subPixel () const
 Gets the layout of RGB subpixels for a single pixel on a display. More...
 
bool hasVSyncControlSupport () const
 Checks if VSync control is supported for this output. More...
 
bool vSyncEnabled () const
 Checks if VSync is enabled (enabled by default). More...
 
bool enableVSync (bool enabled)
 Turns VSync on or off. More...
 
Int32 refreshRateLimit () const
 Gets the refresh rate limit in Hz when VSync is disabled. More...
 
void setRefreshRateLimit (Int32 hz)
 Sets the refresh rate limit in Hz when VSync is disabled. More...
 
UInt32 gammaSize () const
 Gets the size of the gamma table. More...
 
bool setGamma (const LGammaTable *gamma)
 Sets the gamma correction table for the output. More...
 
const std::vector< LOutputMode * > & modes () const
 Vector of available modes. More...
 
const LOutputModepreferredMode () const
 Get the preferred mode. More...
 
const LOutputModecurrentMode () const
 Get the current mode. More...
 
void setMode (const LOutputMode *mode)
 Set the output mode. More...
 
void setScale (Float32 scale)
 Set the output scale factor. More...
 
Float32 scale () const
 Retrieve the current output scale factor. More...
 
Float32 fractionalScale () const
 Gets the same scale set with setScale(). More...
 
bool usingFractionalScale () const
 Checks if the scale factor set with setScale() is fractional. More...
 
bool fractionalOversamplingEnabled () const
 Checks if oversampling is enabled. More...
 
void enableFractionalOversampling (bool enabled)
 Enable or disable oversampling for fractional scales. More...
 
void repaint ()
 Schedule the next rendering frame. More...
 
Int32 dpi ()
 Get the dots per inch (DPI) of the output. More...
 
const LSizephysicalSize () const
 Get the physical dimensions of the output. More...
 
const LSizesize () const
 Get the output size in compositor coordinates. More...
 
const LSizesizeB () const
 Get the output size in buffer coordinates. More...
 
const LRectrect () const
 Get the output rect. More...
 
const LPointpos () const
 Get the output position in surface coordinates. More...
 
void setPos (const LPoint &pos)
 Set the position of the output. More...
 
const char * name () const
 Get the output name. More...
 
const char * model () const
 Get the output model name. More...
 
const char * manufacturer () const
 Get the manufacturer name of the output. More...
 
const char * description () const
 Get the description of the output. More...
 
LPainterpainter () const
 Get access to the associated LPainter. More...
 
const std::thread::id & threadId () const
 Get the ID of the rendering thread. More...
 
Virtual Methods
virtual void initializeGL ()
 Initialize Event. More...
 
virtual void paintGL ()
 Paint Event. More...
 
virtual void resizeGL ()
 Resize Event. More...
 
virtual void moveGL ()
 Move Event. More...
 
virtual void uninitializeGL ()
 Uninitialize Event. More...
 
virtual void setGammaRequest (LClient *client, const LGammaTable *gamma)
 Set gamma table request. More...
 
- Public Member Functions inherited from LObject
 LObject ()=default
 Constructor of the LObject class. More...
 
 ~LObject ()
 Destructor of the LObject class. More...
 
std::shared_ptr< const bool > isAlive () const
 Object's liveness status. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from LObject
static LCompositorcompositor ()
 Quick access to the global compositor instance. More...
 
static LSeatseat ()
 Quick access to the global seat instance. More...
 
static LCursorcursor ()
 Quick access to the global cursor instance. More...
 

Member Enumeration Documentation

◆ State

enum State

Enumeration of possible states for an LOutput.

Enumerator
PendingInitialize 

Output is pending initialization.

PendingUninitialize 

Output is pending uninitialization.

Initialized 

Output is initialized and active.

Uninitialized 

Output is uninitialized.

ChangingMode 

Output is in the process of changing display mode.

Suspended 

Output is suspended.

◆ SubPixel

enum SubPixel

Enumeration describing the subpixel geometry.

This enumeration provides information about how the physical pixels on an output are laid out.

Enumerator
Unknown 

Unknown geometry.

None 

No specific geometry.

HorizontalRGB 

Horizontal RGB layout.

HorizontalBGR 

Horizontal BGR layout.

VerticalRGB 

Vertical RGB layout.

VerticalBGR 

Vertical BGR layout.

Constructor & Destructor Documentation

◆ LOutput()

LOutput ( const void *  params)

Constructor of the LOutput class.

◆ ~LOutput()

~LOutput ( )
virtual

Destructor of the LOutput class.

Invoked internally by the library after LCompositor::destroyOutputRequest() is called.

Member Function Documentation

◆ state()

LOutput::State state ( ) const

Get the current state of the LOutput.

This method returns the current state of the output.

◆ framebuffer()

LFramebuffer * framebuffer ( ) const

Return a pointer to the associated framebuffer.

Returns
A pointer to the LFramebuffer instance associated with the output.

◆ transform()

LFramebuffer::Transform transform ( ) const

Get the framebuffer transformation.

This method returns the current framebuffer transformation applied with setTransform(). The default value is LFramebuffer::Normal.

Returns
The framebuffer transformation.

◆ setTransform()

void setTransform ( LFramebuffer::Transform  transform)

Set the framebuffer transformation.

This method sets the transformation for the framebuffer, allowing you to adjust the orientation of the output. If the specified transformation includes a 90 or 270-degree rotation, the width and height of the output are swapped accordingly.

Parameters
transformThe framebuffer transformation to apply.

◆ currentBuffer()

Int32 currentBuffer ( ) const

Return the index of the current buffer.

Compositors commonly employ double or triple buffering to ensure smooth graphics rendering. This involves rendering to one buffer while displaying another, reducing visual artifacts like glitches and tearing.

Returns
The current buffer index. Alternates between [0], [0, 1] or [0, 1, 2] depending on the graphic backend configuration.
See also
Graphic Backend Configuration

◆ buffersCount()

UInt32 buffersCount ( ) const

Return the count of available buffers.

This method returns the number of buffers used by the output. It can be 1, 2 or 3 depending on the graphic backend configuration.

See also
Graphic Backend Configuration

◆ bufferTexture()

LTexture * bufferTexture ( UInt32  bufferIndex)

Access the texture of a specific buffer.

This method allows access to the texture associated with a particular buffer index.

Parameters
bufferIndexThe index of the buffer for which the texture is to be accessed.
Returns
A pointer to the texture associated with the specified buffer index, or nullptr if texture access is not supported.
Warning
Some hardware/backends may not support accessing outputs textures, so you should always check if nullptr is returned.

◆ hasBufferDamageSupport()

bool hasBufferDamageSupport ( ) const

Check if the output supports buffer damage tracking.

Some graphic backends/hardware can benefit from knowing which regions of the framebuffer have changed within a paintGL() event. This method indicates whether buffer damage support is available.

See also
setBufferDamage()
Returns
true if the graphical backend supports buffer damage tracking, false otherwise.

◆ setBufferDamage()

void setBufferDamage ( const LRegion damage)

Specify the damaged region of the framebuffer.

This method is used to designate the region of the framebuffer that has been affected in the most recent paintGL() event. It should be invoked after completing all painting operations during a paintGL() event. The damage region is automatically cleared just before the subsequent paintGL() event.

Note
Although calling this method is not mandatory, it can significantly enhance performance, especially on certain graphic backends/hardware or when the output scale is fractional and oversampling is enabled. If never invoked, the entire output is considered damaged.

When using LScene for rendering, damage calculation is handled automatically, and calling this method should be avoided.

Parameters
damageThe damaged region of the framebuffer in surface coordinates. Providing an empty region indicates no damage, while passing nullptr implies the entire output is damaged.

◆ subPixel()

LOutput::SubPixel subPixel ( ) const

Gets the layout of RGB subpixels for a single pixel on a display.

The layout of subpixels can impact the display of elements like fonts.

◆ hasVSyncControlSupport()

bool hasVSyncControlSupport ( ) const

Checks if VSync control is supported for this output.

Returns
true if VSync control is supported, false if VSync is always enabled.

◆ vSyncEnabled()

bool vSyncEnabled ( ) const

Checks if VSync is enabled (enabled by default).

Returns
true if VSync is enabled, false otherwise.

◆ enableVSync()

bool enableVSync ( bool  enabled)

Turns VSync on or off.

Parameters
enabledtrue to enable VSync, false to disable.
Returns
true if VSync was successfully enabled or disabled, false if VSync control is not supported (see hasVSyncControlSupport()).

◆ refreshRateLimit()

Int32 refreshRateLimit ( ) const

Gets the refresh rate limit in Hz when VSync is disabled.

A value less than 0 indicates the limit is disabled.
A value equal to 0 indicates the limit is double the current output mode refresh rate (the default).
Any other positive value represents the limit in Hz.

Returns
The refresh rate limit when VSync is disabled.

◆ setRefreshRateLimit()

void setRefreshRateLimit ( Int32  hz)

Sets the refresh rate limit in Hz when VSync is disabled.

A value less than 0 indicates the limit is disabled.
A value equal to 0 indicates the limit is double the current output mode refresh rate (the default).
Any other positive value represents the limit in Hz.

Parameters
hzThe refresh rate limit in Hz when VSync is disabled.

◆ gammaSize()

UInt32 gammaSize ( ) const

Gets the size of the gamma table.

Note
This method can only be called while the output is initialized. If called when not initialized, it returns 0. If the output doesn't support gamma correction, this method also returns 0.
Returns
The size of the gamma correction table.
See also
setGamma()
LGammaTable

◆ setGamma()

bool setGamma ( const LGammaTable gamma)

Sets the gamma correction table for the output.

This method allows to set the gamma correction table for the output.

Note
This method can only be called while the output is initialized. Louvre automatically sets a linear gamma table when the output is initialized.
Parameters
gammaA pointer to the LGammaTable with a size matching gammaSize(). Passing nullptr restores the default table (linear).
Returns
true if the gamma correction table was successfully set, false otherwise.

◆ modes()

const std::vector< LOutputMode * > & modes ( ) const

Vector of available modes.

This method returns a vector containing all the available output modes for the LOutput instance.

Returns
A vector of pointers to LOutputMode instances representing the available modes of the output.

◆ preferredMode()

const LOutputMode * preferredMode ( ) const

Get the preferred mode.

This method returns the preferred mode for the output. It is generally the mode with the highest refresh rate and resolution.

◆ currentMode()

const LOutputMode * currentMode ( ) const

Get the current mode.

This method returns the current output mode.

◆ setMode()

void setMode ( const LOutputMode mode)

Set the output mode.

Use this method to assign a mode to the output, which must be one of the available modes listed in modes(). If the mode changes and the output is already initialized the resizeGL() event is triggered.

Note
Calling this method from any of the GL events is not allowed, as it could potentially lead to a deadlock. In such cases, the method is simply ignored to prevent issues.

◆ setScale()

void setScale ( Float32  scale)

Set the output scale factor.

Use this method to adjust the scale factor of the output. By default, outputs have a scale factor of 1. Increasing the scale factor, such as setting it to 2, is often suitable for high-definition displays (when dpi() >= 200). It's common for clients to adapt their surface scales to match the scale of the output where they are displayed. If the scale changes and the output is already initialized, the resizeGL() event will be triggered.

Note
Starting from Louvre version 1.2, fractional scales are now supported, see the Scaling Section.
Parameters
scaleThe desired scale factor to set.
See also
See an example of its use in the default implementation of LCompositor::initialized().

◆ scale()

Float32 scale ( ) const

Retrieve the current output scale factor.

This method returns the current scale factor assigned to the output using setScale(). The default scale factor is 1.

If the assigned scale is fractional this value is equal to ceil(scale).

See also
fractionalScale()

◆ fractionalScale()

Float32 fractionalScale ( ) const

Gets the same scale set with setScale().

Set to 1.f by default.

Returns
The fractional scale value.

◆ usingFractionalScale()

bool usingFractionalScale ( ) const

Checks if the scale factor set with setScale() is fractional.

Returns
true if the scale factor is fractional, false otherwise.

◆ fractionalOversamplingEnabled()

bool fractionalOversamplingEnabled ( ) const

Checks if oversampling is enabled.

Oversampling is enabled by default when a fractional scale is set using setScale(). It is always disabled when using an integer scale. You can disable oversampling using enableFractionalOversampling().

Returns
true if oversampling is enabled, false otherwise.

◆ enableFractionalOversampling()

void enableFractionalOversampling ( bool  enabled)

Enable or disable oversampling for fractional scales.

Note
Oversampling is always turned off for integer scales. You can instantly turn oversampling on or off when using a fractional scale. However, it is recommended to perform a full repaint in such cases to ensure the framebuffers stay synchronized.
Parameters
enabledtrue to enable oversampling for fractional scales, false to disable.

◆ repaint()

void repaint ( )

Schedule the next rendering frame.

Calling this method unlocks the output rendering thread, triggering a subsequent paintGL() event. Regardless of the number of repaint() calls within the same frame, paintGL() is invoked only once.
To unlock the rendering thread again, repaint() must be called within or after a paintGL() event.

◆ dpi()

Int32 dpi ( )

Get the dots per inch (DPI) of the output.

This method calculates and returns the dots per inch (DPI) of the output, considering its physical dimensions and the resolution provided by its current mode.

◆ physicalSize()

const LSize & physicalSize ( ) const

Get the physical dimensions of the output.

This method retrieves the physical dimensions of the output in millimeters.

Note
In some cases, such as when the compositor is running inside a virtual machine, the physical size may be (0,0).

◆ size()

const LSize & size ( ) const

Get the output size in compositor coordinates.

This method provides the size of the output in surface coordinates, based on its current mode and scale. It is equivalent to the size given by the rect() method.

◆ sizeB()

const LSize & sizeB ( ) const

Get the output size in buffer coordinates.

This method returns the size of the output in buffer coordinates, based on its current mode.

Note
Since the dimensions provided by this method are in buffer coordinates, they are not affected by the output scale.

◆ rect()

const LRect & rect ( ) const

Get the output rect.

This method provides the position and size of the output in surface coordinates (pos(), size()).

◆ pos()

const LPoint & pos ( ) const

Get the output position in surface coordinates.

This method retrieves the position of the output in surface coordinates assigned with setPos(). It is equivalent to the position given by the rect() method.

◆ setPos()

void setPos ( const LPoint pos)

Set the position of the output.

This method allows you to assign the position of the output in surface coordinates, with the upper-left corner as the origin. If the position changes while the output is initialized, it will trigger the moveGL() event.

Parameters
posThe new position of the output.

◆ name()

const char * name ( ) const

Get the output name.

This method retrieves the name of the output provided by the graphic backend, such as "HDMI-A-2."

Note
Output names are always unique, even if they belong to different GPUs.

◆ model()

const char * model ( ) const

Get the output model name.

This method retrieves the model name of the output provided by the graphic backend.

◆ manufacturer()

const char * manufacturer ( ) const

Get the manufacturer name of the output.

This method retrieves the manufacturer name of the output provided by the graphic backend.

◆ description()

const char * description ( ) const

Get the description of the output.

This method retrieves the description of the output provided by the graphic backend.

◆ painter()

LPainter * painter ( ) const

Get access to the associated LPainter.

This method provides access to the LPainter associated with this output.

◆ threadId()

const std::thread::id & threadId ( ) const

Get the ID of the rendering thread.

This method retrieves the ID of the output rendering thread.

◆ initializeGL()

virtual void initializeGL ( )
virtual

Initialize Event.

The initializeGL() event is invoked by the library after the output is properly initialized.
You can override this method to initialize your shaders, programs, textures, etc.

The default implementation assigns the white color to clear the screen.

Note
Avoid performing painting operations here, as they won't be visible on the screen. Instead, perform painting tasks in the paintGL() event.

Default Implementation

{
painter()->setClearColor(1.f, 1.f, 1.f, 1.f);
}
virtual void initializeGL()
Initialize Event.
LPainter * painter() const
Get access to the associated LPainter.
Definition: LOutput.cpp:352
void setClearColor(Float32 r, Float32 g, Float32 b, Float32 a)
Set the clear color.
Definition: LPainter.cpp:894

◆ paintGL()

virtual void paintGL ( )
virtual

Paint Event.

The paintGL() event is invoked by the library after calling the repaint() method.
Override this method to perform your painting operations.

The default implementation clears the screen, draws the surfaces following the order of the LCompositor::surfaces() list, draws the cursor if the graphic backend does not support cursor composition via hardware, and finally draws the icon of a drag & drop session if there was one.

Note
The default implementation provides a basic rendering method that is quite inefficient since it redraws the entire screen every frame. Check the code of the louvre-weston-clone example compositor to see how to render efficiently with LPainter or consider using the LScene and LView rendering system.

Default Implementation

{
LPainter *p = painter();
LPainter::TextureParams params;
p->clearScreen();
// Check if a surface moved under cursor (simulating a pointer move event)
if (seat()->pointer()->surfaceAt(cursor()->pos()) != seat()->pointer()->focus())
cursor()->pos().x(),
cursor()->pos().y(),
true);
if (seat()->dndManager()->icon())
seat()->dndManager()->icon()->surface()->raise();
// Draw every surface
for (LSurface *s : compositor()->surfaces())
{
// Skip some surfaces
if (!s->mapped() || s->minimized() || s->cursorRole())
{
s->requestNextFrame();
continue;
}
// Current surface rect
LRect currentRect = LRect(
s->rolePos(), // Role pos in surface coords
s->size()); // Surface size in surface coords
// Calc which outputs intersect the surface
for (LOutput *o : compositor()->outputs())
{
if (o->rect().intersects(currentRect))
s->sendOutputEnterEvent(o);
else
s->sendOutputLeaveEvent(o);
}
params.srcRect = s->srcRect();
params.dstSize = s->size();
params.srcScale = s->bufferScale();
params.srcTransform = s->bufferTransform();
params.texture = s->texture();
params.pos = currentRect.pos();
// Bind the surface texture
p->bindTextureMode(params);
// Draw the surface
p->drawRect(currentRect);
// Notify the client it can now render a new surface frame
s->requestNextFrame();
}
// Manualy draw the cursor if hardware composition is not supported
if (!cursor()->hasHardwareSupport(this))
{
p->drawTexture(
cursor()->texture(),
LRect(0, cursor()->texture()->sizeB()),
cursor()->rect());
}
}
LSurface * surface() const
Returns the surface that has acquired the role provided in the constructor.
Definition: LBaseSurfaceRole.cpp:31
LDNDIconRole * icon() const
Drag & drop session icon.
Definition: LDNDManager.cpp:25
static LSeat * seat()
Quick access to the global seat instance.
Definition: LObject.h:36
static LCursor * cursor()
Quick access to the global cursor instance.
Definition: LObject.h:44
static LCompositor * compositor()
Quick access to the global compositor instance.
Definition: LObject.h:28
virtual void paintGL()
Paint Event.
const LPoint & pos() const
Get the output position in surface coordinates.
Definition: LOutput.cpp:312
const LSize & sizeB() const
Get the output size in buffer coordinates.
Definition: LOutput.cpp:302
const LRect & rect() const
Get the output rect.
Definition: LOutput.cpp:307
LOutput(const void *params)
Constructor of the LOutput class.
Definition: LOutput.cpp:31
virtual void pointerMoveEvent(Float32 x, Float32 y, bool absolute)
Pointer move event.
LPointer * pointer() const
Access to pointer events.
Definition: LSeat.cpp:122
LDNDManager * dndManager() const
Access to the drag & drop session manager.
Definition: LSeat.cpp:137
void raise()
Moves a surface to the top of the compositor's surfaces list.
Definition: LSurface.cpp:417
LRectTemplate< Int32, Float32 > LRect
4D vector of 32 bits integers
Definition: LNamespaces.h:252

◆ resizeGL()

virtual void resizeGL ( )
virtual

Resize Event.

The resizeGL() event is invoked by the library when the output scale or mode changes.
Override this method to readjust your graphical interfaces.

Note
Avoid performing any painting operations here, as they won't be visible on the screen. Instead, perform painting tasks in the paintGL() event.

The default implementation simply schedules a new rendering frame with repaint().

Default Implementation

{
}
void repaint()
Schedule the next rendering frame.
Definition: LOutput.cpp:278
virtual void resizeGL()
Resize Event.

◆ moveGL()

virtual void moveGL ( )
virtual

Move Event.

This event is triggered when the output's position changes, such as when the setPos() method is called.
Override this method to readjust your graphical interfaces.

Note
Avoid performing any painting operations here, as they won't be visible on the screen. Instead, perform painting tasks in the paintGL() event.

Default Implementation

{
}
virtual void moveGL()
Move Event.

◆ uninitializeGL()

virtual void uninitializeGL ( )
virtual

Uninitialize Event.

The uninitializeGL() event is invoked by the library after the output is removed from the compositor with LCompositor::removeOutput().
This event is also automatically invoked when the output is unplugged, check the LSeat::outputUnplugged() event.
Override this method to free your shaders, programs, textures, etc.

Note
Avoid performing any painting operations here, as they won't be visible on the screen. Instead, perform painting tasks in the paintGL() event.

Default Implementation

{
/* No default implementation */
}
virtual void uninitializeGL()
Uninitialize Event.

◆ setGammaRequest()

virtual void setGammaRequest ( LClient client,
const LGammaTable gamma 
)
virtual

Set gamma table request.

Clients using the wlr gamma control protocol can request to set the gamma table for an output.

Warning
For security reasons, it is advisable to permit only authorized clients to perform such actions. The default implementation ignores all requests, and the mechanism to identify an authorized client is left to the developer's discretion.

The gamma table (when is not nullptr) always have a size equal to gammaSize(), hence, it is not necessary to validate that.

Parameters
clientPointer to the client making the request.
gammaPointer to the LGammaTable object containing the requested gamma table or nullptr to restore the default table.

Default Implementation

void LOutput::setGammaRequest(LClient *client, const LGammaTable *gamma)
{
L_UNUSED(client)
L_UNUSED(gamma)
/* No default implementation */
}
virtual void setGammaRequest(LClient *client, const LGammaTable *gamma)
Set gamma table request.