From 2bb63f9e52b4cb025061734c171252564d69c6a9 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 3 May 2016 11:57:06 +0200 Subject: D3D12: Implement grabWindow Change-Id: Icb8151f26bad68795eb2e1f920297267c880b40b Reviewed-by: Andy Nichols --- .../scenegraph/d3d12/qsgd3d12renderloop.cpp | 31 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp') diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp index 83ba443800..fccb127c4f 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp @@ -367,8 +367,16 @@ bool QSGD3D12RenderThread::event(QEvent *e) Q_ASSERT(wme->window == exposedWindow || !exposedWindow); mutex.lock(); if (wme->window) { - // ### - Q_UNREACHABLE(); + // Grabbing is generally done by rendering a frame and reading the + // color buffer contents back, without presenting, and then + // creating a QImage from the returned data. It is terribly + // inefficient since it involves a full blocking wait for the GPU. + // However, our hands are tied by the existing, synchronous APIs of + // QQuickWindow and such. + QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window); + wd->syncSceneGraph(); + wd->renderSceneGraph(wme->window->size()); + *wme->image = engine->executeAndWaitReadbackRenderTarget(); } if (Q_UNLIKELY(debug_loop())) qDebug("RT - WM_Grab - waking gui to handle result"); @@ -733,7 +741,14 @@ QImage QSGD3D12RenderLoop::grab(QQuickWindow *window) qDebug() << "grab" << window; WindowData *w = windowFor(windows, window); - Q_ASSERT(w); + // Have to support invisible (but created()'ed) windows as well. + // Unlike with GL, leaving that case for QQuickWindow to handle is not feasible. + const bool tempExpose = !w; + if (tempExpose) { + handleExposure(window); + w = windowFor(windows, window); + Q_ASSERT(w); + } if (!w->thread->isRunning()) return QImage(); @@ -752,6 +767,11 @@ QImage QSGD3D12RenderLoop::grab(QQuickWindow *window) lockedForSync = false; w->thread->mutex.unlock(); + result.setDevicePixelRatio(window->effectiveDevicePixelRatio()); + + if (tempExpose) + handleObscurity(w); + return result; } @@ -841,6 +861,11 @@ bool QSGD3D12RenderLoop::interleaveIncubation() const return somethingVisible && anim->isRunning(); } +int QSGD3D12RenderLoop::flags() const +{ + return SupportsGrabWithoutExpose; +} + bool QSGD3D12RenderLoop::event(QEvent *e) { if (e->type() == QEvent::Timer) { -- cgit v1.2.3