mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-27 02:06:00 +01:00
fix dumb cursor buffers
This commit is contained in:
parent
7238dd9d38
commit
c120740a43
3 changed files with 42 additions and 12 deletions
|
@ -396,25 +396,27 @@ int CMonitor::findAvailableDefaultWS() {
|
|||
return INT32_MAX; // shouldn't be reachable
|
||||
}
|
||||
|
||||
SP<Aquamarine::CSwapchain> CMonitor::resizeSwapchain(SP<Aquamarine::CSwapchain> swapchain, Vector2D size, bool isCursor) {
|
||||
SP<Aquamarine::CSwapchain> CMonitor::resizeSwapchain(SP<Aquamarine::CSwapchain> swapchain, Vector2D size, bool isCursor, bool isDumb) {
|
||||
if (!swapchain || size != swapchain->currentOptions().size) {
|
||||
|
||||
if (!swapchain)
|
||||
swapchain = Aquamarine::CSwapchain::create(output->getBackend()->preferredAllocator(), output->getBackend());
|
||||
if (!swapchain) {
|
||||
auto allocator = isDumb && output->getBackend()->fallbackAllocator() ? output->getBackend()->fallbackAllocator() : output->getBackend()->preferredAllocator();
|
||||
swapchain = Aquamarine::CSwapchain::create(allocator, output->getBackend());
|
||||
}
|
||||
|
||||
auto options = swapchain->currentOptions();
|
||||
options.size = size;
|
||||
options.length = 2;
|
||||
options.scanout = true;
|
||||
options.cursor = isCursor;
|
||||
options.multigpu = output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_iDRMFD;
|
||||
options.multigpu = !isDumb && output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_iDRMFD;
|
||||
if (!isCursor && cursorSwapchain)
|
||||
options.format = cursorSwapchain->currentOptions().format;
|
||||
// We do not set the format. If it's unset (DRM_FORMAT_INVALID) then the swapchain will pick for us,
|
||||
// but if it's set, we don't wanna change it.
|
||||
|
||||
if (!swapchain->reconfigure(options)) {
|
||||
Debug::log(TRACE, "Failed to reconfigure {} swapchain", isCursor ? "cursor" : "cursor fallback");
|
||||
Debug::log(TRACE, "Failed to reconfigure{} {} swapchain", isCursor ? "cursor" : "cursor fallback", isDumb ? " dumb" : "");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -862,13 +864,21 @@ bool CMonitor::attemptDirectScanout() {
|
|||
}
|
||||
|
||||
bool CMonitor::resizeCursorSwapchain(Vector2D size) {
|
||||
auto swapchain = resizeSwapchain(cursorSwapchain, size, true);
|
||||
auto swapchain = resizeSwapchain(cursorSwapchain, size, true, useDumbCursorBuffer);
|
||||
if (!cursorSwapchain)
|
||||
cursorSwapchain = swapchain;
|
||||
|
||||
return !!swapchain;
|
||||
}
|
||||
|
||||
bool CMonitor::resizeCursorSwapchain(Vector2D size, bool useDumb) {
|
||||
if (useDumbCursorBuffer != useDumb && cursorSwapchain) {
|
||||
useDumbCursorBuffer = useDumb;
|
||||
cursorSwapchain = nullptr; // recreate swapchain with a different allocator
|
||||
}
|
||||
return resizeCursorSwapchain(size);
|
||||
}
|
||||
|
||||
bool CMonitor::resizeCursorFallbackSwapchain(Vector2D size) {
|
||||
auto swapchain = resizeSwapchain(cursorFallbackSwapchain, size, false);
|
||||
if (!cursorFallbackSwapchain)
|
||||
|
|
|
@ -180,6 +180,7 @@ class CMonitor {
|
|||
void scheduleDone();
|
||||
bool attemptDirectScanout();
|
||||
bool resizeCursorSwapchain(Vector2D size);
|
||||
bool resizeCursorSwapchain(Vector2D size, bool useDumb);
|
||||
bool resizeCursorFallbackSwapchain(Vector2D size);
|
||||
|
||||
bool m_bEnabled = false;
|
||||
|
@ -194,9 +195,10 @@ class CMonitor {
|
|||
private:
|
||||
void setupDefaultWS(const SMonitorRule&);
|
||||
int findAvailableDefaultWS();
|
||||
SP<Aquamarine::CSwapchain> resizeSwapchain(SP<Aquamarine::CSwapchain> swapchain, Vector2D size, bool isCursor);
|
||||
SP<Aquamarine::CSwapchain> resizeSwapchain(SP<Aquamarine::CSwapchain> swapchain, Vector2D size, bool isCursor, bool isDumb = false);
|
||||
|
||||
wl_event_source* doneSource = nullptr;
|
||||
wl_event_source* doneSource = nullptr;
|
||||
bool useDumbCursorBuffer = false;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener frame;
|
||||
|
|
|
@ -411,10 +411,25 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
|||
static auto PDUMB = CConfigValue<Hyprlang::INT>("cursor:allow_dumb_copy");
|
||||
static auto PSLOW = CConfigValue<Hyprlang::INT>("cursor:allow_slow_copy");
|
||||
|
||||
auto isDumb = buf->type() == Aquamarine::BUFFER_TYPE_DMABUF_DUMB;
|
||||
if (isDumb != *PDUMB) {
|
||||
Debug::log(TRACE, "[pointer] switching swapchain to {}", *PDUMB ? "dumb" : "gbm");
|
||||
if (!state->monitor->resizeCursorSwapchain(maxSize, *PDUMB))
|
||||
return nullptr;
|
||||
|
||||
buf = state->monitor->cursorSwapchain->next(nullptr);
|
||||
if (!buf) {
|
||||
Debug::log(TRACE, "Failed to acquire a buffer from the cursor swapchain");
|
||||
return nullptr;
|
||||
}
|
||||
isDumb = buf->type() == Aquamarine::BUFFER_TYPE_DMABUF_DUMB;
|
||||
}
|
||||
|
||||
if (!*PDUMB && !*PSLOW)
|
||||
return nullptr;
|
||||
|
||||
if (*PSLOW) {
|
||||
// slow copy will fail with dumb buffer
|
||||
if (*PSLOW && !*PDUMB) {
|
||||
Debug::log(TRACE, "[pointer] performing slow copy");
|
||||
needsFallback = true;
|
||||
|
||||
|
@ -437,8 +452,11 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
|||
auto bufData = buf->beginDataPtr(0);
|
||||
auto bufPtr = std::get<0>(bufData);
|
||||
|
||||
auto bufSize = isDumb ? buf->shm().size : buf->dmabuf().size;
|
||||
auto bufStride = isDumb ? buf->shm().stride : buf->dmabuf().strides[0];
|
||||
|
||||
// clear buffer
|
||||
memset(bufPtr, 0, buf->type() == Aquamarine::BUFFER_TYPE_DMABUF_DUMB ? std::get<2>(bufData) * buf->dmabuf().size.y : std::get<2>(bufData));
|
||||
memset(bufPtr, 0, bufStride * bufSize.y);
|
||||
|
||||
auto texBuffer = currentCursorImage.pBuffer ? currentCursorImage.pBuffer : currentCursorImage.surface->resource()->current.buffer;
|
||||
if (texBuffer) {
|
||||
|
@ -448,11 +466,11 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
|||
Debug::log(TRACE, "cursor texture {}x{} {} {} {}", textAttrs.size.x, textAttrs.size.y, (void*)texPtr, textAttrs.format, textAttrs.stride);
|
||||
|
||||
// copy cursor texture
|
||||
if (buf->dmabuf().strides[0] == textAttrs.stride && buf->dmabuf().size == textAttrs.size)
|
||||
if (bufStride == textAttrs.stride && bufSize == textAttrs.size)
|
||||
memcpy(bufPtr, texPtr, textAttrs.stride * textAttrs.size.y);
|
||||
else
|
||||
for (int i = 0; i < texBuffer->shm().size.y; i++)
|
||||
memcpy(bufPtr + i * buf->dmabuf().strides[0], texPtr + i * textAttrs.stride, textAttrs.stride);
|
||||
memcpy(bufPtr + i * bufStride, texPtr + i * textAttrs.stride, textAttrs.stride);
|
||||
}
|
||||
|
||||
buf->endDataPtr();
|
||||
|
|
Loading…
Reference in a new issue