Skip to content

Conversation

@gulafaran
Copy link
Contributor

depending on the attachment and commitstate we might end up calling makecurrent twice on an already current context, and on destruction we also make it current yet again even tho it was current. drivers doesnt keep track of this and is very inefficient when calling this on itself all the time. add a bool and only call it when it has changed or require change.

also remove unusued EGLSurface draw, read.

depending on the attachment and commitstate we might end up calling
makecurrent twice on an already current context, and on destruction we
also make it current yet again even tho it was current. drivers doesnt
keep track of this and is very inefficient when calling this on itself
all the time. add a bool and only call it when it has changed or require
change.
Copy link
Member

@vaxerski vaxerski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if hyprland switches context?

return;

if (!eglMakeCurrent(dpy, savedEGLState.draw, savedEGLState.read, savedEGLState.context))
if (!eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, savedEGLState.context))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rest of this change makes sense but I think we need to restore the saved EGL state in case we're switching from a different context from a higher level call (e.g. mGPU CPU blit I think).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only way the context wouldnt be current is if it got changed in the first place, and since its not threaded it wont be any different from the constructor. im even considering looking into moving most of these calls and ensuring the context switching is minimal, the flamegraph on just a 10 second rendering with a dgpu external monitor 30% is spent in nvidia with eglmakecurrent

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CDRMRenderer::blit initializes an EGL context but then might call primaryRenderer->readBuffer which initializes its own separate EGL context. Once readBuffer returns the EGL context should be reset to the blit's context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well yeah, but currently CEglContextGuard works on constructor/destructor. there is no way it ends up wrong as i can see it. besides ending up calling makecurrent on already current context that is

blit {
 CEglContextGuard()
 
dostuff()
bleh->readBuffer() {
      CEglContextGuard()
      dostuff()
      ~CEglContextGuard()
  }
  
  ~CEglContextGuard()
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'll work with the current code, but if dostuff registered a draw or read surface which was used by blit after readBuffer, the current code would restore that when readBuffer returns and its context guard is destructed, but the new code erases the draw and read surfaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only place the draw or read changes is from using eglMakeCurrent , both hypr and aq uses EGL_NO_SURFACE on all those calls.

@gulafaran
Copy link
Contributor Author

gulafaran commented Jul 31, 2025

what if hyprland switches context?

as below thread, AQ never calls hypr* directly. CEglContextGuard is a "scope" guard constructor/destructor. so with these changes it only changes when needed, and restores if it changed. before it changed no matter, and restored no matter the current context. and incase of blit/readBuffer that "nests" it. previously it would call go from

example

blit {
CEglContextGuard() // make intel current(even if current).

readbuffer {
  CEglContextGuard() // make nvidia current even if current
  foo();
  ~CEglContextGuard() // restore intel or nvidia even if it was current already
}

~CEglContextGuard() // restore blit scope, meaning yet again make intel current.
}

so the destructors alone atleast calls it twice on same context in that code path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants