mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-05 22:51:58 -07:00
@@ -75,20 +75,22 @@ CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurf
|
|||||||
});
|
});
|
||||||
|
|
||||||
listeners.surfacePrecommit = surface->events.precommit.registerListener([this](std::any d) {
|
listeners.surfacePrecommit = surface->events.precommit.registerListener([this](std::any d) {
|
||||||
if (!surface->pending.buffer && surface->pending.newBuffer && !surface->pending.texture) {
|
const bool PENDING_HAS_NEW_BUFFER = surface->pending.updated & SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_BUFFER;
|
||||||
|
|
||||||
|
if (!surface->pending.buffer && PENDING_HAS_NEW_BUFFER && !surface->pending.texture) {
|
||||||
removeAllWaiters();
|
removeAllWaiters();
|
||||||
surface->commitPendingState(surface->pending);
|
surface->commitPendingState(surface->pending);
|
||||||
return; // null buffer attached.
|
return; // null buffer attached.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!surface->pending.buffer && !surface->pending.newBuffer && surface->current.buffer) {
|
if (!surface->pending.buffer && !PENDING_HAS_NEW_BUFFER && surface->current.buffer) {
|
||||||
surface->current.bufferDamage.clear();
|
surface->current.bufferDamage.clear();
|
||||||
surface->current.damage.clear();
|
surface->current.damage.clear();
|
||||||
surface->commitPendingState(surface->current);
|
surface->commitPendingState(surface->current);
|
||||||
return; // no new buffer, but we still have current around and a commit happend, commit current again.
|
return; // no new buffer, but we still have current around and a commit happend, commit current again.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!surface->pending.buffer && !surface->pending.newBuffer && !surface->current.buffer) {
|
if (!surface->pending.buffer && !PENDING_HAS_NEW_BUFFER && !surface->current.buffer) {
|
||||||
surface->commitPendingState(surface->pending); // no pending buffer, no current buffer. probably first commit
|
surface->commitPendingState(surface->pending); // no pending buffer, no current buffer. probably first commit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -109,7 +111,8 @@ CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurf
|
|||||||
const auto& state = pendingStates.emplace_back(makeShared<SSurfaceState>(surface->pending));
|
const auto& state = pendingStates.emplace_back(makeShared<SSurfaceState>(surface->pending));
|
||||||
surface->pending.damage.clear();
|
surface->pending.damage.clear();
|
||||||
surface->pending.bufferDamage.clear();
|
surface->pending.bufferDamage.clear();
|
||||||
surface->pending.newBuffer = false;
|
surface->pending.updated &= ~SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_BUFFER;
|
||||||
|
surface->pending.updated &= ~SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_DAMAGE;
|
||||||
surface->pending.buffer.reset();
|
surface->pending.buffer.reset();
|
||||||
|
|
||||||
state->buffer->buffer->syncReleaser = state->buffer->release->createSyncRelease();
|
state->buffer->buffer->syncReleaser = state->buffer->release->createSyncRelease();
|
||||||
|
@@ -71,8 +71,8 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
|
|||||||
resource->setOnDestroy([this](CWlSurface* r) { destroy(); });
|
resource->setOnDestroy([this](CWlSurface* r) { destroy(); });
|
||||||
|
|
||||||
resource->setAttach([this](CWlSurface* r, wl_resource* buffer, int32_t x, int32_t y) {
|
resource->setAttach([this](CWlSurface* r, wl_resource* buffer, int32_t x, int32_t y) {
|
||||||
pending.offset = {x, y};
|
pending.offset = {x, y};
|
||||||
pending.newBuffer = true;
|
pending.updated |= SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_BUFFER | SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_OFFSET;
|
||||||
|
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
pending.buffer.reset();
|
pending.buffer.reset();
|
||||||
@@ -119,11 +119,23 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
|
|||||||
commitPendingState(pending);
|
commitPendingState(pending);
|
||||||
});
|
});
|
||||||
|
|
||||||
resource->setDamage([this](CWlSurface* r, int32_t x, int32_t y, int32_t w, int32_t h) { pending.damage.add(CBox{x, y, w, h}); });
|
resource->setDamage([this](CWlSurface* r, int32_t x, int32_t y, int32_t w, int32_t h) {
|
||||||
resource->setDamageBuffer([this](CWlSurface* r, int32_t x, int32_t y, int32_t w, int32_t h) { pending.bufferDamage.add(CBox{x, y, w, h}); });
|
pending.updated |= SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_DAMAGE;
|
||||||
|
pending.damage.add(CBox{x, y, w, h});
|
||||||
|
});
|
||||||
|
resource->setDamageBuffer([this](CWlSurface* r, int32_t x, int32_t y, int32_t w, int32_t h) {
|
||||||
|
pending.updated |= SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_DAMAGE;
|
||||||
|
pending.bufferDamage.add(CBox{x, y, w, h});
|
||||||
|
});
|
||||||
|
|
||||||
resource->setSetBufferScale([this](CWlSurface* r, int32_t scale) { pending.scale = scale; });
|
resource->setSetBufferScale([this](CWlSurface* r, int32_t scale) {
|
||||||
resource->setSetBufferTransform([this](CWlSurface* r, uint32_t tr) { pending.transform = (wl_output_transform)tr; });
|
pending.updated |= SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_SCALE;
|
||||||
|
pending.scale = scale;
|
||||||
|
});
|
||||||
|
resource->setSetBufferTransform([this](CWlSurface* r, uint32_t tr) {
|
||||||
|
pending.updated |= SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_TRANSFORM;
|
||||||
|
pending.transform = (wl_output_transform)tr;
|
||||||
|
});
|
||||||
|
|
||||||
resource->setSetInputRegion([this](CWlSurface* r, wl_resource* region) {
|
resource->setSetInputRegion([this](CWlSurface* r, wl_resource* region) {
|
||||||
if (!region) {
|
if (!region) {
|
||||||
@@ -131,6 +143,8 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pending.updated |= SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_INPUT;
|
||||||
|
|
||||||
auto RG = CWLRegionResource::fromResource(region);
|
auto RG = CWLRegionResource::fromResource(region);
|
||||||
pending.input = RG->region;
|
pending.input = RG->region;
|
||||||
});
|
});
|
||||||
@@ -141,13 +155,18 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pending.updated |= SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_OPAQUE;
|
||||||
|
|
||||||
auto RG = CWLRegionResource::fromResource(region);
|
auto RG = CWLRegionResource::fromResource(region);
|
||||||
pending.opaque = RG->region;
|
pending.opaque = RG->region;
|
||||||
});
|
});
|
||||||
|
|
||||||
resource->setFrame([this](CWlSurface* r, uint32_t id) { callbacks.emplace_back(makeShared<CWLCallbackResource>(makeShared<CWlCallback>(pClient, 1, id))); });
|
resource->setFrame([this](CWlSurface* r, uint32_t id) { callbacks.emplace_back(makeShared<CWLCallbackResource>(makeShared<CWlCallback>(pClient, 1, id))); });
|
||||||
|
|
||||||
resource->setOffset([this](CWlSurface* r, int32_t x, int32_t y) { pending.offset = {x, y}; });
|
resource->setOffset([this](CWlSurface* r, int32_t x, int32_t y) {
|
||||||
|
pending.updated |= SSurfaceState::eUpdatedProperties::SURFACE_UPDATED_OFFSET;
|
||||||
|
pending.offset = {x, y};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CWLSurfaceResource::~CWLSurfaceResource() {
|
CWLSurfaceResource::~CWLSurfaceResource() {
|
||||||
@@ -403,13 +422,8 @@ CBox CWLSurfaceResource::extends() {
|
|||||||
|
|
||||||
void CWLSurfaceResource::commitPendingState(SSurfaceState& state) {
|
void CWLSurfaceResource::commitPendingState(SSurfaceState& state) {
|
||||||
auto lastTexture = current.texture;
|
auto lastTexture = current.texture;
|
||||||
if (state.newBuffer) {
|
current.updateFrom(state);
|
||||||
state.newBuffer = false;
|
state.updated = 0;
|
||||||
current = state;
|
|
||||||
state.damage.clear();
|
|
||||||
state.bufferDamage.clear();
|
|
||||||
state.buffer.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current.buffer) {
|
if (current.buffer) {
|
||||||
if (current.buffer->buffer->isSynchronous())
|
if (current.buffer->buffer->isSynchronous())
|
||||||
|
@@ -56,3 +56,37 @@ void SSurfaceState::reset() {
|
|||||||
offset = {};
|
offset = {};
|
||||||
size = {};
|
size = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SSurfaceState::updateFrom(SSurfaceState& ref) {
|
||||||
|
updated = ref.updated;
|
||||||
|
|
||||||
|
if (ref.updated & SURFACE_UPDATED_BUFFER) {
|
||||||
|
*this = ref;
|
||||||
|
ref.damage.clear();
|
||||||
|
ref.bufferDamage.clear();
|
||||||
|
ref.buffer.reset();
|
||||||
|
} else {
|
||||||
|
if (ref.updated & SURFACE_UPDATED_DAMAGE) {
|
||||||
|
damage = ref.damage;
|
||||||
|
bufferDamage = ref.bufferDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ref.updated & SURFACE_UPDATED_INPUT)
|
||||||
|
input = ref.input;
|
||||||
|
|
||||||
|
if (ref.updated & SURFACE_UPDATED_OPAQUE)
|
||||||
|
opaque = ref.opaque;
|
||||||
|
|
||||||
|
if (ref.updated & SURFACE_UPDATED_OFFSET)
|
||||||
|
offset = ref.offset;
|
||||||
|
|
||||||
|
if (ref.updated & SURFACE_UPDATED_SCALE)
|
||||||
|
scale = ref.scale;
|
||||||
|
|
||||||
|
if (ref.updated & SURFACE_UPDATED_VIEWPORT)
|
||||||
|
viewport = ref.viewport;
|
||||||
|
|
||||||
|
if (ref.updated & SURFACE_UPDATED_TRANSFORM)
|
||||||
|
transform = ref.transform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -7,6 +7,17 @@ class CHLBufferReference;
|
|||||||
class CTexture;
|
class CTexture;
|
||||||
|
|
||||||
struct SSurfaceState {
|
struct SSurfaceState {
|
||||||
|
enum eUpdatedProperties : uint8_t {
|
||||||
|
SURFACE_UPDATED_OPAQUE = 1 << 0,
|
||||||
|
SURFACE_UPDATED_INPUT = 1 << 1,
|
||||||
|
SURFACE_UPDATED_DAMAGE = 1 << 2,
|
||||||
|
SURFACE_UPDATED_SCALE = 1 << 3,
|
||||||
|
SURFACE_UPDATED_BUFFER = 1 << 4,
|
||||||
|
SURFACE_UPDATED_OFFSET = 1 << 5,
|
||||||
|
SURFACE_UPDATED_VIEWPORT = 1 << 6,
|
||||||
|
SURFACE_UPDATED_TRANSFORM = 1 << 7,
|
||||||
|
};
|
||||||
|
|
||||||
CRegion opaque, input = CBox{{}, {INT32_MAX, INT32_MAX}}, damage, bufferDamage = CBox{{}, {INT32_MAX, INT32_MAX}} /* initial damage */;
|
CRegion opaque, input = CBox{{}, {INT32_MAX, INT32_MAX}}, damage, bufferDamage = CBox{{}, {INT32_MAX, INT32_MAX}} /* initial damage */;
|
||||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
@@ -20,12 +31,15 @@ struct SSurfaceState {
|
|||||||
Vector2D destination;
|
Vector2D destination;
|
||||||
CBox source;
|
CBox source;
|
||||||
} viewport;
|
} viewport;
|
||||||
bool rejected = false;
|
bool rejected = false;
|
||||||
bool newBuffer = false;
|
uint8_t updated = 0; // eUpdatedProperties. Stores what the last update changed
|
||||||
|
|
||||||
Vector2D sourceSize();
|
Vector2D sourceSize();
|
||||||
// Translates damage into bufferDamage, clearing damage and returning the updated bufferDamage
|
// Translates damage into bufferDamage, clearing damage and returning the updated bufferDamage
|
||||||
CRegion accumulateBufferDamage();
|
CRegion accumulateBufferDamage();
|
||||||
void updateSynchronousTexture(SP<CTexture> lastTexture);
|
void updateSynchronousTexture(SP<CTexture> lastTexture);
|
||||||
void reset();
|
void reset();
|
||||||
|
// updates this state from a reference state. Mutates the reference state. If a new buffer is committed,
|
||||||
|
// reference state gets its damage and buffer cleared.
|
||||||
|
void updateFrom(SSurfaceState& ref);
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user