Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Plasma
KWin
Commits
f07d6bd4
Commit
f07d6bd4
authored
May 04, 2022
by
Xaver Hugl
Committed by
Vlad Zahorodnii
May 10, 2022
Browse files
backends/drm: port the cursor to use output layers
CCBUG: 447797
parent
12515b46
Pipeline
#174306
passed with stage
in 14 minutes and 44 seconds
Changes
26
Pipelines
3
Hide whitespace changes
Inline
Side-by-side
src/backends/drm/CMakeLists.txt
View file @
f07d6bd4
...
...
@@ -31,6 +31,7 @@ set(DRM_SOURCES
egl_gbm_layer_surface.cpp
dmabuf_feedback.cpp
drm_dumb_buffer.cpp
egl_gbm_cursor_layer.cpp
)
add_library
(
KWinWaylandDrmBackend MODULE
${
DRM_SOURCES
}
)
...
...
src/backends/drm/drm_buffer_gbm.cpp
View file @
f07d6bd4
...
...
@@ -196,7 +196,7 @@ std::shared_ptr<GbmBuffer> GbmBuffer::importBuffer(DrmGpu *gpu, KWaylandServer::
}
}
std
::
shared_ptr
<
GbmBuffer
>
GbmBuffer
::
importBuffer
(
DrmGpu
*
gpu
,
GbmBuffer
*
buffer
)
std
::
shared_ptr
<
GbmBuffer
>
GbmBuffer
::
importBuffer
(
DrmGpu
*
gpu
,
GbmBuffer
*
buffer
,
uint32_t
flags
)
{
const
auto
fds
=
buffer
->
fds
();
if
(
fds
[
0
]
==
-
1
)
{
...
...
@@ -219,7 +219,7 @@ std::shared_ptr<GbmBuffer> GbmBuffer::importBuffer(DrmGpu *gpu, GbmBuffer *buffe
data
.
strides
[
i
]
=
strides
[
i
];
data
.
offsets
[
i
]
=
offsets
[
i
];
}
gbm_bo
*
bo
=
gbm_bo_import
(
gpu
->
gbmDevice
(),
GBM_BO_IMPORT_FD_MODIFIER
,
&
data
,
GBM_BO_USE_SCANOUT
);
gbm_bo
*
bo
=
gbm_bo_import
(
gpu
->
gbmDevice
(),
GBM_BO_IMPORT_FD_MODIFIER
,
&
data
,
flags
);
if
(
bo
)
{
return
std
::
make_shared
<
GbmBuffer
>
(
gpu
,
bo
);
}
else
{
...
...
src/backends/drm/drm_buffer_gbm.h
View file @
f07d6bd4
...
...
@@ -14,6 +14,7 @@
#include
<QSharedPointer>
#include
<epoxy/egl.h>
#include
<gbm.h>
struct
gbm_bo
;
...
...
@@ -45,7 +46,7 @@ public:
QSharedPointer
<
GLTexture
>
createTexture
(
EGLDisplay
eglDisplay
)
const
;
static
std
::
shared_ptr
<
GbmBuffer
>
importBuffer
(
DrmGpu
*
gpu
,
KWaylandServer
::
LinuxDmaBufV1ClientBuffer
*
clientBuffer
);
static
std
::
shared_ptr
<
GbmBuffer
>
importBuffer
(
DrmGpu
*
gpu
,
GbmBuffer
*
buffer
);
static
std
::
shared_ptr
<
GbmBuffer
>
importBuffer
(
DrmGpu
*
gpu
,
GbmBuffer
*
buffer
,
uint32_t
flags
=
GBM_BO_USE_SCANOUT
);
private:
void
createFds
()
override
;
...
...
src/backends/drm/drm_gpu.cpp
View file @
f07d6bd4
...
...
@@ -287,7 +287,7 @@ bool DrmGpu::updateOutputs()
addedOutputs
<<
output
;
Q_EMIT
outputAdded
(
output
);
}
pipeline
->
setLayer
(
m_platform
->
renderBackend
()
->
create
DrmPipeline
Layer
(
pipeline
));
pipeline
->
setLayer
s
(
m_platform
->
renderBackend
()
->
create
PrimaryLayer
(
pipeline
),
m_platform
->
renderBackend
()
->
createCursor
Layer
(
pipeline
));
pipeline
->
setActive
(
!
conn
->
isNonDesktop
());
pipeline
->
applyPendingChanges
();
}
...
...
@@ -567,7 +567,7 @@ void DrmGpu::removeOutput(DrmOutput *output)
qCDebug
(
KWIN_DRM
)
<<
"Removing output"
<<
output
;
m_drmOutputs
.
removeOne
(
output
);
m_pipelines
.
removeOne
(
output
->
pipeline
());
output
->
pipeline
()
->
setLayer
(
nullptr
);
output
->
pipeline
()
->
setLayer
s
(
nullptr
,
nullptr
);
m_outputs
.
removeOne
(
output
);
Q_EMIT
outputRemoved
(
output
);
delete
output
;
...
...
@@ -666,7 +666,7 @@ void DrmGpu::removeLeaseOutput(DrmLeaseOutput *output)
qCDebug
(
KWIN_DRM
)
<<
"Removing leased output"
<<
output
;
m_leaseOutputs
.
removeOne
(
output
);
m_pipelines
.
removeOne
(
output
->
pipeline
());
output
->
pipeline
()
->
setLayer
(
nullptr
);
output
->
pipeline
()
->
setLayer
s
(
nullptr
,
nullptr
);
delete
output
;
}
...
...
@@ -790,7 +790,7 @@ void DrmGpu::releaseBuffers()
crtc
->
releaseBuffers
();
}
for
(
const
auto
&
pipeline
:
qAsConst
(
m_pipelines
))
{
pipeline
->
l
ayer
()
->
releaseBuffers
();
pipeline
->
primaryL
ayer
()
->
releaseBuffers
();
}
for
(
const
auto
&
output
:
qAsConst
(
m_outputs
))
{
if
(
const
auto
virtualOutput
=
qobject_cast
<
DrmVirtualOutput
*>
(
output
))
{
...
...
@@ -802,7 +802,7 @@ void DrmGpu::releaseBuffers()
void
DrmGpu
::
recreateSurfaces
()
{
for
(
const
auto
&
pipeline
:
qAsConst
(
m_pipelines
))
{
pipeline
->
setLayer
(
m_platform
->
renderBackend
()
->
create
DrmPipeline
Layer
(
pipeline
));
pipeline
->
setLayer
s
(
m_platform
->
renderBackend
()
->
create
PrimaryLayer
(
pipeline
),
m_platform
->
renderBackend
()
->
createCursor
Layer
(
pipeline
));
pipeline
->
applyPendingChanges
();
}
for
(
const
auto
&
output
:
qAsConst
(
m_outputs
))
{
...
...
src/backends/drm/drm_layer.cpp
View file @
f07d6bd4
...
...
@@ -36,6 +36,30 @@ bool DrmPipelineLayer::hasDirectScanoutBuffer() const
return
false
;
}
DrmOverlayLayer
::
DrmOverlayLayer
(
DrmPipeline
*
pipeline
)
:
DrmPipelineLayer
(
pipeline
)
{
}
void
DrmOverlayLayer
::
setPosition
(
const
QPoint
&
pos
)
{
m_position
=
pos
;
}
QPoint
DrmOverlayLayer
::
position
()
const
{
return
m_position
;
}
void
DrmOverlayLayer
::
setVisible
(
bool
visible
)
{
m_visible
=
visible
;
}
bool
DrmOverlayLayer
::
isVisible
()
const
{
return
m_visible
;
}
}
#include
"drm_layer.moc"
src/backends/drm/drm_layer.h
View file @
f07d6bd4
...
...
@@ -45,4 +45,19 @@ protected:
DrmPipeline
*
const
m_pipeline
;
};
class
DrmOverlayLayer
:
public
DrmPipelineLayer
{
public:
DrmOverlayLayer
(
DrmPipeline
*
pipeline
);
void
setPosition
(
const
QPoint
&
pos
);
void
setVisible
(
bool
visible
);
QPoint
position
()
const
;
bool
isVisible
()
const
;
protected:
QPoint
m_position
;
bool
m_visible
=
false
;
};
}
src/backends/drm/drm_output.cpp
View file @
f07d6bd4
...
...
@@ -19,6 +19,8 @@
#include
"drm_dumb_buffer.h"
#include
"drm_layer.h"
#include
"dumb_swapchain.h"
#include
"egl_gbm_backend.h"
#include
"kwinglutils.h"
#include
"logging.h"
#include
"main.h"
#include
"outputconfiguration.h"
...
...
@@ -102,16 +104,6 @@ DrmOutput::~DrmOutput()
m_pipeline
->
setOutput
(
nullptr
);
}
static
bool
isCursorSpriteCompatible
(
const
QImage
*
buffer
,
const
QImage
*
sprite
)
{
// Note that we need compare the rects in the device independent pixels because the
// buffer and the cursor sprite image may have different scale factors.
const
QRect
bufferRect
(
QPoint
(
0
,
0
),
buffer
->
size
()
/
buffer
->
devicePixelRatio
());
const
QRect
spriteRect
(
QPoint
(
0
,
0
),
sprite
->
size
()
/
sprite
->
devicePixelRatio
());
return
bufferRect
.
contains
(
spriteRect
);
}
void
DrmOutput
::
updateCursor
()
{
static
bool
valid
;
...
...
@@ -120,56 +112,40 @@ void DrmOutput::updateCursor()
m_setCursorSuccessful
=
false
;
return
;
}
if
(
!
m_pipeline
->
crtc
())
{
const
auto
layer
=
m_pipeline
->
cursorLayer
();
if
(
!
m_pipeline
->
crtc
()
||
!
layer
)
{
return
;
}
const
Cursor
*
cursor
=
Cursors
::
self
()
->
currentCursor
();
if
(
!
cursor
)
{
m_pipeline
->
setCursor
(
nullptr
);
if
(
!
cursor
||
cursor
->
image
().
isNull
()
||
Cursors
::
self
()
->
isCursorHidden
())
{
if
(
layer
->
isVisible
())
{
layer
->
setVisible
(
false
);
m_pipeline
->
setCursor
();
}
return
;
}
const
QImage
cursorImage
=
cursor
->
image
();
if
(
cursorImage
.
isNull
()
||
Cursors
::
self
()
->
isCursorHidden
())
{
m_pipeline
->
setCursor
(
nullptr
);
return
;
}
if
(
m_cursor
&&
m_cursor
->
isEmpty
())
{
m_pipeline
->
setCursor
(
nullptr
);
return
;
}
const
auto
plane
=
m_pipeline
->
crtc
()
->
cursorPlane
();
if
(
!
m_cursor
||
(
plane
&&
!
plane
->
formats
().
value
(
m_cursor
->
drmFormat
()).
contains
(
DRM_FORMAT_MOD_LINEAR
)))
{
if
(
plane
&&
(
!
plane
->
formats
().
contains
(
DRM_FORMAT_ARGB8888
)
||
!
plane
->
formats
().
value
(
DRM_FORMAT_ARGB8888
).
contains
(
DRM_FORMAT_MOD_LINEAR
)))
{
m_pipeline
->
setCursor
(
nullptr
);
m_setCursorSuccessful
=
false
;
return
;
}
m_cursor
=
QSharedPointer
<
DumbSwapchain
>::
create
(
m_gpu
,
m_gpu
->
cursorSize
(),
plane
?
DRM_FORMAT_ARGB8888
:
DRM_FORMAT_XRGB8888
,
QImage
::
Format
::
Format_ARGB32_Premultiplied
);
if
(
!
m_cursor
||
m_cursor
->
isEmpty
())
{
m_pipeline
->
setCursor
(
nullptr
);
m_setCursorSuccessful
=
false
;
return
;
const
QMatrix4x4
monitorMatrix
=
logicalToNativeMatrix
(
geometry
(),
scale
(),
transform
());
const
QSize
surfaceSize
=
m_gpu
->
cursorSize
()
/
scale
();
const
QRect
cursorRect
=
monitorMatrix
.
mapRect
(
QRect
(
cursor
->
geometry
().
topLeft
(),
surfaceSize
));
if
(
cursorRect
.
width
()
>
m_gpu
->
cursorSize
().
width
()
||
cursorRect
.
height
()
>
m_gpu
->
cursorSize
().
height
())
{
if
(
layer
->
isVisible
())
{
layer
->
setVisible
(
false
);
m_pipeline
->
setCursor
();
}
}
m_cursor
->
releaseBuffer
(
m_cursor
->
currentBuffer
());
m_cursor
->
acquireBuffer
();
QImage
*
c
=
m_cursor
->
currentBuffer
()
->
image
();
c
->
setDevicePixelRatio
(
scale
());
if
(
!
isCursorSpriteCompatible
(
c
,
&
cursorImage
))
{
// If the cursor image is too big, fall back to rendering the software cursor.
m_pipeline
->
setCursor
(
nullptr
);
m_setCursorSuccessful
=
false
;
return
;
}
c
->
fill
(
Qt
::
transparent
);
QPainter
p
;
p
.
begin
(
c
);
p
.
setWorldTransform
(
logicalToNativeMatrix
(
cursor
->
rect
(),
1
,
transform
()).
toTransform
());
p
.
setRenderHint
(
QPainter
::
SmoothPixmapTransform
);
p
.
drawImage
(
QPoint
(
0
,
0
),
cursorImage
);
p
.
end
();
m_setCursorSuccessful
=
m_pipeline
->
setCursor
(
DrmFramebuffer
::
createFramebuffer
(
m_cursor
->
currentBuffer
()),
logicalToNativeMatrix
(
cursor
->
rect
(),
scale
(),
transform
()).
map
(
cursor
->
hotspot
()));
moveCursor
();
if
(
dynamic_cast
<
EglGbmBackend
*>
(
m_gpu
->
platform
()
->
renderBackend
()))
{
renderCursorOpengl
(
cursor
->
geometry
().
size
()
*
scale
());
}
else
{
renderCursorQPainter
();
}
layer
->
setPosition
(
cursorRect
.
topLeft
());
layer
->
setVisible
(
cursor
->
geometry
().
intersects
(
geometry
()));
if
(
layer
->
isVisible
())
{
m_setCursorSuccessful
=
m_pipeline
->
setCursor
(
logicalToNativeMatrix
(
QRect
(
QPoint
(),
cursorRect
.
size
()),
scale
(),
transform
()).
map
(
cursor
->
hotspot
()));
}
}
void
DrmOutput
::
moveCursor
()
...
...
@@ -177,12 +153,24 @@ void DrmOutput::moveCursor()
if
(
!
m_setCursorSuccessful
||
!
m_pipeline
->
crtc
())
{
return
;
}
const
auto
layer
=
m_pipeline
->
cursorLayer
();
Cursor
*
cursor
=
Cursors
::
self
()
->
currentCursor
();
if
(
!
cursor
||
cursor
->
image
().
isNull
()
||
Cursors
::
self
()
->
isCursorHidden
()
||
!
cursor
->
geometry
().
intersects
(
geometry
()))
{
if
(
layer
->
isVisible
())
{
layer
->
setVisible
(
false
);
m_pipeline
->
setCursor
();
}
return
;
}
const
QMatrix4x4
monitorMatrix
=
logicalToNativeMatrix
(
geometry
(),
scale
(),
transform
());
const
QMatrix4x4
hotspotMatrix
=
logicalToNativeMatrix
(
cursor
->
rect
(),
scale
(),
transform
());
m_moveCursorSuccessful
=
m_pipeline
->
moveCursor
(
monitorMatrix
.
map
(
cursor
->
pos
())
-
hotspotMatrix
.
map
(
cursor
->
hotspot
()));
const
QSize
surfaceSize
=
m_gpu
->
cursorSize
()
/
scale
();
const
QRect
cursorRect
=
monitorMatrix
.
mapRect
(
QRect
(
cursor
->
geometry
().
topLeft
(),
surfaceSize
));
layer
->
setVisible
(
true
);
layer
->
setPosition
(
cursorRect
.
topLeft
());
m_moveCursorSuccessful
=
m_pipeline
->
moveCursor
();
layer
->
setVisible
(
m_moveCursorSuccessful
);
if
(
!
m_moveCursorSuccessful
)
{
m_pipeline
->
setCursor
(
nullptr
);
m_pipeline
->
setCursor
();
}
}
...
...
@@ -322,7 +310,7 @@ bool DrmOutput::present()
}
bool
modeset
=
gpu
()
->
needsModeset
();
if
(
modeset
?
m_pipeline
->
maybeModeset
()
:
m_pipeline
->
present
())
{
Q_EMIT
outputChange
(
m_pipeline
->
l
ayer
()
->
currentDamage
());
Q_EMIT
outputChange
(
m_pipeline
->
primaryL
ayer
()
->
currentDamage
());
return
true
;
}
else
if
(
!
modeset
)
{
qCWarning
(
KWIN_DRM
)
<<
"Presentation failed!"
<<
strerror
(
errno
);
...
...
@@ -393,6 +381,8 @@ void DrmOutput::applyQueuedChanges(const OutputConfiguration &config)
m_renderLoop
->
scheduleRepaint
();
Q_EMIT
changed
();
updateCursor
();
}
void
DrmOutput
::
revertQueuedChanges
()
...
...
@@ -407,7 +397,7 @@ bool DrmOutput::usesSoftwareCursor() const
DrmOutputLayer
*
DrmOutput
::
outputLayer
()
const
{
return
m_pipeline
->
l
ayer
();
return
m_pipeline
->
primaryL
ayer
();
}
void
DrmOutput
::
setColorTransformation
(
const
QSharedPointer
<
ColorTransformation
>
&
transformation
)
...
...
@@ -420,4 +410,76 @@ void DrmOutput::setColorTransformation(const QSharedPointer<ColorTransformation>
m_pipeline
->
revertPendingChanges
();
}
}
void
DrmOutput
::
renderCursorOpengl
(
const
QSize
&
cursorSize
)
{
const
auto
layer
=
m_pipeline
->
cursorLayer
();
auto
allocateTexture
=
[
this
]()
{
const
QImage
img
=
Cursors
::
self
()
->
currentCursor
()
->
image
();
if
(
img
.
isNull
())
{
m_cursorTextureDirty
=
false
;
return
;
}
m_cursorTexture
.
reset
(
new
GLTexture
(
img
));
m_cursorTexture
->
setWrapMode
(
GL_CLAMP_TO_EDGE
);
m_cursorTextureDirty
=
false
;
};
if
(
!
m_cursorTexture
)
{
allocateTexture
();
// handle shape update on case cursor image changed
connect
(
Cursors
::
self
(),
&
Cursors
::
currentCursorChanged
,
this
,
[
this
]()
{
m_cursorTextureDirty
=
true
;
});
}
else
if
(
m_cursorTextureDirty
)
{
const
QImage
image
=
Cursors
::
self
()
->
currentCursor
()
->
image
();
if
(
image
.
size
()
==
m_cursorTexture
->
size
())
{
m_cursorTexture
->
update
(
image
);
m_cursorTextureDirty
=
false
;
}
else
{
allocateTexture
();
}
}
const
auto
[
renderTarget
,
repaint
]
=
layer
->
beginFrame
();
QMatrix4x4
mvp
;
mvp
.
ortho
(
QRect
(
QPoint
(),
renderTarget
.
size
()));
glClear
(
GL_COLOR_BUFFER_BIT
);
glEnable
(
GL_BLEND
);
glBlendFunc
(
GL_SRC_ALPHA
,
GL_ONE_MINUS_SRC_ALPHA
);
m_cursorTexture
->
bind
();
ShaderBinder
binder
(
ShaderTrait
::
MapTexture
);
binder
.
shader
()
->
setUniform
(
GLShader
::
ModelViewProjectionMatrix
,
mvp
);
m_cursorTexture
->
render
(
QRect
(
0
,
0
,
cursorSize
.
width
(),
cursorSize
.
height
()));
m_cursorTexture
->
unbind
();
glDisable
(
GL_BLEND
);
layer
->
endFrame
(
infiniteRegion
(),
infiniteRegion
());
}
void
DrmOutput
::
renderCursorQPainter
()
{
const
auto
layer
=
m_pipeline
->
cursorLayer
();
const
Cursor
*
cursor
=
Cursors
::
self
()
->
currentCursor
();
const
QImage
cursorImage
=
cursor
->
image
();
const
auto
[
renderTarget
,
repaint
]
=
layer
->
beginFrame
();
QImage
*
c
=
std
::
get
<
QImage
*>
(
renderTarget
.
nativeHandle
());
c
->
setDevicePixelRatio
(
scale
());
c
->
fill
(
Qt
::
transparent
);
QPainter
p
;
p
.
begin
(
c
);
p
.
setWorldTransform
(
logicalToNativeMatrix
(
cursor
->
rect
(),
1
,
transform
()).
toTransform
());
p
.
setRenderHint
(
QPainter
::
SmoothPixmapTransform
);
p
.
drawImage
(
QPoint
(
0
,
0
),
cursorImage
);
p
.
end
();
layer
->
endFrame
(
infiniteRegion
(),
infiniteRegion
());
}
}
src/backends/drm/drm_output.h
View file @
f07d6bd4
...
...
@@ -29,6 +29,7 @@ class DrmConnector;
class
DrmGpu
;
class
DrmPipeline
;
class
DumbSwapchain
;
class
GLTexture
;
class
KWIN_EXPORT
DrmOutput
:
public
DrmAbstractOutput
{
...
...
@@ -61,14 +62,16 @@ private:
void
updateCursor
();
void
moveCursor
();
void
renderCursorOpengl
(
const
QSize
&
cursorSize
);
void
renderCursorQPainter
();
DrmPipeline
*
m_pipeline
;
DrmConnector
*
m_connector
;
QSharedPointer
<
DumbSwapchain
>
m_cursor
;
bool
m_setCursorSuccessful
=
false
;
bool
m_moveCursorSuccessful
=
false
;
QRect
m_lastCursorGeometry
;
bool
m_cursorTextureDirty
=
true
;
std
::
unique_ptr
<
GLTexture
>
m_cursorTexture
;
QTimer
m_turnOffTimer
;
};
...
...
src/backends/drm/drm_pipeline.cpp
View file @
f07d6bd4
...
...
@@ -31,6 +31,9 @@
namespace
KWin
{
static
const
QMap
<
uint32_t
,
QVector
<
uint64_t
>>
legacyFormats
=
{{
DRM_FORMAT_XRGB8888
,
{}}};
static
const
QMap
<
uint32_t
,
QVector
<
uint64_t
>>
legacyCursorFormats
=
{{
DRM_FORMAT_ARGB8888
,
{}}};
DrmPipeline
::
DrmPipeline
(
DrmConnector
*
conn
)
:
m_connector
(
conn
)
{
...
...
@@ -182,9 +185,11 @@ bool DrmPipeline::populateAtomicValues(drmModeAtomicReq *req, uint32_t &flags)
m_pending
.
crtc
->
primaryPlane
()
->
setBuffer
(
activePending
()
?
fb
:
nullptr
);
if
(
m_pending
.
crtc
->
cursorPlane
())
{
m_pending
.
crtc
->
cursorPlane
()
->
set
(
QPoint
(
0
,
0
),
gpu
()
->
cursorSize
(),
m_pending
.
cursorPos
,
gpu
()
->
cursorSize
());
m_pending
.
crtc
->
cursorPlane
()
->
setBuffer
(
activePending
()
?
m_pending
.
cursorFb
.
get
()
:
nullptr
);
m_pending
.
crtc
->
cursorPlane
()
->
setPending
(
DrmPlane
::
PropertyIndex
::
CrtcId
,
(
activePending
()
&&
m_pending
.
cursorFb
)
?
m_pending
.
crtc
->
id
()
:
0
);
const
auto
layer
=
cursorLayer
();
bool
active
=
activePending
()
&&
layer
->
isVisible
();
m_pending
.
crtc
->
cursorPlane
()
->
set
(
QPoint
(
0
,
0
),
gpu
()
->
cursorSize
(),
layer
->
position
(),
gpu
()
->
cursorSize
());
m_pending
.
crtc
->
cursorPlane
()
->
setBuffer
(
active
?
layer
->
currentBuffer
().
get
()
:
nullptr
);
m_pending
.
crtc
->
cursorPlane
()
->
setPending
(
DrmPlane
::
PropertyIndex
::
CrtcId
,
active
?
m_pending
.
crtc
->
id
()
:
0
);
}
}
if
(
!
m_connector
->
atomicPopulate
(
req
))
{
...
...
@@ -289,7 +294,7 @@ void DrmPipeline::atomicCommitSuccessful(CommitMode mode)
m_pending
.
crtc
->
primaryPlane
()
->
setNext
(
m_pending
.
layer
->
currentBuffer
());
m_pending
.
crtc
->
primaryPlane
()
->
commit
();
if
(
m_pending
.
crtc
->
cursorPlane
())
{
m_pending
.
crtc
->
cursorPlane
()
->
setNext
(
m_pending
.
cursorFb
);
m_pending
.
crtc
->
cursorPlane
()
->
setNext
(
cursorLayer
()
->
currentBuffer
()
);
m_pending
.
crtc
->
cursorPlane
()
->
commit
();
}
}
...
...
@@ -300,40 +305,30 @@ void DrmPipeline::atomicCommitSuccessful(CommitMode mode)
}
}
bool
DrmPipeline
::
setCursor
(
const
std
::
shared_ptr
<
DrmFramebuffer
>
&
buffer
,
const
QPoint
&
hotspot
)
bool
DrmPipeline
::
setCursor
(
const
QPoint
&
hotspot
)
{
if
(
m_pending
.
cursorFb
==
buffer
&&
m_pending
.
cursorHotspot
==
hotspot
)
{
return
true
;
}
bool
result
;
const
bool
visibleBefore
=
isCursorVisible
();
m_pending
.
cursorFb
=
buffer
;
m_pending
.
cursorHotspot
=
hotspot
;
// explicitly check for the cursor plane and not for AMS, as we might not always have one
if
(
m_pending
.
crtc
->
cursorPlane
())
{
result
=
commitPipelines
({
this
},
CommitMode
::
Test
);
if
(
result
&&
m_output
)
{
m_output
->
renderLoop
()
->
scheduleRepaint
();
}
}
else
{
result
=
setCursorLegacy
();
}
if
(
result
)
{
m_next
=
m_pending
;
if
(
m_output
&&
(
visibleBefore
||
isCursorVisible
()))
{
m_output
->
renderLoop
()
->
scheduleRepaint
();
}
}
else
{
m_pending
=
m_next
;
}
return
result
;
}
bool
DrmPipeline
::
moveCursor
(
QPoint
pos
)
bool
DrmPipeline
::
moveCursor
()
{
if
(
m_pending
.
cursorPos
==
pos
)
{
return
true
;
}
const
bool
visibleBefore
=
isCursorVisible
();
bool
result
;
m_pending
.
cursorPos
=
pos
;
// explicitly check for the cursor plane and not for AMS, as we might not always have one
if
(
m_pending
.
crtc
->
cursorPlane
())
{
result
=
commitPipelines
({
this
},
CommitMode
::
Test
);
...
...
@@ -342,7 +337,7 @@ bool DrmPipeline::moveCursor(QPoint pos)
}
if
(
result
)
{
m_next
=
m_pending
;
if
(
m_output
&&
(
visibleBefore
||
isCursorVisible
())
)
{
if
(
m_output
)
{
m_output
->
renderLoop
()
->
scheduleRepaint
();
}
}
else
{
...
...
@@ -368,12 +363,6 @@ QSize DrmPipeline::bufferSize() const
return
modeSize
;
}
bool
DrmPipeline
::
isCursorVisible
()
const
{
const
QRect
mode
=
QRect
(
QPoint
(),
m_pending
.
mode
->
size
());
return
m_pending
.
cursorFb
&&
(
!
m_pending
.
cursorFb
->
buffer
()
||
QRect
(
m_pending
.
cursorPos
,
m_pending
.
cursorFb
->
buffer
()
->
size
()).
intersects
(
mode
));
}
DrmConnector
*
DrmPipeline
::
connector
()
const
{
return
m_connector
;
...
...
@@ -414,6 +403,15 @@ QMap<uint32_t, QVector<uint64_t>> DrmPipeline::formats() const
return
m_pending
.
formats
;
}
QMap
<
uint32_t
,
QVector
<
uint64_t
>>
DrmPipeline
::
cursorFormats
()
const
{
if
(
m_pending
.
crtc
&&
m_pending
.
crtc
->
cursorPlane
())
{
return
m_pending
.
crtc
->
cursorPlane
()
->
formats
();
}
else
{
return
legacyCursorFormats
;
}
}
bool
DrmPipeline
::
pruneModifier
()
{
if
(
!
m_pending
.
layer
->
currentBuffer
()
...
...
@@ -582,11 +580,16 @@ bool DrmPipeline::enabled() const
return
m_pending
.
enabled
;
}
DrmPipelineLayer
*
DrmPipeline
::
l
ayer
()
const
DrmPipelineLayer
*
DrmPipeline
::
primaryL
ayer
()
const
{
return
m_pending
.
layer
.
get
();
}
DrmOverlayLayer
*
DrmPipeline
::
cursorLayer
()
const
{
return
m_pending
.
cursorLayer
.
get
();
}
DrmPlane
::
Transformations
DrmPipeline
::
renderOrientation
()
const
{
return
m_pending
.
renderOrientation
;
...
...
@@ -612,8 +615,6 @@ Output::RgbRange DrmPipeline::rgbRange() const
return
m_pending
.
rgbRange
;
}
static
const
QMap
<
uint32_t
,
QVector
<
uint64_t
>>
legacyFormats
=
{{
DRM_FORMAT_XRGB8888
,
{}}};
void
DrmPipeline
::
setCrtc
(
DrmCrtc
*
crtc
)
{
if
(
crtc
&&
m_pending
.
crtc
&&
crtc
->
gammaRampSize
()
!=
m_pending
.
crtc
->
gammaRampSize
()
&&
m_pending
.
colorTransformation
)
{
...
...
@@ -642,9 +643,10 @@ void DrmPipeline::setEnable(bool enable)
m_pending
.
enabled
=
enable
;
}
void
DrmPipeline
::
setLayer
(
const
QSharedPointer
<
DrmPipelineLayer
>
&
l
ayer
)
void
DrmPipeline
::
setLayer
s
(
const
QSharedPointer
<
DrmPipelineLayer
>
&
primaryLayer
,
const
QSharedPointer
<
DrmOverlayLayer
>
&
cursorL
ayer
)
{
m_pending
.
layer
=
layer
;
m_pending
.
layer
=
primaryLayer
;
m_pending
.
cursorLayer
=
cursorLayer
;
}
void
DrmPipeline
::
setRenderOrientation
(
DrmPlane
::
Transformations
orientation
)
...
...
src/backends/drm/drm_pipeline.h
View file @
f07d6bd4
...
...
@@ -31,6 +31,7 @@ class DrmCrtc;
class
GammaRamp
;
class
DrmConnectorMode
;
class
DrmPipelineLayer
;
class
DrmOverlayLayer
;
class
DrmGammaRamp
{
...
...
@@ -65,8 +66,8 @@ public:
void
applyPendingChanges
();
void
revertPendingChanges
();
bool
setCursor
(
const
std
::
shared_ptr
<
DrmFramebuffer
>
&
buffer
,
const
QPoint
&
hotspot
=
QPoint
());
bool
moveCursor
(
QPoint
pos
);
bool
setCursor
(
const
QPoint
&
hotspot
=
QPoint
());
bool
moveCursor
();
DrmConnector
*
connector
()
const
;
DrmCrtc
*
currentCrtc
()
const
;
...
...
@@ -83,6 +84,7 @@ public:
QSize
bufferSize
()
const
;
QMap
<
uint32_t
,
QVector
<
uint64_t
>>
formats
()
const
;
QMap
<
uint32_t
,
QVector
<
uint64_t
>>
cursorFormats
()
const
;
bool
pruneModifier
();
void
setOutput
(
DrmOutput
*
output
);
...
...
@@ -92,7 +94,8 @@ public:
QSharedPointer
<
DrmConnectorMode
>
mode
()
const
;
bool
active
()
const
;
bool
enabled
()
const
;
DrmPipelineLayer
*
layer
()
const
;
DrmPipelineLayer
*
primaryLayer
()
const
;
DrmOverlayLayer
*
cursorLayer
()
const
;
DrmPlane
::
Transformations
renderOrientation
()
const
;
DrmPlane
::
Transformations
bufferOrientation
()
const
;
RenderLoopPrivate
::
SyncMode
syncMode
()
const
;
...
...
@@ -103,7 +106,7 @@ public:
void
setMode
(
const
QSharedPointer
<
DrmConnectorMode
>
&
mode
);
void
setActive
(
bool
active
);
void
setEnable
(
bool
enable
);
void
setLayer
(
const
QSharedPointer
<
DrmPipelineLayer
>
&
l
ayer
);
void
setLayer
s
(
const
QSharedPointer