Fixes for direct scanout
This commit is contained in:
parent
16f27d2dc6
commit
bda47c9043
2 changed files with 53 additions and 48 deletions
|
@ -629,10 +629,17 @@ void EglGbmBackend::setViewport(const Output &output) const
|
|||
|
||||
QRegion EglGbmBackend::beginFrame(int screenId)
|
||||
{
|
||||
auto output = m_outputs[screenId];
|
||||
if (output.directScanoutBuffer) {
|
||||
gbm_bo_destroy(output.directScanoutBuffer);
|
||||
output.directScanoutBuffer = nullptr;
|
||||
output.surfaceInterface = nullptr;
|
||||
output.bufferInterface = nullptr;
|
||||
}
|
||||
if (isPrimary()) {
|
||||
return prepareRenderingForOutput(m_outputs[screenId]);
|
||||
return prepareRenderingForOutput(output);
|
||||
} else {
|
||||
return renderingBackend()->beginFrameForSecondaryGpu(m_outputs.at(screenId).output);
|
||||
return renderingBackend()->beginFrameForSecondaryGpu(output.output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,13 +649,6 @@ QRegion EglGbmBackend::prepareRenderingForOutput(Output &output) const
|
|||
prepareRenderFramebuffer(output);
|
||||
setViewport(output);
|
||||
|
||||
if (output.directScanoutBuffer) {
|
||||
gbm_bo_destroy(output.directScanoutBuffer);
|
||||
output.directScanoutBuffer = nullptr;
|
||||
output.surfaceInterface = nullptr;
|
||||
output.bufferInterface = nullptr;
|
||||
}
|
||||
|
||||
if (supportsBufferAge()) {
|
||||
QRegion region;
|
||||
|
||||
|
@ -750,6 +750,9 @@ bool EglGbmBackend::scanout(int screenId, KWaylandServer::SurfaceInterface *surf
|
|||
} else {
|
||||
damage = output.output->geometry();
|
||||
}
|
||||
if (output.directScanoutBuffer) {
|
||||
gbm_bo_destroy(output.directScanoutBuffer);
|
||||
}
|
||||
output.directScanoutBuffer = importedBuffer;
|
||||
output.surfaceInterface = surface;
|
||||
output.bufferInterface = buffer;
|
||||
|
|
|
@ -626,52 +626,54 @@ void SceneOpenGL::paint(int screenId, const QRegion &damage, const QList<Topleve
|
|||
scaling = 1;
|
||||
}
|
||||
|
||||
bool directScanout = false;
|
||||
if (m_backend->directScanoutAllowed(screenId)) {
|
||||
EffectsHandlerImpl *implEffects = static_cast<EffectsHandlerImpl*>(effects);
|
||||
if (!implEffects->blocksDirectScanout()) {
|
||||
for (int i = stacking_order.count() - 1; i >= 0; i--) {
|
||||
Window *window = stacking_order[i];
|
||||
AbstractClient *c = dynamic_cast<AbstractClient*>(window->window());
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
if (c->isOnScreen(screenId)) {
|
||||
if (window->isOpaque() && c->isFullScreen()) {
|
||||
auto pixmap = window->windowPixmap<WindowPixmap>();
|
||||
if (!pixmap) {
|
||||
break;
|
||||
}
|
||||
pixmap->update();
|
||||
pixmap = pixmap->topMostSurface();
|
||||
// the subsurface has to be able to cover the whole window
|
||||
if (pixmap->position() != QPoint(0, 0)) {
|
||||
break;
|
||||
}
|
||||
directScanout = m_backend->scanout(screenId, pixmap->surface());
|
||||
const GLenum status = glGetGraphicsResetStatus();
|
||||
if (status != GL_NO_ERROR) {
|
||||
handleGraphicsReset(status);
|
||||
} else {
|
||||
renderLoop->beginFrame();
|
||||
|
||||
bool directScanout = false;
|
||||
if (m_backend->directScanoutAllowed(screenId)) {
|
||||
EffectsHandlerImpl *implEffects = static_cast<EffectsHandlerImpl*>(effects);
|
||||
if (!implEffects->blocksDirectScanout()) {
|
||||
for (int i = stacking_order.count() - 1; i >= 0; i--) {
|
||||
Window *window = stacking_order[i];
|
||||
AbstractClient *c = dynamic_cast<AbstractClient*>(window->window());
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
if (c->isOnScreen(screenId)) {
|
||||
if (window->isOpaque() && c->isFullScreen()) {
|
||||
auto pixmap = window->windowPixmap<WindowPixmap>();
|
||||
if (!pixmap) {
|
||||
break;
|
||||
}
|
||||
pixmap->update();
|
||||
pixmap = pixmap->topMostSurface();
|
||||
// the subsurface has to be able to cover the whole window
|
||||
if (pixmap->position() != QPoint(0, 0)) {
|
||||
break;
|
||||
}
|
||||
directScanout = m_backend->scanout(screenId, pixmap->surface());
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!directScanout) {
|
||||
|
||||
// prepare rendering makes context current on the output
|
||||
repaint = m_backend->beginFrame(screenId);
|
||||
|
||||
GLVertexBuffer::setVirtualScreenGeometry(geo);
|
||||
GLRenderTarget::setVirtualScreenGeometry(geo);
|
||||
GLVertexBuffer::setVirtualScreenScale(scaling);
|
||||
GLRenderTarget::setVirtualScreenScale(scaling);
|
||||
|
||||
const GLenum status = glGetGraphicsResetStatus();
|
||||
if (status != GL_NO_ERROR) {
|
||||
handleGraphicsReset(status);
|
||||
if (directScanout) {
|
||||
renderLoop->endFrame();
|
||||
} else {
|
||||
// prepare rendering makescontext current on the output
|
||||
repaint = m_backend->beginFrame(screenId);
|
||||
|
||||
GLVertexBuffer::setVirtualScreenGeometry(geo);
|
||||
GLRenderTarget::setVirtualScreenGeometry(geo);
|
||||
GLVertexBuffer::setVirtualScreenScale(scaling);
|
||||
GLRenderTarget::setVirtualScreenScale(scaling);
|
||||
|
||||
int mask = 0;
|
||||
updateProjectionMatrix();
|
||||
renderLoop->beginFrame();
|
||||
|
||||
paintScreen(&mask, damage.intersected(geo), repaint, &update, &valid,
|
||||
renderLoop, projectionMatrix(), geo, scaling); // call generic implementation
|
||||
|
|
Loading…
Reference in a new issue