Window not showing properly


#1

Hi, I need to fix something in my host, because a JUCE window is displaying like this:

When I move the mouse cursor over some controls, they begin to display. Sometimes it eventually displays everything.
Can this be connected to a resource problem? Window regions? Direct3D? (which I use to display the host)

Here are some values from UI spy for that window:

IsKeyboardFocusable: "False"
IsEnabled: "True"
HasKeyboardFocus: "False"
IsOffscreen: “False”

Can anybody help?

Best regards
Markus


#2

Never seen anything like that before… Maybe something is preventing it loading any fonts?


#3

It seems like this. It displays only certain characters, e.g. all Fs and Gs. When I load Sytrus into the host before hosting the problematic plugins, then everything is fine. It looks to me like if I omit a certain call to a Windows function that Sytrus and other host usually call. But I don’t know what it could be.


#4

No idea. I can’t think of anything at all that could have that effect. What host is it?


#5

It’s my not yet finished host. Meanwhile I found out that the Image-Line’s JUCE windows will display in it, as long as it doesn’t create a Direct3D 9 device. :shock:


#6

Bizarre. Must be something to do with the win32 dlls that your host is loading, and which are shared by the plugin, but I can’t think of any reason why you’d get something like this…


#7

Yey, found another one
It’s also made with JUCE, I’ll really need to compile a JUCE plugin myself now, too see why a Direct3D device makes a special kind of art out of it. :wink:


#8

The font functions are all just basic win32 calls, nothing fancy! I really have no idea how you’d manage to get it into that kind of state!


#9

I got a simmilar result with the juce demo, in initialise in ApplicationStartup.cpp I added

And I used the following to create a Directd3D device:

[code]#include <windows.h>
#include <d3d9.h>

void created3d9device(void *windowhandle)
{
HWND hwnd = (HWND) windowhandle
HMODULE d3ddll;
IDirect3D9 *d3d;
IDirect3DDevice9 *d3ddevice;
D3DPRESENT_PARAMETERS presentparams;
IDirect3D9 *(WINAPI *_Direct3DCreate9)(UINT SDKVersion);

d3ddll = LoadLibrary("d3d9.dll");
if(!d3ddll)
{
    MessageBox(0, "could not load d3d9.dll", "Error", MB_ICONSTOP);
    return;
}

_Direct3DCreate9 = (IDirect3D9 *(WINAPI *)(UINT)) GetProcAddress(d3ddll, "Direct3DCreate9");
if(!_Direct3DCreate9)
{
    MessageBox(0, "could not get Direct3DCreate9 procedure address", "Error", MB_ICONSTOP);
    return;
}

d3d = _Direct3DCreate9(D3D_SDK_VERSION);
if(!d3d)
{
    MessageBox(0, "Direct3DCreate9 returned null", "Error", MB_ICONSTOP);
    return;
}

ZeroMemory(&presentparams, sizeof(presentparams));

presentparams.SwapEffect           = D3DSWAPEFFECT_DISCARD;
presentparams.hDeviceWindow        = hwnd;
presentparams.BackBufferCount      = 1;
presentparams.Windowed             = 1;
presentparams.BackBufferWidth      = GetSystemMetrics(SM_CXSCREEN);
presentparams.BackBufferHeight     = GetSystemMetrics(SM_CYSCREEN);
presentparams.Flags                = 0;
presentparams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
presentparams.BackBufferFormat     = D3DFMT_X8R8G8B8; // needs 32 bit bitdepth

if(d3d->CreateDevice(
    D3DADAPTER_DEFAULT,
    D3DDEVTYPE_HAL,
    hwnd,
    D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    &presentparams,
    &d3ddevice) != D3D_OK)
{
    MessageBox(0, "could not create Direct3d device", "Error", MB_ICONSTOP);
    return;
}

d3ddevice->Release();
d3d->Release();
FreeLibrary(d3ddll);

}[/code]


#10

That’s pretty screwed up! Sorry, but I’m really at a loss for what to suggest… Have you tried the font page in the juce demo, to see whether all the fonts get messed up in the same way?


#11

The font demo works. Everthing seems to depend only on the creation of the Direct3D 9 device. If it is created and released, many graphics objects won’t show up at first. E.g. the window buttons (minimize, maximize, close) were invisible at first, then showed up each when I put the mouse cursor over them.

I traced some win32 GDI functions in the native code section of JUCE, but none of these calls failed. It’s like the Direct3D device makes JUCE draw font characters and buttons with full transparency, but not always, so JUCE setting a full transparency (because of whatever) seems not so likely. I thought, JUCE might fail to do some drawing into memory done via win32 calls, but I could not find such a thing, it’s pretty much code to walk through. Can you provide me some info? Will a shape (ellipse, glyph etc) go through win32 calls? All I really found was a dib section where the whole window including nonclient area gets DrawDibDrawn into, and shadows via UpdateLayeredWindow. And all seems to work fine. But inbetween…e.g. the window buttons, will they be software rendered directly into the final dibsection?


#12

None of the rendering uses any win32 calls at all - the only thing that could possibly be failing are the calls to GetGlyphOutline, which get the actual shapes of the glyphs. As soon as it’s got the shapes, everything else is pure software rendering, so won’t be affected.

Perhaps when you launch d3d it throws away all the graphics handles that the app had previously been using…?


#13

The thing is… in my host app, Direct3D is active all the time. And when I load e.g. the VST plugin Poizone, everything shows up fine. Only its preset manager window has the problem.

Hmm…Direct3D can actually only throw away handles in the OS, if all is software rendered. The things that are invisible and then show up are font characters and other things like buttons.

And important to mention :wink: the plugin Sytrus must probably be calling some GDI functions that prevent the whole thing.

I’ll have a look at GetGlyphOutline, maybe this one fails.


#14

Okies, got it. The d3d device sets the precision to single in the fpu control word, Sytrus sets it to double. Nothing special, but roundToInt will not forgive it and convert most numbers to 0.
In juce_EdgeTable.cpp line 63 it’s doing its evil job.

Grr… my fpu reset code left the precision control unchanged though I wanted to prevent exactly these things… :cry:

…at least it works now… I’ll be able to open Image-Line preset selectors :mrgreen:


#15

Aha! I wonder if there’s an assertion I could put somewhere to catch this if it happens to anyone else? Is there an easy way to check the current precision?


#16

With no guarrantee for correctness: Yes, with fnstcw (or fstcw for additional error checking) it can be read into a short int - and with fldcw put back into the FPU. Bits 8 and 9 are for the precision control, 11b would be double extended, as far as I can read the Intel CPU docs, and I’ll set 11b now for pretty much everything, Intel docs say it’s the default…

Btw, I wonder how much faster this roundToInt is. Maybe the path table floats can be converted to ints with SSE/AltiVec faster, seems the path values are all ready when it begins to rasterize it. Or maybe the compilers code for a type cast would be just as fast.


#17

Maybe a more empirical test would be to assert that roundToInt is producing the correct values. Presumably some values were working correctly, but there must be some particular values that were causing it to go wrong.

It could indeed be possible to do a faster roundToInt with SSE, though when I wrote it the general wisdom was that this was the fastest way to do it. But can SSE instructions do rounding to the nearest int rather than just rounding down? That’s an important feature of the function.


#18

I had done a quick test, roundToInt seemed to work just fine, but the precision control must be set to double or double extended. With float precision it returned 0 for everything below hundreds of thousands.

Yep, SSE can round to nearest with one instruction.


#19

So I guess a test like

would have caught the problem.


#20

Yes, quickly checked it, it would catch the problem, and it would also catch rounding up (10b in bit 10 to 11 in the FPU control word), which is a good thing I guess.