Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions examples/tinywl/helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ void Helper::init()
qw_output_state newState;
newState.set_gamma_lut(ramp_size, r, g, b);

if (!qwOutput->commit_state(newState)) {
if (!getOutput(WOutput::fromHandle(qwOutput))->commitState(newState.handle())) {
qw_gamma_control_v1::from(gamma_control)->send_failed_and_destroy();
}
});
Expand Down Expand Up @@ -441,9 +441,9 @@ void Helper::init()
}

if (onlyTest)
ok &= output->handle()->test_state(newState);
ok &= getOutput(output)->testState(newState.handle());
else
ok &= output->handle()->commit_state(newState);
ok &= getOutput(output)->commitState(newState.handle());
}
wOutputManager->sendResult(config, ok);
});
Expand Down Expand Up @@ -662,10 +662,9 @@ void Helper::setCursorPosition(const QPointF &position)
void Helper::allowNonDrmOutputAutoChangeMode(WOutput *output)
{
output->safeConnect(&qw_output::notify_request_state,
this, [this] (wlr_output_event_request_state *newState) {
this, [this, output] (wlr_output_event_request_state *newState) {
if (newState->state->committed & WLR_OUTPUT_STATE_MODE) {
auto output = qobject_cast<qw_output*>(sender());
output->commit_state(newState->state);
getOutput(output)->commitState(newState->state);
}
});
}
Expand All @@ -689,7 +688,7 @@ void Helper::enableOutput(WOutput *output)
newState.set_mode(mode);
}
newState.set_enabled(true);
bool ok = qwoutput->commit_state(newState);
bool ok = getOutput(output)->commitState(newState);
Q_ASSERT(ok);
}
}
Expand Down
16 changes: 16 additions & 0 deletions examples/tinywl/output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,22 @@ void Output::updatePositionFromLayout()
m_item->setPosition(pos);
}

bool Output::commitState(const wlr_output_state *state)
{
auto viewport = screenViewport();
if (!viewport)
return false;
return viewport->commitState(state);
}

bool Output::testState(const wlr_output_state *state)
{
auto viewport = screenViewport();
if (!viewport)
return false;
return viewport->testState(state);
}

std::pair<WOutputViewport*, QQuickItem*> Output::getOutputItemProperty()
{
WOutputViewport *viewportCopy = outputItem()->findChild<WOutputViewport*>({}, Qt::FindDirectChildrenOnly);
Expand Down
3 changes: 3 additions & 0 deletions examples/tinywl/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ class Output : public SurfaceListModel
WOutputViewport *screenViewport() const;
void updatePositionFromLayout();

bool commitState(const wlr_output_state *state);
bool testState(const wlr_output_state *state);

signals:
void exclusiveZoneChanged();
void moveResizeFinised();
Expand Down
38 changes: 20 additions & 18 deletions src/server/qtquick/woutputhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@ class Q_DECL_HIDDEN WOutputHelperPrivate : public WObjectPrivate
output->safeConnect(&qw_output::notify_frame, qq, [this] {
on_frame();
});
output->safeConnect(&qw_output::notify_needs_frame, qq, [this] {
setNeedsFrame(true);
qwoutput()->qw_output::schedule_frame();
});
output->safeConnect(&qw_output::notify_needs_frame, qq, &WOutputHelper::requestFrame);
output->safeConnect(&qw_output::notify_damage, qq, [this] {
on_damage();
});
Expand Down Expand Up @@ -134,8 +131,10 @@ void WOutputHelperPrivate::on_frame()

void WOutputHelperPrivate::on_damage()
{
setContentIsDirty(true);
Q_EMIT q_func()->damaged();
// The damage envent is from wlr_cursor.

// The cursor's implementation is in WOutputLayer,
// is not in wlroots, so don't do anything here.
}

qw_buffer *WOutputHelperPrivate::acquireBuffer(wlr_swapchain **sc, int *bufferAge)
Expand Down Expand Up @@ -214,18 +213,6 @@ qw_buffer *WOutputHelper::buffer() const
return d->state.buffer ? qw_buffer::from(d->state.buffer) : nullptr;
}

void WOutputHelper::setScale(float scale)
{
W_D(WOutputHelper);
wlr_output_state_set_scale(&d->state, scale);
}

void WOutputHelper::setTransform(WOutput::Transform t)
{
W_D(WOutputHelper);
wlr_output_state_set_transform(&d->state, static_cast<wl_output_transform>(t));
}

void WOutputHelper::setDamage(const pixman_region32 *damage)
{
W_D(WOutputHelper);
Expand Down Expand Up @@ -256,6 +243,14 @@ bool WOutputHelper::commit()
{
W_D(WOutputHelper);
wlr_output_state state = d->state;
if (state.committed == 0)
return false;

if (state.committed != WLR_OUTPUT_STATE_LAYERS) {
Q_ASSERT_X(state.committed & WLR_OUTPUT_STATE_BUFFER, Q_FUNC_INFO,
"WOutputHelper::commit: buffer is not set, you will got a black frame");
}

wlr_output_state_init(&d->state);
bool ok = d->qwoutput()->commit_state(&state);
wlr_output_state_finish(&state);
Expand Down Expand Up @@ -335,6 +330,13 @@ void WOutputHelper::update()
d->update();
}

void WOutputHelper::requestFrame()
{
W_D(WOutputHelper);
d->setNeedsFrame(true);
d->qwoutput()->schedule_frame();
}

WAYLIB_SERVER_END_NAMESPACE

#include "moc_woutputhelper.cpp"
4 changes: 1 addition & 3 deletions src/server/qtquick/woutputhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ class WAYLIB_SERVER_EXPORT WOutputHelper : public QObject, public WObject
void setBuffer(QW_NAMESPACE::qw_buffer *buffer);
QW_NAMESPACE::qw_buffer *buffer() const;

void setScale(float scale);
void setTransform(WOutput::Transform t);
void setDamage(const pixman_region32 *damage);
const pixman_region32 *damage() const;
void setLayers(const wlr_output_layer_state_array &layers);
Expand All @@ -68,13 +66,13 @@ class WAYLIB_SERVER_EXPORT WOutputHelper : public QObject, public WObject

void resetState(bool resetRenderable);
void update();
void requestFrame();

protected:
WOutputHelper(WOutput *output, bool renderable, bool contentIsDirty, bool needsFrame, QObject *parent = nullptr);

Q_SIGNALS:
void requestRender();
void damaged();
void renderableChanged();
void contentIsDirtyChanged();
void needsFrameChanged();
Expand Down
69 changes: 55 additions & 14 deletions src/server/qtquick/woutputrenderwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ class Q_DECL_HIDDEN OutputHelper : public WOutputHelper

inline void init() {
connect(this, &OutputHelper::requestRender, renderWindow(), qOverload<>(&WOutputRenderWindow::render));
connect(this, &OutputHelper::damaged, renderWindow(), &WOutputRenderWindow::scheduleRender);
// TODO: pre update scale after WOutputHelper::setScale
output()->output()->safeConnect(&WOutput::scaleChanged, this, &OutputHelper::updateSceneDPR);
}
Expand Down Expand Up @@ -241,12 +240,13 @@ class Q_DECL_HIDDEN OutputHelper : public WOutputHelper
WBufferRenderer *afterRender();
WBufferRenderer *compositeLayers(const QVector<LayerData*> layers, bool forceShadowRenderer);
bool commit(WBufferRenderer *buffer);
qw_buffer* lastBuffer() const;
bool tryToHardwareCursor(const LayerData *layer);

private:
WOutputViewport *m_output = nullptr;
QList<LayerData*> m_layers;
WBufferRenderer *m_lastCommitBuffer = nullptr;
QPointer<WBufferRenderer> m_lastCommitBuffer;
// only for render cursor
QPointer<WBufferRenderer> m_cursorRenderer;
BufferRendererProxy *m_cursorLayerProxy = nullptr;
Expand Down Expand Up @@ -1069,6 +1069,13 @@ bool OutputHelper::commit(WBufferRenderer *buffer)
return WOutputHelper::commit();
}

qw_buffer *OutputHelper::lastBuffer() const
{
if (Q_UNLIKELY(!m_lastCommitBuffer))
return nullptr;
return m_lastCommitBuffer->lastBuffer();
}

bool OutputHelper::tryToHardwareCursor(const LayerData *layer)
{
do {
Expand Down Expand Up @@ -1646,10 +1653,10 @@ void WOutputRenderWindow::attach(WOutputLayer *layer, WOutputViewport *output)

auto outputHelper = d->getOutputHelper(output);
if (outputHelper && outputHelper->attachLayer(wapper))
d->scheduleDoRender();
outputHelper->requestFrame();

connect(layer, &WOutputLayer::flagsChanged, this, &WOutputRenderWindow::scheduleRender);
connect(layer, &WOutputLayer::zChanged, this, &WOutputRenderWindow::scheduleRender);
connect(layer, &WOutputLayer::flagsChanged, outputHelper, &OutputHelper::requestFrame);
connect(layer, &WOutputLayer::zChanged, outputHelper, &OutputHelper::requestFrame);

if (auto od = WOutputViewportPrivate::get(output)) {
od->notifyLayersChanged();
Expand Down Expand Up @@ -1739,24 +1746,59 @@ QList<WOutputLayer *> WOutputRenderWindow::hardwareLayers(const WOutputViewport
return list;
}

void WOutputRenderWindow::setOutputScale(WOutputViewport *output, float scale)
bool WOutputRenderWindow::commitOutputState(WOutputViewport *output, const wlr_output_state *state)
{
Q_D(WOutputRenderWindow);

if (auto helper = d->getOutputHelper(output)) {
helper->setScale(scale);
update();
auto helper = d->getOutputHelper(output);
auto buffer = helper->lastBuffer();

if ((state->committed & WLR_OUTPUT_STATE_BUFFER)
|| !buffer) {
return helper->qwoutput()->commit_state(state);
}

wlr_output_state new_state;
// Don't use the wlr_output_state_copy, we need only a shallow copy
new_state = *state;
wlr_output_state_set_buffer(&new_state, *buffer);

bool ok = helper->qwoutput()->commit_state(&new_state);
// lock in wlr_output_state_set_buffer
buffer->unlock();

if ((state->committed
& (WLR_OUTPUT_STATE_MODE
| WLR_OUTPUT_STATE_SCALE
| WLR_OUTPUT_STATE_TRANSFORM)) != 0) {
helper->update();
}

return ok;
}

void WOutputRenderWindow::rotateOutput(WOutputViewport *output, WOutput::Transform t)
bool WOutputRenderWindow::testOutputState(WOutputViewport *output, const wlr_output_state *state)
{
Q_D(WOutputRenderWindow);

if (auto helper = d->getOutputHelper(output)) {
helper->setTransform(t);
update();
auto helper = d->getOutputHelper(output);
auto buffer = helper->lastBuffer();

if ((state->committed & WLR_OUTPUT_STATE_BUFFER)
|| !buffer) {
return helper->qwoutput()->test_state(state);
}

wlr_output_state new_state;
// Don't use the wlr_output_state_copy, we need only a shallow copy
new_state = *state;
wlr_output_state_set_buffer(&new_state, *buffer);

bool ok = helper->qwoutput()->test_state(&new_state);
// lock in wlr_output_state_set_buffer
buffer->unlock();

return ok;
}

void WOutputRenderWindow::init(qw_renderer *renderer, qw_allocator *allocator)
Expand Down Expand Up @@ -1876,7 +1918,6 @@ void WOutputRenderWindow::update(WOutputViewport *output)
int index = d->indexOfOutputHelper(output);
Q_ASSERT(index >= 0);
d->outputs.at(index)->update();
d->scheduleDoRender();
}

qreal WOutputRenderWindow::width() const
Expand Down
5 changes: 2 additions & 3 deletions src/server/qtquick/woutputrenderwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ class WAYLIB_SERVER_EXPORT WOutputRenderWindow : public QQuickWindow, public QQm
WOutputViewport *mapFrom, QQuickItem *mapTo);
void detach(WOutputLayer *layer, WOutputViewport *output);

void setOutputScale(WOutputViewport *output, float scale);
void rotateOutput(WOutputViewport *output, WOutput::Transform t);
void setOutputEnabled(WOutputViewport *output, bool enabled);
bool commitOutputState(WOutputViewport *output, const wlr_output_state *state);
bool testOutputState(WOutputViewport *output, const wlr_output_state *state);

void init(QW_NAMESPACE::qw_renderer *renderer, QW_NAMESPACE::qw_allocator *allocator);
QW_NAMESPACE::qw_renderer *renderer() const;
Expand Down
34 changes: 30 additions & 4 deletions src/server/qtquick/woutputviewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,18 +493,44 @@ void WOutputViewport::setDepends(const QList<WOutputViewport *> &newDepends)
Q_EMIT dependsChanged();
}

bool WOutputViewport::commitState(const wlr_output_state *state)
{
W_D(WOutputViewport);
if (auto window = d->outputWindow()) {
return window->commitOutputState(this, state);
}

return false;
}

bool WOutputViewport::testState(const wlr_output_state *state)
{
W_D(WOutputViewport);
if (auto window = d->outputWindow()) {
return window->testOutputState(this, state);
}

return false;
}

void WOutputViewport::setOutputScale(float scale)
{
W_D(WOutputViewport);
if (auto window = d->outputWindow())
window->setOutputScale(this, scale);
if (auto window = d->outputWindow()) {
qw_output_state state;
state.set_scale(scale);
window->commitOutputState(this, state.handle());
}
}

void WOutputViewport::rotateOutput(WOutput::Transform t)
{
W_D(WOutputViewport);
if (auto window = d->outputWindow())
window->rotateOutput(this, t);
if (auto window = d->outputWindow()) {
qw_output_state state;
state.set_transform(static_cast<wl_output_transform>(t));
window->commitOutputState(this, state.handle());
}
}

void WOutputViewport::render(bool doCommit)
Expand Down
3 changes: 3 additions & 0 deletions src/server/qtquick/woutputviewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ class WAYLIB_SERVER_EXPORT WOutputViewport : public QQuickItem, public virtual W
QList<WOutputViewport *> depends() const;
void setDepends(const QList<WOutputViewport *> &newDepends);

bool commitState(const wlr_output_state *state);
bool testState(const wlr_output_state *state);

public Q_SLOTS:
void setOutputScale(float scale);
void rotateOutput(WOutput::Transform t);
Expand Down