output: rework state

This commit is contained in:
Vaxry 2024-06-22 17:31:01 +02:00
parent 229fd3a036
commit 03ed93e8b5
4 changed files with 133 additions and 27 deletions

View file

@ -37,7 +37,20 @@ namespace Aquamarine {
class COutputState { class COutputState {
public: public:
// TODO: make this state private, this sucks enum eOutputStateProperties : uint32_t {
AQ_OUTPUT_STATE_DAMAGE = (1 << 0),
AQ_OUTPUT_STATE_ENABLED = (1 << 1),
AQ_OUTPUT_STATE_ADAPTIVE_SYNC = (1 << 2),
AQ_OUTPUT_STATE_PRESENTATION_MODE = (1 << 3),
AQ_OUTPUT_STATE_GAMMA_LUT = (1 << 4),
AQ_OUTPUT_STATE_MODE = (1 << 5),
AQ_OUTPUT_STATE_FORMAT = (1 << 6),
AQ_OUTPUT_STATE_BUFFER = (1 << 7),
};
struct SInternalState {
uint32_t committed = 0; // enum eOutputStateProperties
Hyprutils::Math::CRegion damage; Hyprutils::Math::CRegion damage;
bool enabled = false; bool enabled = false;
bool adaptiveSync = false; bool adaptiveSync = false;
@ -50,6 +63,28 @@ namespace Aquamarine {
Hyprutils::Memory::CSharedPointer<IBuffer> buffer; Hyprutils::Memory::CSharedPointer<IBuffer> buffer;
}; };
const SInternalState& state();
void addDamage(const Hyprutils::Math::CRegion& region);
void clearDamage();
void setEnabled(bool enabled);
void setAdaptiveSync(bool enabled);
void setPresentationMode(eOutputPresentationMode mode);
void setGammaLut(const std::vector<uint16_t>& lut);
void setMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
void setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
void setFormat(uint32_t drmFormat);
void setBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer);
private:
SInternalState internalState;
void onCommit(); // clears a few props like damage and committed.
friend class IOutput;
friend class CWaylandOutput;
};
class IOutput { class IOutput {
public: public:
virtual ~IOutput() { virtual ~IOutput() {
@ -68,7 +103,6 @@ namespace Aquamarine {
std::string name, description, make, model, serial; std::string name, description, make, model, serial;
Hyprutils::Math::Vector2D physicalSize; Hyprutils::Math::Vector2D physicalSize;
bool enabled = false; bool enabled = false;
bool adaptiveSync = false;
bool nonDesktop = false; bool nonDesktop = false;
eSubpixelMode subpixel = AQ_SUBPIXEL_NONE; eSubpixelMode subpixel = AQ_SUBPIXEL_NONE;

View file

@ -231,10 +231,12 @@ Aquamarine::CWaylandPointer::CWaylandPointer(SP<CCWlPointer> pointer_, Hyprutils
backend->backend->log(AQ_LOG_DEBUG, "New wayland pointer wl_pointer"); backend->backend->log(AQ_LOG_DEBUG, "New wayland pointer wl_pointer");
pointer->setMotion([this](CCWlPointer* r, uint32_t serial, wl_fixed_t x, wl_fixed_t y) { pointer->setMotion([this](CCWlPointer* r, uint32_t serial, wl_fixed_t x, wl_fixed_t y) {
if (!backend->focusedOutput || (!backend->focusedOutput->state->mode && !backend->focusedOutput->state->customMode)) const auto STATE = backend->focusedOutput->state->state();
if (!backend->focusedOutput || (!STATE.mode && !STATE.customMode))
return; return;
const Vector2D size = backend->focusedOutput->state->customMode ? backend->focusedOutput->state->customMode->pixelSize : backend->focusedOutput->state->mode->pixelSize; const Vector2D size = STATE.customMode ? STATE.customMode->pixelSize : STATE.mode->pixelSize;
Vector2D local = {wl_fixed_to_double(x), wl_fixed_to_double(y)}; Vector2D local = {wl_fixed_to_double(x), wl_fixed_to_double(y)};
local = local / size; local = local / size;
@ -496,16 +498,16 @@ bool Aquamarine::CWaylandOutput::commit() {
Vector2D pixelSize = {}; Vector2D pixelSize = {};
uint32_t refreshRate = 0; uint32_t refreshRate = 0;
if (state->customMode) if (state->internalState.customMode)
pixelSize = state->customMode->pixelSize; pixelSize = state->internalState.customMode->pixelSize;
else if (state->mode) else if (state->internalState.mode)
pixelSize = state->mode->pixelSize; pixelSize = state->internalState.mode->pixelSize;
else { else {
backend->backend->log(AQ_LOG_ERROR, std::format("Output {}: pending state rejected: invalid mode", name)); backend->backend->log(AQ_LOG_ERROR, std::format("Output {}: pending state rejected: invalid mode", name));
return false; return false;
} }
uint32_t format = state->drmFormat; uint32_t format = state->internalState.drmFormat;
if (format == DRM_FORMAT_INVALID) { if (format == DRM_FORMAT_INVALID) {
backend->backend->log(AQ_LOG_ERROR, std::format("Output {}: pending state rejected: invalid format", name)); backend->backend->log(AQ_LOG_ERROR, std::format("Output {}: pending state rejected: invalid format", name));
@ -522,12 +524,19 @@ bool Aquamarine::CWaylandOutput::commit() {
return false; return false;
} }
if (!state->buffer) { if (!state->internalState.buffer) {
// if the consumer explicitly committed a null buffer, that's a violation.
if (state->internalState.committed & COutputState::AQ_OUTPUT_STATE_BUFFER) {
backend->backend->log(AQ_LOG_ERROR, std::format("Output {}: pending state rejected: no buffer", name)); backend->backend->log(AQ_LOG_ERROR, std::format("Output {}: pending state rejected: no buffer", name));
return false; return false;
} }
auto wlBuffer = wlBufferFromBuffer(state->buffer); events.commit.emit();
state->onCommit();
return true;
}
auto wlBuffer = wlBufferFromBuffer(state->internalState.buffer);
if (!wlBuffer) { if (!wlBuffer) {
backend->backend->log(AQ_LOG_ERROR, std::format("Output {}: pending state rejected: no wlBuffer??", name)); backend->backend->log(AQ_LOG_ERROR, std::format("Output {}: pending state rejected: no wlBuffer??", name));
@ -547,6 +556,8 @@ bool Aquamarine::CWaylandOutput::commit() {
events.commit.emit(); events.commit.emit();
state->onCommit();
return true; return true;
} }

View file

@ -26,3 +26,64 @@ void Aquamarine::IOutput::scheduleFrame() {
Hyprutils::Math::Vector2D Aquamarine::IOutput::maxCursorSize() { Hyprutils::Math::Vector2D Aquamarine::IOutput::maxCursorSize() {
return {}; // error return {}; // error
} }
const Aquamarine::COutputState::SInternalState& Aquamarine::COutputState::state() {
return internalState;
}
void Aquamarine::COutputState::addDamage(const Hyprutils::Math::CRegion& region) {
internalState.damage.add(region);
internalState.committed |= AQ_OUTPUT_STATE_DAMAGE;
}
void Aquamarine::COutputState::clearDamage() {
internalState.damage.clear();
internalState.committed |= AQ_OUTPUT_STATE_DAMAGE;
}
void Aquamarine::COutputState::setEnabled(bool enabled) {
internalState.enabled = enabled;
internalState.committed |= AQ_OUTPUT_STATE_ENABLED;
}
void Aquamarine::COutputState::setAdaptiveSync(bool enabled) {
internalState.adaptiveSync = enabled;
internalState.committed |= AQ_OUTPUT_STATE_ADAPTIVE_SYNC;
}
void Aquamarine::COutputState::setPresentationMode(eOutputPresentationMode mode) {
internalState.presentationMode = mode;
internalState.committed |= AQ_OUTPUT_STATE_PRESENTATION_MODE;
}
void Aquamarine::COutputState::setGammaLut(const std::vector<uint16_t>& lut) {
internalState.gammaLut = lut;
internalState.committed |= AQ_OUTPUT_STATE_GAMMA_LUT;
}
void Aquamarine::COutputState::setMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode) {
internalState.mode = mode;
internalState.customMode = nullptr;
internalState.committed |= AQ_OUTPUT_STATE_MODE;
}
void Aquamarine::COutputState::setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode) {
internalState.mode.reset();
internalState.customMode = mode;
internalState.committed |= AQ_OUTPUT_STATE_MODE;
}
void Aquamarine::COutputState::setFormat(uint32_t drmFormat) {
internalState.drmFormat = drmFormat;
internalState.committed |= AQ_OUTPUT_STATE_FORMAT;
}
void Aquamarine::COutputState::setBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer) {
internalState.buffer = buffer;
internalState.committed |= AQ_OUTPUT_STATE_BUFFER;
}
void Aquamarine::COutputState::onCommit() {
internalState.committed = 0;
internalState.damage.clear();
}

View file

@ -34,16 +34,16 @@ void onFrame() {
auto buf = output->swapchain->next(nullptr); auto buf = output->swapchain->next(nullptr);
output->state->buffer = buf; output->state->setBuffer(buf);
output->commit(); output->commit();
} }
void onState(const Aquamarine::IOutput::SStateEvent& event) { void onState(const Aquamarine::IOutput::SStateEvent& event) {
std::cout << "[Client] onState with size " << std::format("{}", event.size) << "\n"; std::cout << "[Client] onState with size " << std::format("{}", event.size) << "\n";
output->state->enabled = true; output->state->setEnabled(true);
output->state->customMode = makeShared<Aquamarine::SOutputMode>(Aquamarine::SOutputMode{.pixelSize = event.size}); output->state->setCustomMode(makeShared<Aquamarine::SOutputMode>(Aquamarine::SOutputMode{.pixelSize = event.size}));
output->state->drmFormat = DRM_FORMAT_XRGB8888; output->state->setFormat(DRM_FORMAT_XRGB8888);
output->commit(); output->commit();
} }