mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 03:46:00 +01:00
initial impl of ctm
This commit is contained in:
parent
b82fdaff91
commit
62031d59bb
6 changed files with 44 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <hyprutils/memory/WeakPtr.hpp>
|
||||
#include <wayland-client.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <optional>
|
||||
|
||||
namespace Aquamarine {
|
||||
class CDRMBackend;
|
||||
|
@ -162,6 +163,7 @@ namespace Aquamarine {
|
|||
bool ownModeID = false;
|
||||
uint32_t modeID = 0;
|
||||
uint32_t gammaLut = 0;
|
||||
uint32_t ctm = 0;
|
||||
} atomic;
|
||||
|
||||
Hyprutils::Memory::CSharedPointer<SDRMPlane> primary;
|
||||
|
@ -175,6 +177,7 @@ namespace Aquamarine {
|
|||
uint32_t vrr_enabled;
|
||||
uint32_t gamma_lut;
|
||||
uint32_t gamma_lut_size;
|
||||
uint32_t ctm;
|
||||
|
||||
// atomic-modesetting only
|
||||
|
||||
|
@ -242,13 +245,16 @@ namespace Aquamarine {
|
|||
uint32_t flags = 0;
|
||||
bool test = false;
|
||||
drmModeModeInfo modeInfo;
|
||||
std::optional<Hyprutils::Math::Mat3x3> ctm;
|
||||
|
||||
struct {
|
||||
uint32_t gammaLut = 0;
|
||||
uint32_t fbDamage = 0;
|
||||
uint32_t modeBlob = 0;
|
||||
uint32_t ctmBlob = 0;
|
||||
bool blobbed = false;
|
||||
bool gammad = false;
|
||||
bool ctmd = false;
|
||||
} atomic;
|
||||
|
||||
void calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <hyprutils/signal/Signal.hpp>
|
||||
#include <hyprutils/memory/SharedPtr.hpp>
|
||||
#include <hyprutils/math/Region.hpp>
|
||||
#include <hyprutils/math/Mat3x3.hpp>
|
||||
#include <drm_fourcc.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include "../allocator/Swapchain.hpp"
|
||||
|
@ -51,6 +52,7 @@ namespace Aquamarine {
|
|||
AQ_OUTPUT_STATE_BUFFER = (1 << 7),
|
||||
AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE = (1 << 8),
|
||||
AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE = (1 << 9),
|
||||
AQ_OUTPUT_STATE_CTM = (1 << 10),
|
||||
};
|
||||
|
||||
struct SInternalState {
|
||||
|
@ -67,6 +69,7 @@ namespace Aquamarine {
|
|||
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
||||
Hyprutils::Memory::CSharedPointer<IBuffer> buffer;
|
||||
int64_t explicitInFence = -1, explicitOutFence = -1;
|
||||
Hyprutils::Math::Mat3x3 ctm;
|
||||
};
|
||||
|
||||
const SInternalState& state();
|
||||
|
@ -84,6 +87,7 @@ namespace Aquamarine {
|
|||
void setExplicitInFence(int64_t fenceFD); // -1 removes
|
||||
void setExplicitOutFence(int64_t fenceFD); // -1 removes
|
||||
void resetExplicitFences();
|
||||
void setCTM(const Hyprutils::Math::Mat3x3& ctm);
|
||||
|
||||
private:
|
||||
SInternalState internalState;
|
||||
|
|
|
@ -1183,6 +1183,8 @@ void Aquamarine::SDRMConnector::recheckCRTCProps() {
|
|||
output->supportsExplicit = backend->drmProps.supportsTimelines && crtc->props.out_fence_ptr && crtc->primary->props.in_fence_fd;
|
||||
|
||||
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Explicit sync {}", output->supportsExplicit ? "supported" : "unsupported"));
|
||||
|
||||
backend->backend->log(AQ_LOG_DEBUG, std::format("drm: connector {} crtc {} CTM", szName, (crtc->props.ctm ? "supports" : "doesn't support")));
|
||||
}
|
||||
|
||||
void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) {
|
||||
|
@ -1577,6 +1579,9 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) {
|
|||
}
|
||||
}
|
||||
|
||||
if (COMMITTED & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_CTM)
|
||||
data.ctm = STATE.ctm;
|
||||
|
||||
data.blocking = BLOCKING || formatMismatch;
|
||||
data.modeset = NEEDS_RECONFIG || lastCommitNoBuffer || formatMismatch;
|
||||
data.flags = flags;
|
||||
|
|
|
@ -38,6 +38,7 @@ static const struct prop_info crtc_info[] = {
|
|||
#define INDEX(name) (offsetof(SDRMCRTC::UDRMCRTCProps, name) / sizeof(uint32_t))
|
||||
{"ACTIVE", INDEX(active)}, {"GAMMA_LUT", INDEX(gamma_lut)}, {"GAMMA_LUT_SIZE", INDEX(gamma_lut_size)},
|
||||
{"MODE_ID", INDEX(mode_id)}, {"OUT_FENCE_PTR", INDEX(out_fence_ptr)}, {"VRR_ENABLED", INDEX(vrr_enabled)},
|
||||
{"CTM", INDEX(ctm)},
|
||||
#undef INDEX
|
||||
};
|
||||
|
||||
|
|
|
@ -100,6 +100,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
|
|||
if (data.modeset && enable && connector->props.max_bpc && connector->maxBpcBounds.at(1))
|
||||
add(connector->id, connector->props.max_bpc, 8); // FIXME: this isnt always 8
|
||||
|
||||
if (data.ctm.has_value() && connector->crtc->props.ctm && data.atomic.ctmBlob && data.atomic.ctmd)
|
||||
add(connector->crtc->id, connector->crtc->props.ctm, data.atomic.ctmBlob);
|
||||
|
||||
add(connector->crtc->id, connector->crtc->props.active, enable);
|
||||
|
||||
if (enable) {
|
||||
|
@ -197,6 +200,7 @@ void Aquamarine::CDRMAtomicRequest::rollback(SDRMConnectorCommitData& data) {
|
|||
if (data.atomic.blobbed)
|
||||
rollbackBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
|
||||
rollbackBlob(&conn->crtc->atomic.gammaLut, data.atomic.gammaLut);
|
||||
rollbackBlob(&conn->crtc->atomic.ctm, data.atomic.ctmBlob);
|
||||
destroyBlob(data.atomic.fbDamage);
|
||||
}
|
||||
|
||||
|
@ -211,6 +215,7 @@ void Aquamarine::CDRMAtomicRequest::apply(SDRMConnectorCommitData& data) {
|
|||
if (data.atomic.blobbed)
|
||||
commitBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
|
||||
commitBlob(&conn->crtc->atomic.gammaLut, data.atomic.gammaLut);
|
||||
commitBlob(&conn->crtc->atomic.ctm, data.atomic.ctmBlob);
|
||||
destroyBlob(data.atomic.fbDamage);
|
||||
}
|
||||
|
||||
|
@ -263,6 +268,24 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin
|
|||
}
|
||||
}
|
||||
|
||||
if ((STATE.committed & COutputState::AQ_OUTPUT_STATE_CTM) && data.ctm.has_value()) {
|
||||
if (!connector->crtc->props.ctm)
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to commit ctm: no ctm prop support");
|
||||
else {
|
||||
drm_color_ctm ctm = {0};
|
||||
for (size_t i = 0; i < 9; ++i) {
|
||||
const double val = data.ctm->getMatrix()[i];
|
||||
ctm.matrix[i] = static_cast<uint64_t>(val * std::pow(2, 32));
|
||||
}
|
||||
|
||||
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, &ctm, sizeof(drm_color_ctm), &data.atomic.ctmBlob)) {
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a ctm blob");
|
||||
data.atomic.ctmBlob = 0;
|
||||
} else
|
||||
data.atomic.ctmd = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((STATE.committed & COutputState::AQ_OUTPUT_STATE_DAMAGE) && connector->crtc->primary->props.fb_damage_clips && MODE) {
|
||||
if (STATE.damage.empty())
|
||||
data.atomic.fbDamage = 0;
|
||||
|
|
|
@ -115,6 +115,11 @@ void Aquamarine::COutputState::resetExplicitFences() {
|
|||
internalState.explicitOutFence = -1;
|
||||
}
|
||||
|
||||
void Aquamarine::COutputState::setCTM(const Hyprutils::Math::Mat3x3& ctm) {
|
||||
internalState.ctm = ctm;
|
||||
internalState.committed |= AQ_OUTPUT_STATE_CTM;
|
||||
}
|
||||
|
||||
void Aquamarine::COutputState::onCommit() {
|
||||
internalState.committed = 0;
|
||||
internalState.damage.clear();
|
||||
|
|
Loading…
Reference in a new issue