Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DesktopDuplication call releaseFrame before acquireNextFrame #373

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Revert "Chnges to DesktopDuplication to conform to Guidelines ( https…
Womifa committed Aug 21, 2020
commit 979edbfa0088ca8ecd274fe3d50ee2da96f01337
71 changes: 30 additions & 41 deletions Software/grab/DDuplGrabber.cpp
Original file line number Diff line number Diff line change
@@ -43,8 +43,8 @@ _COM_SMARTPTR_TYPEDEF(ID3D11Texture2D, __uuidof(ID3D11Texture2D));
_COM_SMARTPTR_TYPEDEF(ID3D11ShaderResourceView, __uuidof(ID3D11ShaderResourceView));


typedef HRESULT(WINAPI* CreateDXGIFactory1Func)(REFIID riid, _Out_ void** ppFactory);
typedef HRESULT(WINAPI* D3D11CreateDeviceFunc)(
typedef HRESULT(WINAPI *CreateDXGIFactory1Func)(REFIID riid, _Out_ void **ppFactory);
typedef HRESULT(WINAPI *D3D11CreateDeviceFunc)(
_In_opt_ IDXGIAdapter* pAdapter,
D3D_DRIVER_TYPE DriverType,
HMODULE Software,
@@ -79,16 +79,16 @@ struct DDuplScreenData
: output(_output), duplication(_duplication), device(_device), context(_context)
{}

IDXGIOutputPtr output{ nullptr };
IDXGIOutputDuplicationPtr duplication{ nullptr };
ID3D11DevicePtr device{ nullptr };
ID3D11DeviceContextPtr context{ nullptr };
IDXGIOutputPtr output{nullptr};
IDXGIOutputDuplicationPtr duplication{nullptr};
ID3D11DevicePtr device{nullptr};
ID3D11DeviceContextPtr context{nullptr};

ID3D11Texture2DPtr textureCopy{ nullptr };
ID3D11Texture2DPtr textureCopy{nullptr};
DXGI_MAPPED_RECT surfaceMap;
};

DDuplGrabber::DDuplGrabber(QObject* parent, GrabberContext* context)
DDuplGrabber::DDuplGrabber(QObject * parent, GrabberContext *context)
: GrabberBase(parent, context),
m_state(Uninitialized),
m_accessDeniedLastCheck(0),
@@ -162,7 +162,6 @@ bool DDuplGrabber::init()
}

m_state = Ready;
m_releaseFrame = false;
return true;
}

@@ -221,7 +220,7 @@ bool DDuplGrabber::runThreadCommand(DWORD timeout) {
}
}

bool anyWidgetOnThisMonitor(HMONITOR monitor, const QList<GrabWidget*>& grabWidgets)
bool anyWidgetOnThisMonitor(HMONITOR monitor, const QList<GrabWidget *> &grabWidgets)
{
for (GrabWidget* widget : grabWidgets)
{
@@ -235,12 +234,12 @@ bool anyWidgetOnThisMonitor(HMONITOR monitor, const QList<GrabWidget*>& grabWidg
return false;
}

QList< ScreenInfo >* DDuplGrabber::screensWithWidgets(QList< ScreenInfo >* result, const QList<GrabWidget*>& grabWidgets)
QList< ScreenInfo > * DDuplGrabber::screensWithWidgets(QList< ScreenInfo > * result, const QList<GrabWidget *> &grabWidgets)
{
return __screensWithWidgets(result, grabWidgets);
}

QList< ScreenInfo >* DDuplGrabber::__screensWithWidgets(QList< ScreenInfo >* result, const QList<GrabWidget*>& grabWidgets, bool noRecursion)
QList< ScreenInfo > * DDuplGrabber::__screensWithWidgets(QList< ScreenInfo > * result, const QList<GrabWidget *> &grabWidgets, bool noRecursion)
{
result->clear();

@@ -262,8 +261,7 @@ QList< ScreenInfo >* DDuplGrabber::__screensWithWidgets(QList< ScreenInfo >* res
qWarning() << Q_FUNC_INFO << "Found a monitor with NULL handle. Recreating adapters";
recreateAdapters();
return __screensWithWidgets(result, grabWidgets, true);
}
else {
} else {
qWarning() << Q_FUNC_INFO << "Found a monitor with NULL handle (after recreation)";
continue;
}
@@ -298,7 +296,7 @@ void DDuplGrabber::onSessionChange(int change)
}
}

bool DDuplGrabber::isReallocationNeeded(const QList< ScreenInfo >& grabScreens) const
bool DDuplGrabber::isReallocationNeeded(const QList< ScreenInfo > &grabScreens) const
{
if (m_state != Allocated)
{
@@ -352,22 +350,21 @@ void DDuplGrabber::freeScreens()
_screensWithWidgets.clear();
}

bool DDuplGrabber::reallocate(const QList< ScreenInfo >& grabScreens)
bool DDuplGrabber::reallocate(const QList< ScreenInfo > &grabScreens)
{
// Reallocate on the dedicated thread to be able to SetThreadDesktop to the currently active input desktop
// once the duplication is created, it seems like it can be used from the normal thread.
m_threadCommand = Reallocate;
m_threadReallocateArg = grabScreens;
if (runThreadCommand(INFINITE)) {
return m_threadReallocateResult;
}
else {
} else {
return false;
}
}

// Must be called from DDuplGrabberThreadProc !
bool DDuplGrabber::_reallocate(const QList< ScreenInfo >& grabScreens, bool noRecursion)
bool DDuplGrabber::_reallocate(const QList< ScreenInfo > &grabScreens, bool noRecursion)
{
if (m_state == Uninitialized)
{
@@ -387,8 +384,7 @@ bool DDuplGrabber::_reallocate(const QList< ScreenInfo >& grabScreens, bool noRe
m_accessDeniedLastCheck = GetTickCount();
qWarning(Q_FUNC_INFO " Access to input desktop denied, retry later");
return true;
}
else {
} else {
qCritical(Q_FUNC_INFO " Failed to open input desktop: %x", GetLastError());
return true;
}
@@ -453,8 +449,7 @@ bool DDuplGrabber::_reallocate(const QList< ScreenInfo >& grabScreens, bool noRe
return false;
}
return _reallocate(grabScreens, true);
}
else {
} else {
qCritical(Q_FUNC_INFO " Failed to reallocate: DXGI mode change in progress (after recreation)");
return false;
}
@@ -466,7 +461,7 @@ bool DDuplGrabber::_reallocate(const QList< ScreenInfo >& grabScreens, bool noRe
}

GrabbedScreen grabScreen;
grabScreen.imgData = (unsigned char*)NULL;
grabScreen.imgData = (unsigned char *)NULL;
grabScreen.imgFormat = BufferFormatArgb;
grabScreen.screenInfo = screenInfo;
grabScreen.scale = 1.0;
@@ -518,15 +513,15 @@ BufferFormat mapDXGIFormatToBufferFormat(DXGI_FORMAT format)
{
switch (format)
{
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
return BufferFormatArgb;
case DXGI_FORMAT_R8G8B8A8_UINT:
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
return BufferFormatAbgr;
default:
return BufferFormatUnknown;
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
return BufferFormatArgb;
case DXGI_FORMAT_R8G8B8A8_UINT:
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
return BufferFormatAbgr;
default:
return BufferFormatUnknown;
}
}

@@ -609,11 +604,6 @@ GrabResult DDuplGrabber::grabScreens()
DDuplScreenData* screenData = (DDuplScreenData*)screen.associatedData;
DXGI_OUTDUPL_FRAME_INFO frameInfo;
IDXGIResourcePtr resource;
if (m_releaseFrame)
{
screenData->duplication->ReleaseFrame();
m_releaseFrame = false;
}
HRESULT hr = screenData->duplication->AcquireNextFrame(ACQUIRE_TIMEOUT_INTERVAL, &frameInfo, &resource);
if (hr == DXGI_ERROR_WAIT_TIMEOUT)
{
@@ -637,7 +627,6 @@ GrabResult DDuplGrabber::grabScreens()
return GrabResultError;
}
anyUpdate = true;
m_releaseFrame = true;

ID3D11Texture2DPtr texture;
hr = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture);
@@ -679,8 +668,7 @@ GrabResult DDuplGrabber::grabScreens()
// reset texture and data before getting new one
if (screenData->textureCopy) {
screenData->textureCopy = nullptr;
}
else if (screen.imgData) {
} else if (screen.imgData) {
free((void*)screen.imgData);
}

@@ -753,6 +741,7 @@ GrabResult DDuplGrabber::grabScreens()
screen.scale = 1.0 / (1 << DownscaleMipLevel);
screen.bytesPerRow = screenData->surfaceMap.Pitch;

screenData->duplication->ReleaseFrame();
}

if (!anyUpdate)
13 changes: 6 additions & 7 deletions Software/grab/include/DDuplGrabber.hpp
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ class DDuplGrabber : public GrabberBase
{
Q_OBJECT
public:
DDuplGrabber(QObject* parent, GrabberContext* context);
DDuplGrabber(QObject * parent, GrabberContext *context);
virtual ~DDuplGrabber();

DECLARE_GRABBER_NAME("DDuplGrabber")
@@ -73,13 +73,13 @@ public slots:

protected slots:
virtual GrabResult grabScreens();
virtual bool reallocate(const QList< ScreenInfo >& grabScreens);
bool _reallocate(const QList< ScreenInfo >& grabScreens, bool noRecursion = false);
virtual bool reallocate(const QList< ScreenInfo > &grabScreens);
bool _reallocate(const QList< ScreenInfo > &grabScreens, bool noRecursion = false);

virtual QList< ScreenInfo >* screensWithWidgets(QList< ScreenInfo >* result, const QList<GrabWidget*>& grabWidgets);
QList< ScreenInfo >* __screensWithWidgets(QList< ScreenInfo >* result, const QList<GrabWidget*>& grabWidgets, bool noRecursion = false);
virtual QList< ScreenInfo > * screensWithWidgets(QList< ScreenInfo > * result, const QList<GrabWidget *> &grabWidgets);
QList< ScreenInfo > * __screensWithWidgets(QList< ScreenInfo > * result, const QList<GrabWidget *> &grabWidgets, bool noRecursion = false);

virtual bool isReallocationNeeded(const QList< ScreenInfo >& grabScreens) const;
virtual bool isReallocationNeeded(const QList< ScreenInfo > &grabScreens) const;

protected:
bool init();
@@ -105,7 +105,6 @@ protected slots:
QList<ScreenInfo> m_threadReallocateArg;
bool m_threadReallocateResult;
bool m_isSessionLocked;
bool m_releaseFrame;
};