mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-12-22 21:49:48 +01:00
output: rework state
This commit is contained in:
parent
229fd3a036
commit
03ed93e8b5
4 changed files with 133 additions and 27 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue