wayland: Make SurfaceInterface::{frameRendered,takePresentationFeedback} not touch subsurface tree
This gives us greater flexibility and in general more cleaner code.
This commit is contained in:
parent
9e047059c1
commit
79d5a70c01
8 changed files with 45 additions and 48 deletions
|
@ -580,11 +580,6 @@ void TestSubSurface::testSyncMode()
|
|||
QCOMPARE(childDamagedSpy.count(), 1);
|
||||
QVERIFY(childSurface->isMapped());
|
||||
QVERIFY(parentSurface->isMapped());
|
||||
|
||||
// sending frame rendered to parent should also send it to child
|
||||
QSignalSpy frameRenderedSpy(surface.get(), &KWayland::Client::Surface::frameRendered);
|
||||
parentSurface->frameRendered(100);
|
||||
QVERIFY(frameRenderedSpy.wait());
|
||||
}
|
||||
|
||||
void TestSubSurface::testDeSyncMode()
|
||||
|
|
|
@ -941,9 +941,10 @@ void CursorImage::updateCursorOutputs(const QPointF &pos)
|
|||
void CursorImage::markAsRendered(std::chrono::milliseconds timestamp)
|
||||
{
|
||||
if (m_currentSource == m_serverCursor.surface.get()) {
|
||||
auto cursorSurface = m_serverCursor.surface->surface();
|
||||
if (cursorSurface) {
|
||||
cursorSurface->frameRendered(timestamp.count());
|
||||
if (auto cursorSurface = m_serverCursor.surface->surface()) {
|
||||
cursorSurface->traverseTree([×tamp](SurfaceInterface *surface) {
|
||||
surface->frameRendered(timestamp.count());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,16 +30,9 @@ DragAndDropIconItem::~DragAndDropIconItem()
|
|||
{
|
||||
}
|
||||
|
||||
void DragAndDropIconItem::frameRendered(quint32 timestamp)
|
||||
SurfaceInterface *DragAndDropIconItem::surface() const
|
||||
{
|
||||
if (m_surfaceItem) {
|
||||
m_surfaceItem->surface()->frameRendered(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<PresentationFeedback> DragAndDropIconItem::takePresentationFeedback(Output *output)
|
||||
{
|
||||
return m_surfaceItem ? m_surfaceItem->surface()->takePresentationFeedback(output) : nullptr;
|
||||
return m_surfaceItem ? m_surfaceItem->surface() : nullptr;
|
||||
}
|
||||
|
||||
void DragAndDropIconItem::setOutput(Output *output)
|
||||
|
|
|
@ -25,8 +25,7 @@ public:
|
|||
explicit DragAndDropIconItem(DragAndDropIcon *icon, Scene *scene, Item *parent = nullptr);
|
||||
~DragAndDropIconItem() override;
|
||||
|
||||
void frameRendered(quint32 timestamp);
|
||||
std::unique_ptr<PresentationFeedback> takePresentationFeedback(Output *output);
|
||||
SurfaceInterface *surface() const;
|
||||
|
||||
void setOutput(Output *output);
|
||||
|
||||
|
|
|
@ -201,17 +201,23 @@ void WorkspaceScene::frame(SceneDelegate *delegate, OutputFrame *frame)
|
|||
continue;
|
||||
}
|
||||
if (auto surface = window->surface()) {
|
||||
surface->frameRendered(frameTime.count());
|
||||
if (auto feedback = surface->takePresentationFeedback(output)) {
|
||||
frame->addFeedback(std::move(feedback));
|
||||
}
|
||||
surface->traverseTree([&frameTime, &frame, &output](SurfaceInterface *surface) {
|
||||
surface->frameRendered(frameTime.count());
|
||||
if (auto feedback = surface->takePresentationFeedback(output)) {
|
||||
frame->addFeedback(std::move(feedback));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (m_dndIcon) {
|
||||
m_dndIcon->frameRendered(frameTime.count());
|
||||
if (auto feedback = m_dndIcon->takePresentationFeedback(output)) {
|
||||
frame->addFeedback(std::move(feedback));
|
||||
if (auto surface = m_dndIcon->surface()) {
|
||||
surface->traverseTree([&frameTime, &frame, &output](SurfaceInterface *surface) {
|
||||
surface->frameRendered(frameTime.count());
|
||||
if (auto feedback = surface->takePresentationFeedback(output)) {
|
||||
frame->addFeedback(std::move(feedback));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -467,13 +467,6 @@ void SurfaceInterface::frameRendered(quint32 msec)
|
|||
wl_callback_send_done(resource, msec);
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
for (SubSurfaceInterface *subsurface : std::as_const(d->current->subsurface.below)) {
|
||||
subsurface->surface()->frameRendered(msec);
|
||||
}
|
||||
for (SubSurfaceInterface *subsurface : std::as_const(d->current->subsurface.above)) {
|
||||
subsurface->surface()->frameRendered(msec);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<PresentationFeedback> SurfaceInterface::takePresentationFeedback(Output *output)
|
||||
|
@ -484,16 +477,6 @@ std::unique_ptr<PresentationFeedback> SurfaceInterface::takePresentationFeedback
|
|||
std::vector<std::unique_ptr<PresentationFeedback>> feedbacks;
|
||||
std::move(d->current->presentationFeedbacks.begin(), d->current->presentationFeedbacks.end(), std::back_inserter(feedbacks));
|
||||
d->current->presentationFeedbacks.clear();
|
||||
for (SubSurfaceInterface *subsurface : std::as_const(d->current->subsurface.below)) {
|
||||
auto &subSurfaceFeedbacks = subsurface->surface()->d->current->presentationFeedbacks;
|
||||
std::move(subSurfaceFeedbacks.begin(), subSurfaceFeedbacks.end(), std::back_inserter(feedbacks));
|
||||
subSurfaceFeedbacks.clear();
|
||||
}
|
||||
for (SubSurfaceInterface *subsurface : std::as_const(d->current->subsurface.above)) {
|
||||
auto &subSurfaceFeedbacks = subsurface->surface()->d->current->presentationFeedbacks;
|
||||
std::move(subSurfaceFeedbacks.begin(), subSurfaceFeedbacks.end(), std::back_inserter(feedbacks));
|
||||
subSurfaceFeedbacks.clear();
|
||||
}
|
||||
return std::make_unique<PresentationFeedback>(std::move(feedbacks));
|
||||
}
|
||||
|
||||
|
@ -1260,6 +1243,18 @@ void SurfaceInterface::setLastTransaction(Transaction *transaction)
|
|||
d->lastTransaction = transaction;
|
||||
}
|
||||
|
||||
void SurfaceInterface::traverseTree(std::function<void(SurfaceInterface *surface)> callback)
|
||||
{
|
||||
callback(this);
|
||||
|
||||
for (SubSurfaceInterface *subsurface : std::as_const(d->current->subsurface.below)) {
|
||||
subsurface->surface()->traverseTree(callback);
|
||||
}
|
||||
for (SubSurfaceInterface *subsurface : std::as_const(d->current->subsurface.above)) {
|
||||
subsurface->surface()->traverseTree(callback);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
||||
#include "moc_surface.cpp"
|
||||
|
|
|
@ -379,6 +379,11 @@ public:
|
|||
|
||||
void setPreferredColorDescription(const ColorDescription &descr);
|
||||
|
||||
/**
|
||||
* Traverses the surface sub-tree with this surface as the root.
|
||||
*/
|
||||
void traverseTree(std::function<void(SurfaceInterface *surface)> callback);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when the underlying wl_surface resource is about to be freed.
|
||||
|
|
|
@ -4197,11 +4197,14 @@ void Window::unrefOffscreenRendering()
|
|||
void Window::maybeSendFrameCallback()
|
||||
{
|
||||
if (m_surface && !m_windowItem->isVisible()) {
|
||||
m_surface->frameRendered(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
|
||||
const auto feedback = m_surface->takePresentationFeedback(nullptr);
|
||||
if (feedback) {
|
||||
feedback->presented(std::chrono::nanoseconds(1'000'000'000'000 / output()->refreshRate()), std::chrono::steady_clock::now().time_since_epoch(), PresentationMode::VSync);
|
||||
}
|
||||
const auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
m_surface->traverseTree([this, ×tamp](SurfaceInterface *surface) {
|
||||
surface->frameRendered(timestamp);
|
||||
const auto feedback = surface->takePresentationFeedback(nullptr);
|
||||
if (feedback) {
|
||||
feedback->presented(std::chrono::nanoseconds(1'000'000'000'000 / output()->refreshRate()), std::chrono::steady_clock::now().time_since_epoch(), PresentationMode::VSync);
|
||||
}
|
||||
});
|
||||
// update refresh rate, it might have changed
|
||||
m_offscreenFramecallbackTimer.start(1'000'000 / output()->refreshRate());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue