mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-23 15:45:59 +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
|
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 || size != swapchain->currentOptions().size) {
|
||||||
|
|
||||||
if (!swapchain)
|
if (!swapchain) {
|
||||||
swapchain = Aquamarine::CSwapchain::create(output->getBackend()->preferredAllocator(), output->getBackend());
|
auto allocator = isDumb && output->getBackend()->fallbackAllocator() ? output->getBackend()->fallbackAllocator() : output->getBackend()->preferredAllocator();
|
||||||
|
swapchain = Aquamarine::CSwapchain::create(allocator, output->getBackend());
|
||||||
|
}
|
||||||
|
|
||||||
auto options = swapchain->currentOptions();
|
auto options = swapchain->currentOptions();
|
||||||
options.size = size;
|
options.size = size;
|
||||||
options.length = 2;
|
options.length = 2;
|
||||||
options.scanout = true;
|
options.scanout = true;
|
||||||
options.cursor = isCursor;
|
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)
|
if (!isCursor && cursorSwapchain)
|
||||||
options.format = cursorSwapchain->currentOptions().format;
|
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,
|
// 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.
|
// but if it's set, we don't wanna change it.
|
||||||
|
|
||||||
if (!swapchain->reconfigure(options)) {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -862,13 +864,21 @@ bool CMonitor::attemptDirectScanout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMonitor::resizeCursorSwapchain(Vector2D size) {
|
bool CMonitor::resizeCursorSwapchain(Vector2D size) {
|
||||||
auto swapchain = resizeSwapchain(cursorSwapchain, size, true);
|
auto swapchain = resizeSwapchain(cursorSwapchain, size, true, useDumbCursorBuffer);
|
||||||
if (!cursorSwapchain)
|
if (!cursorSwapchain)
|
||||||
cursorSwapchain = swapchain;
|
cursorSwapchain = swapchain;
|
||||||
|
|
||||||
return !!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) {
|
bool CMonitor::resizeCursorFallbackSwapchain(Vector2D size) {
|
||||||
auto swapchain = resizeSwapchain(cursorFallbackSwapchain, size, false);
|
auto swapchain = resizeSwapchain(cursorFallbackSwapchain, size, false);
|
||||||
if (!cursorFallbackSwapchain)
|
if (!cursorFallbackSwapchain)
|
||||||
|
|
|
@ -180,6 +180,7 @@ class CMonitor {
|
||||||
void scheduleDone();
|
void scheduleDone();
|
||||||
bool attemptDirectScanout();
|
bool attemptDirectScanout();
|
||||||
bool resizeCursorSwapchain(Vector2D size);
|
bool resizeCursorSwapchain(Vector2D size);
|
||||||
|
bool resizeCursorSwapchain(Vector2D size, bool useDumb);
|
||||||
bool resizeCursorFallbackSwapchain(Vector2D size);
|
bool resizeCursorFallbackSwapchain(Vector2D size);
|
||||||
|
|
||||||
bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
|
@ -194,9 +195,10 @@ class CMonitor {
|
||||||
private:
|
private:
|
||||||
void setupDefaultWS(const SMonitorRule&);
|
void setupDefaultWS(const SMonitorRule&);
|
||||||
int findAvailableDefaultWS();
|
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 {
|
struct {
|
||||||
CHyprSignalListener frame;
|
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 PDUMB = CConfigValue<Hyprlang::INT>("cursor:allow_dumb_copy");
|
||||||
static auto PSLOW = CConfigValue<Hyprlang::INT>("cursor:allow_slow_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)
|
if (!*PDUMB && !*PSLOW)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (*PSLOW) {
|
// slow copy will fail with dumb buffer
|
||||||
|
if (*PSLOW && !*PDUMB) {
|
||||||
Debug::log(TRACE, "[pointer] performing slow copy");
|
Debug::log(TRACE, "[pointer] performing slow copy");
|
||||||
needsFallback = true;
|
needsFallback = true;
|
||||||
|
|
||||||
|
@ -437,8 +452,11 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
|
||||||
auto bufData = buf->beginDataPtr(0);
|
auto bufData = buf->beginDataPtr(0);
|
||||||
auto bufPtr = std::get<0>(bufData);
|
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
|
// 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;
|
auto texBuffer = currentCursorImage.pBuffer ? currentCursorImage.pBuffer : currentCursorImage.surface->resource()->current.buffer;
|
||||||
if (texBuffer) {
|
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);
|
Debug::log(TRACE, "cursor texture {}x{} {} {} {}", textAttrs.size.x, textAttrs.size.y, (void*)texPtr, textAttrs.format, textAttrs.stride);
|
||||||
|
|
||||||
// copy cursor texture
|
// 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);
|
memcpy(bufPtr, texPtr, textAttrs.stride * textAttrs.size.y);
|
||||||
else
|
else
|
||||||
for (int i = 0; i < texBuffer->shm().size.y; i++)
|
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();
|
buf->endDataPtr();
|
||||||
|
|
Loading…
Reference in a new issue