D3D11 Freezes Windows Present - directx-11

When using D3D11 encountered a problem with an empty call context-> Present (0,0); OK. And if it goes before the draw, drawindexed ..., reezes windows completely.
Errors and warnings are missing in the assembly and execution.
GContext->VSSetShader(mVS->GetVertexShader(), NULL, 0);
GContext->PSSetShader(mPS->GetPixelShader(), NULL, 0);
GContext->IASetIndexBuffer(NULL, DXGI_FORMAT_UNKNOWN, 0);
GContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); GContext->Draw(3, 0);
mSwapChain->Present(0, 0);

Enable the debug device and look for messages in your debug window, and ensure you are checking every HRESULT for SUCCEEDED or FAILED.
Are you doing this in a 'tight loop'? Where are you processing your windows messages?
You should take a look at this Windows desktop VS template for a good minimal rendering loop.
// Main message loop
MSG msg = { 0 };
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
g_game->Tick();
}
}
Here Tick is the Update loop and Render loop. See StepTimer for a robust way to do the update timing.

Your problem is some ignorance of init D3D code, GContext->Draw(3, 0);, you only want to draw a triangle.
So your can try mSwapChain->Present(1, 0); which will follow the Vsync like 60Hz and present(0,0) work as fast as it can, often 1000-5000Hz depend on computer. What is freeze you mean, you can not interact with window? That you can follow #Chuck Walbourn advice in main loop, like add the code after mSwapChain->Present(0 or 1, 0);.
As you know, you problem amostly an apearance of a bug, so don't worry.

Related

Can't figure out how to use SetWindowsHookEx within Dart using ffi

I want to use SetWindowsHookEx to call a function every time a user presses a key
the closest thing to what I'm trying to do is a keylogger
I've been inspiring from these projects GiacomoLaw/Keylogger and timsneath/win32/blob/master/example/tetris
I have little to no experience with winapi or c++ in general and I'm in the process of learning dart
sorry in advance for my messy code, the important filles are main.dart, lib/native_functions/SetWindowsHookEx.dart, lib/native_functions/GetModuleHandle.dart, lib/native_functions/CallNextHookEx.dart
here's the zip file
i just added this
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, lpfn, hmod, 0);
// more code above ^
// i added this
final MSG msg = MSG.allocate();
while (GetMessage(msg.addressOf, 0, 0, 0) != 0) {
TranslateMessage(msg.addressOf);
DispatchMessage(msg.addressOf);
}
don't forget to write bindings for GetMessage, TranslateMessage, DispatchMessage

Different behaviour between dialogbox and createdialog is not understood

I am creating a dialog in a DLL and while DialogBox creates it - but seems hard to be stopped programmatically, CreateDialog only shows the borders (and title) of the dialog and "does not respond" after creating
I am adding some functionality to an existing program - not under my control. Control of this added functionality - for some external device - requires the user to do some settings particular to settings for this device, not covered by controls in the main program. For this I add a DLL with a small dialog, one with three control elements. The dialog is started with the DialogBox function in a separate thread and funtions well, apart from termination: the use of the main program may want to switch from one device to another without having to explicity quit the dialog by touching some button or control on the dialog.
Therefore I figured it would be better to use CreateDialog since that gives a handle.
However, when doing that - of course adding ShowWindow (handle, WS_SHOW) to make the dialog visible, only the raw widget appears, no controles visible and suffering from "does not respond"
` // DialogBox (hInstance,`
` widgetHandle = CreateDialog (hInstance,`
` MAKEINTRESOURCE(IDD_DIALOG1), NULL, ialog1Proc);`
` err = GetLastError ();`
` fprintf (stderr, "Last Error = %d\n", err);`
` if (err == 0) {`
` ShowWindow (widgetHandle, SW_SHOW);`
` while (running)`
` Sleep (100);`
` }`
Since - when using CreateBox, the contours of the widget - and the title of the dialog - are visible, I assume that the resource is seen correctly,
but it is as such unusable.
Therefore two questions
a. Is my assumption that CreateBox can be used in a thread in a DLL wrong
b. I'm perfectly willing to use DialogBox here, but then I need some advice on how to terminate the dialog (box) programmatically, i.e. from elsewhere in the DLL.
Any help would be appreciated here
DialogBox creates its own message loop and does not return until the dialog is closed. It is essentially CreateDialog + a message loop.
CreateDialog returns after creating the window and it expects you to process messages for it.
HWND hDlg = CreateDialog(...);
ShowWindow(hDlg, SW_SHOW);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsWindow(hDlg)) break;
if (IsDialogMessage(hDlg, &msg)) continue;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
If your only requirement is to be able to close the dialog from a different thread you can pull it off with DialogBox as well:
HWND g_hDlg = 0; // Assumes you only have one dialog instance open at the time
.. MyDlgProc(HWND hDlg, UINT Msg, ..)
{
switch(Msg)
{
case WM_INITDIALOG:
g_hDlg = hDlg;
return TRUE;
case WM_DESTROY:
g_hDlg = 0;
break;
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
}
return FALSE;
}
EXTERN_C void WINAPI CloseDialog()
{
if (g_hDlg) SendMessage(g_hDlg, WM_CLOSE, 0, 0);
}

Capture output from console program with overlapping and events

I know lots of similar questions on this topic have been asked before but so far I have been unable to find a solution that actually works. I want to start a console program from my program and capture its output. My implementation should be in a way that is compatible with WaitForMultipleObjects(), i.e. I want to get notified whenever there is new data to read in the pipe.
My implementation is based on this example from MSDN. However, I had to modify it a little because I need overlapped I/O in order to be able to wait for ReadFile() to finish. So I'm using named pipes created using Dave Hart's MyCreatePipeEx() function from here.
This is my actual code. I have removed error checks for readability reasons.
HANDLE hReadEvent;
HANDLE hStdIn_Rd, hStdIn_Wr;
HANDLE hStdOut_Rd, hStdOut_Wr;
SECURITY_ATTRIBUTES saAttr;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
OVERLAPPED ovl;
HANDLE hEvt[2];
DWORD mask, gotbytes;
BYTE buf[4097];
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
MyCreatePipeEx(&hStdOut_Rd, &hStdOut_Wr, &saAttr, 0, FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED);
MyCreatePipeEx(&hStdIn_Rd, &hStdIn_Wr, &saAttr, 0, FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED);
SetHandleInformation(hStdOut_Rd, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(hStdIn_Wr, HANDLE_FLAG_INHERIT, 0);
memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
memset(&siStartInfo, 0, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = hStdOut_Wr;
siStartInfo.hStdOutput = hStdOut_Wr;
siStartInfo.hStdInput = hStdIn_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
CreateProcess(NULL, "test.exe", NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);
hReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
for(;;) {
int i = 0;
hEvt[i++] = piProcInfo.hProcess;
memset(&ovl, 0, sizeof(OVERLAPPED));
ovl.hEvent = hReadEvent;
if(!ReadFile(hStdOut_Rd, buf, 4096, &gotbytes, &ovl)) {
if(GetLastError() == ERROR_IO_PENDING) hEvt[i++] = hReadEvent;
} else {
buf[gotbytes] = 0;
printf("%s", buf);
}
mask = WaitForMultipleObjects(i, hEvt, FALSE, INFINITE);
if(mask == WAIT_OBJECT_0 + 1) {
if(GetOverlappedResult(hStdOut_Rd, &ovl, &gotbytes, FALSE)) {
buf[gotbytes] = 0;
printf("%s", buf);
}
} else if(mask == WAIT_OBJECT_0) {
break;
}
}
The problem with this code is the following: As you can see, I'm reading in chunks of 4kb using ReadFile() because I obviously don't know how much data the external program test.exe will output. Doing it this way was suggested here:
To read a variable amount of data from the client process just issue
read requests of whatever size you find convenient and be prepared to
handle read events that are shorter than you requested. Don't
interpret a short but non-zero length as EOF. Keep issuing read
requests until you get a zero length read or an error.
However, this doesn't work. The event object passed to ReadFile() as part of the OVERLAPPED structure will only trigger once there are 4kb in the buffer. If the external program just prints "Hello", the event won't trigger at all. There need to be 4kb in the buffer for hReadEvent to actually trigger.
So I thought I should read byte by byte instead and modified my program to use ReadFile() like this:
if(!ReadFile(hStdOut_Rd, buf, 1, &gotbytes, &ovl)) {
However, this doesn't work either. If I do it like this, the read event is not triggered at all which is really confusing me. When using 4096 bytes, the event does indeed trigger as soon as there are 4096 bytes in the pipe, but when using 1 byte it doesn't work at all.
So how am I supposed to solve this? I'm pretty much out of ideas here. Is there no way to have the ReadFile() event trigger whenever there is some new data in the pipe? Can't be that difficult, can it?
Just for the record, while there are some problems with my code (see discussion in comments below the OP), the general problem is that it's not really possible to capture the output of arbitrary external programs because they will typically use block buffering when their output is redirected to a pipe, which means that output will only arrive at the capturing program once that buffer is flushed so real time capturing is not really possible.
Some workarounds have been suggested though:
1) (Windows) Here is a workaround that uses GetConsoleScreenBuffer() to capture the output from arbitrary console programs but it currently only supports one console page of output.
2) (Linux) On Linux, it's apparently possible to use pseudo-terminals to force the external program to use unbuffered output. Here is an example.

On Windows 10, the Cancel object never returns RPC_E_CALL_COMPLETE

In our application that we've had for 15+ years, we have a type of progress bar.
This progress bar is for long lasting C++ operations and there is also the case for when we make a COM call and it takes a long time for the COM call to return.
In general, we want the user to know that something is taking a long time to complete and give him a chance to cancel if he thinks it is taking too much time.
For COM operations, many years ago we implemented a custom IMessageFilter for COM calls that take too long. We would like the user to be able to cancel but also for the prompt to cancel go away on its own when the operation completes. It has been working fine for years. Most of our customers are conservative and are still running Windows 7. Recently a customer using Windows 10 has found an issue where a COM call on Windows 10 never seems to never finish.
Our progress bar comes up and the progress control cycles and recycles, but the operation never seems to finish. After investigating it, it seems that the ICancelMethodCalls::TestCancel() method always returns RPC_S_CALLPENDING, it never returns RPC_E_CALL_COMPLETE. On Windows 7, previous versions of Windows, and Windows 8.1, it works fine, but not on Windows 10.
I created a minimal test solution in Visual Studio 2013 that demonstrates the problem. One project is an ATL server, and the other project is an MFC client application. A link to a zip file of a sample solution is here: https://www.dropbox.com/s/1dkchplsi7d6tda/MyTimeOutServer.zip?dl=0
Basically the ATL server has a property that sets a delay, and a method that just waits the delay length. The purpose is to simulate a COM operation that is taking too long.
interface IMyTimoutServer : IDispatch{
[propget, id(1), helpstring("Timeout value in milliseconds")] HRESULT TimeOut([out, retval] LONG* pVal);
[propput, id(1), helpstring("Timeout value in milliseconds")] HRESULT TimeOut([in] LONG newVal);
[id(2)] HRESULT DoTimeOut([out, retval] VARIANT_BOOL* Result);
};
The next important thing is the IMessageFilter in the client application. At some point, someone decided it was good to derive from COleMessageFilter, the default MFC implementation. (Let's not argue whether that is a good idea.)
The important methods of the the class are the MessagePending() and MyNotResponding().
DWORD CMyMessageFilter::XMyMessageFilter::MessagePending(HTASK htaskCallee, DWORD dwTickCount, DWORD dwPendingType)
{
METHOD_PROLOGUE_EX(CMyMessageFilter, MyMessageFilter);
ASSERT_VALID(pThis);
MSG msg;
if (dwTickCount > pThis->m_nTimeout && !pThis->m_bUnblocking && pThis->IsSignificantMessage(&msg))
{
if (pThis->m_bEnableNotResponding)
{
pThis->m_bUnblocking = TRUE; // avoid reentrant calls
// eat all mouse and keyboard messages in our queue
while (PeekMessage(&msg, NULL, WM_MOUSEFIRST, AFX_WM_MOUSELAST, PM_REMOVE | PM_NOYIELD));
while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE | PM_NOYIELD));
// show not responding dialog
pThis->m_dwTickCount = dwTickCount;
bool bCancel = pThis->MyNotResponding(htaskCallee) == RPC_E_CALL_CANCELED;
pThis->m_bUnblocking = FALSE;
return bCancel ? PENDINGMSG_CANCELCALL : PENDINGMSG_WAITNOPROCESS; // if canceled, the COM call will return RPC_E_CALL_CANCELED
}
}
// don't process re-entrant messages
if (pThis->m_bUnblocking)
return PENDINGMSG_WAITDEFPROCESS;
// allow application to process pending message
if (::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE | PM_NOYIELD))
pThis->OnMessagePending(&msg); // IK: could also return a value from extended OnMessagePending() to cancel the call
// by default we return pending MSG wait
return PENDINGMSG_WAITNOPROCESS;
}
After a timeout, we display a status type window that updates in the NotMyResponding() method.
int CMyMessageFilter::MyNotResponding(HTASK hTaskBusy)
{
TRY
{
CComPtr<ICancelMethodCalls> pCancel;
HRESULT hRes = ::CoGetCancelObject(0, IID_ICancelMethodCalls, (void**)&pCancel);
ATLASSERT(SUCCEEDED(hRes)); // COM should automatically create Cancel objects for pending calls [both on client and server]
if (pCancel == NULL)
{
return COleBusyDialog::retry;
}
m_pFrame->EnableWindow(FALSE);
CMyCancelDlg dlg;
dlg.Create(CMyCancelDlg::IDD);
dlg.ShowWindow(SW_SHOWNORMAL);
HWND hWndDlg = dlg.GetSafeHwnd();
do
{
MSG msg;
for (int i = 0; i < 100 && PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD); ++i)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (dlg.StepAndCheckCancel())
{
dlg.DestroyWindow();
m_pFrame->EnableWindow(TRUE);
return RPC_E_CALL_CANCELED; // signals to MessagePending() that the COM call should be cancelled
}
Sleep(250); // this call has been pending for many seconds now... sleep for some time to avoid CPU utilization by this loop and yield if needed
hRes = pCancel->TestCancel();
} while (hRes == RPC_S_CALLPENDING);
ATLASSERT(hRes == RPC_E_CALL_COMPLETE);
dlg.DestroyWindow();
m_pFrame->EnableWindow(TRUE);
}
END_TRY
return RPC_E_CALL_COMPLETE;
}
Basically, in MyNotResponding(), we create a Cancel object, create a window with a cancel button, pump messsages, and look for either a press on the cancel button or if TestCancel() returns something other than RPC_S_CALLPENDING.
Well, on Windows 10, it stays in the loop and RPC_S_CALLPENDING is always returned from TestCancel().
Has anyone seen anything like this on Windows 10? Are we doing something wrong that we are really only getting lucky on Windows 7?
The default implementation of the MFC puts up an OLEUIBusy dialog which pumps messages. It just never tests the cancel object.

SDL2: How to draw rectangles as quickly as possible?

Background
I am working on a rendering client that draws graphical information it receives from a server. The server sends packets containing non-overlapping rectangles with different solid colors at a frame rate variably defined on the server. I currently have it configured so that the size of the screen being transmitted by the server is different than the size of the window onto which the client is drawing, so scaling is done. I need the client to draw these rectangles as quickly as possible to not fall behind the server's stream.
Currently, I am using SDL 2.0. I am using the streaming texture technique described in the SDL 2 Migration Guide to draw the rectangles onto an SDL_Surface. When the time to display a frame arrives, I calll SDL_UpdateTexture() to overwrite the pixel data for an SDL_Texture, and then I use SDL_RenderCopyEx() to copy the texture to the renderer. I need this function instead of SDL_RenderCopy() so I can specify SDL_FLIP_VERTICAL to account for the fact that the coordinates passed are bitmap-style.
Question
My current approach does not render the rectangles quickly enough. To get the client to be able to keep up with the server, I currently have to reduce the server's upload rate from 30+ FPS to 15- FPS. Even then, I have to make the socket's buffer dangerously large, and I end up getting to watch the client's rendering slowly fall behind and eventually result in packet loss.
What is the fastest way to get SDL to render these rectangles? If I am currently using the fastest method, what other APIs would others recommend to make a client that can keep up?
I have included a stripped-down version of my source code so others can look for improvements/mistakes.
Technical Details
I am using C++11, MinGW32, and SDL2 with Eclipse Kepler CDT and GCC 4.8.2 on Window 7 64-bit.
Stripped Code
int main(int argc, char** args) {
// omitted initialization code
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow(
"RTSC",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
windowWidth,
windowHeight,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Surface* surface = SDL_CreateRGBSurface(
0,
sourceWidth,
sourceHeight,
24,
0xFF << 16,
0xFF << 8,
0xFF,
0
);
SDL_FillRect(surface, nullptr, 0);
SDL_Texture* texture = SDL_CreateTexture(
renderer,
surface->format->format,
SDL_TEXTUREACCESS_STREAMING,
sourceWidth,
sourceHeight
);
bool running {true};
while (running) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
running = false;
break;
case SDL_WINDOWEVENT:
switch (event.windowevent.event) {
case SDL_WINDOWEVENT_CLOSE:
running = false;
break;
default:
break;
}
break;
default:
break;
}
}
// omitted packet reception and interpretation code
for (uint32_t i {0}; i < receivedRegions; ++i) {
Region& region = regions[i];
SDL_Rect rect {
(int) region.x,
(int) region.y,
(int) region.width,
(int) region.height
};
uint32_t color =
(region.red << 16) +
(region.green << 8) +
region.blue;
SDL_FillRect(surface, &rect, color);
}
// omitted logic for determining whether to present the frame
SDL_RenderClear(renderer);
SDL_UpdateTexture(texture, nullptr, surface->pixels, surface->pitch);
SDL_RenderCopyEx(
renderer,
texture,
nullptr,
nullptr,
0,
nullptr,
SDL_FLIP_VERTICAL
);
SDL_RenderPresent(renderer);
SDL_FillRect(surface, nullptr, 0);
}
// omitted clean-up and return code
}
This is embarassing. Because of earlier instrumentation I had done on my server, I assumed all the problem was with the SDL rendering client. However, it turns out the client slows only when the server does. It has nothing to do with SDL at all. Sorry.

Resources