DirectX Firefox Plugin rendering artifacts - directx

QUICK ANSWER: For those of you who reach this page via Google looking for
a solution to the same problem, try
this quick fix (suggested by Goz) -
Add D3DCREATE_FPU_PRESERVE to the
behavior flags on your CreateDevice()
call. That cleared it up for me!
I'm creating a DirectX 9-based NPAPI plugin. It seems to be working well in Chrome and Opera, but in Firefox I get strange rendering artifacts. Upon initializing DirectX (no rendering needs to be done for the artifact to appear) all or parts of the Firefox UI will turn black. Resizing the window (IE: Initiating a repaint) clears up the artifacts and the plugin seems to work properly at that point, but this is obviously not a desirable "feature". I have found that several others online have mentioned this issue, most claiming that it began with Firefox 3. Only one post mentions any solution being found, but the author doesn't seem to keen on divulging how.
Is anyone familiar with this issue and a possible solution? From the linked post it would seem to be related to the way DX is initialized, but I've yet to find a combination that prevents the issue.
This is the DX Initialization code I'm using (Error Handling removed for clarity):
RECT rc;
GetClientRect(pluginHwnd, &rc);
D3DPRESENT_PARAMETERS d3d9PresentParams;
ZeroMemory(&d3d9PresentParams, sizeof(D3DPRESENT_PARAMETERS));
d3d9PresentParams.hDeviceWindow = pluginHwnd;
d3d9PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3d9PresentParams.Flags = D3DPRESENTFLAG_DEVICECLIP; // Failed attempt to solve FF issue
d3d9PresentParams.EnableAutoDepthStencil = FALSE; // No depth testing
d3d9PresentParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Use Vsync
d3d9PresentParams.MultiSampleType = D3DMULTISAMPLE_NONE; // Don't care about Multisampling
d3d9PresentParams.MultiSampleQuality = 0;
d3d9PresentParams.BackBufferCount = 1;
d3d9PresentParams.BackBufferWidth = rc.right - rc.left;
d3d9PresentParams.BackBufferHeight = rc.bottom - rc.top;
d3d9PresentParams.BackBufferFormat = D3DFMT_UNKNOWN; // Use the same color format as windows
d3d9PresentParams.Windowed = TRUE; // Explicitly windowed
d3d9PresentParams.FullScreen_RefreshRateInHz = 0;
d3d9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pluginHwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3d9PresentParams, &d3d9Device );

The only thing I can think of off the top of my head is setting the "D3DCREATE_NOWINDOWCHANGES" behaviour flag on device creation.
Edit1:
You could try setting backbufferwidth and height to 0 and let it inherit the info from the window.
Might also be worth trying setting the D3DCREATE_FPU_PRESERVE flag and D3DCREATE_MULTITHREADED.

Related

SuperCollider error: ServerOptions.memSize not understood

I ran into a memory error so I'm trying to allocate more memory to the server, as instructed by the IDE. However, it doesn't recognise the class method which is clearly documented. What could have possibly gone wrong??
There is absolutely nothing to my code, it's literally just
ServerOptions.memSize = 65536;
I've also tried what I found on a blog, which is
Server.options.memSize = 65536;
Which also does not work. Please help!! I want to make music!
To refer to the current server, use the global variable 's'. Also, capitalization counts.
s.options.memSize = s.options.memSize * 2;

How to set alignment in Fire Monkey multi device application at runtime C++ Builder?

The main problem is FMX dose not support the SomeController->Align = alClient; but that code will work in the VLC application, so after many googling, I find TAlignLayout.Client for my case and the documentation of it is here and here, I try many way to use it but it wont work!
I want create Frame in the runtime as you can see in the following code:
TSettings *appSettingsFrame;
appSettingsFrame = new TSettings(viewSettings);
appSettingsFrame->Parent = viewSettings;
appSettingsFrame->Align = TAlignLayout.Client;
TSettings is Fire Monkey Frame and I use the above code in FormCreate event to create it, at runtime.
viewSettings is TMultiView and it's place for appSettingsFrame.
If I run application for Android target, the error massage point me to 'TAlinLayout' dose not refer to a value.
And if I run application for 32-bit Windows target, the error massage point me to Improper use of typedef 'TAlignLayout'.
Hope this will help someone, I did used :: instead of . to fix issue.
TSettings *appSettingsFrame;
appSettingsFrame = new TSettings(viewSettings);
appSettingsFrame->Parent = viewSettings;
appSettingsFrame->Align = TAlignLayout::Client;

MSBuild is failing inconsistently when performing a TFS build (usually error C1093 / Not enough Storage)

I have a really odd and hard to diagnose issue with MSBuild / TFS. I have a solution that contains about 12 different build configurations. When running on the build server, it takes maybe 30mins to build the lot and has worked fine for weeks now but now is occasionally failing.
Most of the time, when it fails it'll be an error like this:
19:25:45.037 2>TestPlanDocument.cpp(1): fatal error C1093: API call 'GetAssemblyRefHash' failed '0x8007000e' : ErrorMessage: Not enough storage is available to complete this operation. [C:\Builds\1\ICCSim Card Test Controller\ICCSimCTC Release\src\CardTestController\CardTestController.vcxproj]
The error will sometimes happen on a different file. It won't happen for every build configuration either, it's very inconsistent and occasionally even builds all of them successfully. There's not much different between the build configurations either, mostly it's just a few string changes and of course they all build locally just fine.
The API call in question is usually GetAssemblyRefHash but not always. I don't think this is the issue, as Googling for GetAssemblyRefHash specifically brings up next to nothing. I suspect there's some kind of resource issue at play here but I'm at a loss as to what: There's plenty of HDD space (Hundreds of GB's), plenty of RAM (Machine originally had 4GB minimum allocated but was dynamic as it's a Hyper-v - it never pushed above 2.5GB. I upped this to 8GB minimum just in case and there's been no change).
I've set the build verbosity to diagnostic and it doesn't really show anything else that's helpful, just the same error.
For reference, the build server is fully up to date on all patches. It's running Windows Server 2012 R2, has TFS 2013 and VS 2013 installed, both are on Update 4.
I'm really at a loss at this point and would appreciate any help or pointers.
EDIT: Just to keep people up to date, the compile toolchain was in 32bit mode however even after switching to 64bit, the issue persists.
I think I found the source, but I still don't know the reason.
Browsing through the Microsoft Shared Source, we can find the source for GetAssemblyRefHash():
HRESULT CAsmLink::GetAssemblyRefHash(mdToken FileToken, const void** ppvHash, DWORD* pcbHash)
{
if (TypeFromToken(FileToken) != mdtAssemblyRef) {
VSFAIL( "You can only get AssemblyRef hashes for assemblies!");
return E_INVALIDARG;
}
HRESULT hr;
CAssembly *file = NULL;
if (FAILED(hr = m_pImports->GetFile( FileToken, (CFile**)&file)))
return hr;
return file->GetHash(ppvHash, pcbHash);
}
Only two places here to investigate - the call to m_pImports->GetFile(), where m_pImports is CAssembly *m_pImports;, the other is file->GetHash().
m_pImports->GetFile() is here, and is a dead end:
HRESULT CAssembly::GetFile(DWORD index, CFile** file)
{
if (!file)
return E_POINTER;
if (RidFromToken(index) < m_Files.Count()) {
if ((*file = m_Files.GetAt(RidFromToken(index))))
return S_OK;
}
return ReportError(E_INVALIDARG);
}
file->GetHash(), which is here:
HRESULT CAssembly::GetHash(const void ** ppvHash, DWORD *pcbHash)
{
ASSERT( ppvHash && pcbHash);
if (IsInMemory()) {
// We can't hash an InMemory file
*ppvHash = NULL;
*pcbHash = 0;
return S_FALSE;
}
if (!m_bDoHash || (m_cbHash && m_pbHash != NULL)) {
*ppvHash = m_pbHash;
*pcbHash = m_cbHash;
return S_OK;
}
DWORD cchSize = 0, result;
// AssemblyRefs ALWAYS use CALG_SHA1
ALG_ID alg = CALG_SHA1;
if (StrongNameHashSize( alg, &cchSize) == FALSE)
return ReportError(StrongNameErrorInfo());
if ((m_pbHash = new BYTE[cchSize]) == NULL)
return ReportError(E_OUTOFMEMORY);
m_cbHash = cchSize;
if ((result = GetHashFromAssemblyFileW(m_Path, &alg, (BYTE*)m_pbHash, cchSize, &m_cbHash)) != 0) {
delete [] m_pbHash;
m_pbHash = 0;
m_cbHash = 0;
}
*ppvHash = m_pbHash;
*pcbHash = m_cbHash;
return result == 0 ? S_OK : ReportError(HRESULT_FROM_WIN32(result));
}
We can see that about halfway down, it tries to allocate room to store the byte[] result, and when fails, returns E_OUTOFMEMORY, which is the error code you're seeing:
if ((m_pbHash = new BYTE[cchSize]) == NULL)
return ReportError(E_OUTOFMEMORY);
m_cbHash = cchSize;
There's other paths to consider, but this seems like the most obvious source. So it looks like the problem is that a plain memory allocation is failing.
What could cause this?
Lack of free physical memory pages / swap
Memory fragmentation in the process.
Inability to reserve commit space for this in the swap file
Lack of address space
At this point, my best guess would be memory fragmentation. Have you triple checked that the Microsoft CPP compiler is running in 64-bit mode? Perhaps see if you can debug the compiler (Microsoft symbol servers may be able to help you here), and set a breakpoint for that line and dump the heap when it happens.
Some specifics on diagnosing heap fragmentation - fire up sysinternal's VMMap when the compiler breaks, and look at the free list - you need three chunks at least 64 kB free to perform an allocation; less than 64 kB and it won't get used, and two 64 kB chunks are reserved.
Okay, I have an update to this! I opened a support ticket with Microsoft and have been busy working with them to figure out the issue.
They went down the same paths as outlined above and came to the same conclusion - it's not a resources issue.
To cut a long story short, Microsoft has now acknowledged that this is likely a bug in the VC++ compiler, which is almost certainly caused by a race condition (Though this is unconfirmed). There's no word on if they'll fix it in a future release.
There is a workaround by using the /MP flag at the project level to limit the number of compiler processes opened by MSBuild without disabling multiple instances entirely (Which for me was doubling build times).
To do this, go to your project properties and under Configuration Properties -> C/C++ -> Command Line, you need to specify the /MP flag and then a number to limit the number of processes.
My build server has 8 Virtual CPU's and the normal behaviour is equivelant to /MP8 but this causes the bug to sometimes appear. For me, using /MP4 seems to be enough to limit the bug without causing build times to increase too much. If you're seeing a bug similar to this, you may need to experiment with other numbers such as /MP6 or /MP2.

How to position the On-Screen Keyboard window?

After launching osk.exe with ShellExecuteEx() I would like to position the keyboard window relative to the data-entry fields, so that it doesn't cover them.
How do I set the window position for the osk before calling it?
Also, how can I have the application hide the osk when I am finished?
You can use FindWindow using the window class "OSKMainClass" to get the window handle, and then SetWindowPos on that handle to position it to the coordinates you want. (You may need to use the control's ClientToScreen method to convert to the proper coordinates, but I'll let you figure that part out.)
// Off the top of my head - not at a machine that has a Delphi compiler at
// the moment.
var
OSKWnd: HWnd;
begin
OSKWnd := FindWindow(PChar('OSKMainClass'), nil);
if OSKWnd <> 0 then
begin
SetWindowPos(OSKWnd,
HWND_BOTTOM,
NewPos.Left,
NewPos.Top,
NewPos.Width,
NewPos.Height,
0);
end;
end;
Code taken in part from a CodeProject article related to the same topic. I got the window class using AutoHotKey's Window Spy utility.
Notes:
Remy Lebeau points out in a comment that you should make sure to use CreateProcess() or ShellExecuteEx() so that you get back a process handle that can then be passed to WaitForInputIdle() before calling FindWindow(). Otherwise the call to FindWindow() may happen before OSK creates the window.
mghie points out in a comment that the only way he could get this to work was by running the app as Administrator; otherwise the call to SetWindowPos() resulted in an "Access Denied (5)".
I can,t move the window as mentioned above.
Using Win32 commands, SetWindow or MoveWindow not worked for on screen keyboard.
Its worked only while running exe in admin privilege.
I think its not a good solution.
I found another solution.
Please go through this.
After trying using registry values its worked well i can move on screen keyboard in my application
try
{
RegistryKey myKey = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Osk", true);
myKey.SetValue("WindowLeft", oskLeft, RegistryValueKind.DWord);
myKey.SetValue("WindowTop", oskTop, RegistryValueKind.DWord);
}
catch
{
//Log the error
}

how to set Steps To Reproduce field required in MANTIS

Is this possible to setup Steps To Reproduce field so it's required?
It's always difficult to get enough info from reporters, so maybe forcing them to fill this field will help us - programmers - a little.
I would like to still be able to update mantis without troubles.
You are able to achieve this by changing, (in bug_report.php)
$t_bug_data->steps_to_reproduce = gpc_get_string( 'steps_to_reproduce', '' );
To
$t_bug_data->steps_to_reproduce = gpc_get_string( 'steps_to_reproduce' );
But on the advanced report it doesn't show an * (Asterisk) to indicate that it is mandatory. You have to add the * yourself in the PHP file.

Resources