[ann] New Api In The Sprintwindow Library

Hi folks !

I've been working for 3 days now to make this new API come to life:

bool SPrintWindowSetDIB(HWND hWnd, SPW_DIB *pDIB);

void SPrintWindowRestoreDIB(HWND hWnd);

With this API, you can SET a dib in which the window will actually paint.

It's NOT a copy, the window will really paint into that DIB.

However, there are some drawbacks: you MUST call SPrintWindowRestoreDIB() before your program exit !! Because if your program dies and the original DIB pointer hasn't been restored, you'll end up with a cute Blue Screen Of Death :)

You might not see what's the benefit of that API :)

Lemme tell you what I've just tried.

I made a Direct3D application in which I had a textured cube I could move around.

I locked the texture, to retrieve a pointer to the texture DIB, and I just set this DIB pointer to my window :)

And boom, the window was actually painting DIRECTLY (no copy) in the texture :)

In other words, I had a REAL TIME window wrapped in a Direct3D Cube :)

But here's another drawback, sometimes setting the DIB directly is slower than copying the entire DIB (when using it with textures). Why is that ? Lemme explain: in Direct3D, all the texture are transfered into VIDEO memory. But the transfer is done using AGP for WRITING only, READING is still done through PCI. And because PCI is MUCH slower than our DDR rams, if the windows kernel tries to read from the DIB, it will slow down the whole process.

But you will tell me, hey, what's the benefits of that method over the other one ?

Well, I would say that the speed you can use for refreshing the windows is limited by the AGP bus. So for one window it's good, but I had some real slow downs with 3 windows at the same time (size like 1000*800 pix), and what's the need to refresh a window if it's not drawing anything ? With this tecthnique, I shouldn't experience those slowdowns because the texture is updated directly by the system, so no problem :)

I am about to release the v0.1 version of the SPrintWindow library in one or two days :)

I didn't made a video because I just finished to test this API :)

siwu

#207368

I guess this was the last cornerstone missing for a truly 3D accelerated

desktop. If you could hack yourself into the window manager inside

User32.dll itself, well you could be tying all application windows to a

DirectX surface...

#207525

Originally posted by herd@Aug 26 2004, 01:18 PM

I guess this was the last cornerstone missing for a truly 3D accelerated

desktop. If you could hack yourself into the window manager inside

User32.dll itself, well you could be tying all application windows to a

DirectX surface...

<{POST_SNAPBACK}>

The Window Manager is Win32k.sys :)

User32.dll is nothing but a syscall wrapper :)

For example, the PrintWindow API:

.text:77D5B898 PrintWindow     proc near
.text:77D5B898                 mov     eax, 11DCh
.text:77D5B89D                 mov     edx, 7FFE0300h
.text:77D5B8A2                 call    edx
.text:77D5B8A4                 retn    0Ch

And at edx, we have nothing but a mov and a sysenter (for my p4, could be a int on other CPU) instruction (to switch to kernel mode).

eax is actually the API id, used to the Win32k.sys to know which API you are calling :)

So redirecting every window to a DirectX surface is quite simple actually. Just do a hook dll that will hook NC_CREATE and then set the window to layered, set the DIB, and you're done :)

siwu

#207560

not bad not bad, but my pc will die doing this for all windows ^^

#207738

Originally posted by Vjay@Aug 27 2004, 12:02 AM

not bad not bad, but my pc will die doing this for all windows ^^

<{POST_SNAPBACK}>

Maybe not. With all those supercharged GFX cards becoming commonplace,

it'd be a matter of time. 64 or 128 MB AGP memory unused until you play

a game - what a waste - Let's unleash that power in a production environment!

On the other hand, I believe global hooks are evil. There should be a 3D desktop

take over as in Mac OS X. Believe it or not, the entire desktop is an OpenGL

scene there, and the frame windows render themselves on OpenGL surfaces. This

freaking genie effect is so easy to do for Macs, and so hard to do for Windozers.

Even the dock animations are done with hw accelerated motion blur!

I somehow have it in my water that his excellency Siwu is opening a door here,

for evening out the advantages that OS X has over Win32.

Too bad I am a user mode 2D coder and can't be of any help here. But as a

knowing bystander, I cheer Siwu to go on. This clearly has more use cases than

Expiré, I see it as a milestone.

#208112

Originally posted by herd@Aug 28 2004, 01:00 AM

Maybe not. With all those supercharged GFX cards becoming commonplace,

it'd be a matter of time. 64 or 128 MB AGP memory unused until you play

a game - what a waste - Let's unleash that power in a production environment!

On the other hand, I believe global hooks are evil. There should be a 3D desktop

take over as in Mac OS X. Believe it or not, the entire desktop is an OpenGL

scene there, and the frame windows render themselves on OpenGL surfaces. This

freaking genie effect is so easy to do for Macs, and so hard to do for Windozers.

Even the dock animations are done with hw accelerated motion blur!

I somehow have it in my water that his excellency Siwu is opening a door here,

for evening out the advantages that OS X has over Win32.

Too bad I am a user mode 2D coder and can't be of any help here. But as a

knowing bystander, I cheer Siwu to go on. This clearly has more use cases than

Expiré, I see it as a milestone.

<{POST_SNAPBACK}>

Well, the problem in entirely 3D desktop is actually the AGP bandwidth. You simply can't afford to transfer n bitmaps in real time. But with OSX, the bitmap is still your screen res (because of window overlapping, you don't have to send the "overlapped" part of the bitmap).

But, as I see it, the only problem with the SPrintWindowSetDIB() API is that the bitmap itself will be in video memory (for both writing and reading). Reading from video memory is 40 times SLOWER that writing (because reading is STILL done through PCI). And because the windows kernel reads a lot it's redirected windows bitmaps, it results in a slow framerate (can drop to 5 frames/sec when refreshing a firefox page for example).

So I thought the good way would be to have the video memory bitmap cached in system memory. Then, just walk trough the real window bitmap, catch the differencies, and then update (so write only, which is kinda fast) the video memory bitmap.

But the problem is we have to walk trough bitmap that have a maximum dimension of the screen (mostly), and is quite CPU intensive.

That's why I thought about MMX and SSE instructions, they can help a lot (for example, a memcpy() with MMX+SSE can be 3 times faster than the simple memcpy()).

For example, SPrintWindow uses the memcpy_amd() API, provided by AMD that uses MMX and SSE.

But still it's a way to investigate. SPrintWindow unlocked the Windows WM capabilities (which is capable of redirecting windows since Windows 2000, WS_EX_LAYERED).

Now all the optimizing work needs to be done :)

siwu

#208286

Okay I made a function that uses SSE to optimize bitmap changes.

Here it is:

	__asm
{
 mov eax, realPtr
 mov ebx, cachePtr
 mov ecx, videoPtr
 mov esi, realSize
 xor edi, edi

 $loop1:
 prefetchnta  16[EAX]  // prefecth next 4 pixels
 prefetchnta  16[EBX]

 movapd  xmm0, [eax]  // read 16 bytes in the window DIB
 movapd  xmm1, [ebx]  // read 16 bytes in the cache DIB

 cmpsd  xmm1, xmm0, 0 // compare the four pixels
 movmskps edi, xmm1  // mov the comparison mask to edi
 test  edi, edi  // check if the pixels are the same
 jnz  $end_loop  // loop if the pixels are the same

 movapd  [ebx], xmm0  // update the cache DIB
 movntdq  [ecx], xmm0  // update the video DIB with non temporal
         // flag to make sure write only is done

 $end_loop:
 add  eax, 16
 add  ebx, 16
 add  ecx, 16
 sub  esi, 16
 test  esi, esi
 jnz  $loop1

 emms
}

With this function I am able to maintain a framerate of 35 frames/sec with about 10 windows open. That is passing trough all the bitmaps.

Note that the bitmaps must be aligned to 16 bytes in this version

siwu

#208611

People you've lost me here.

Does this mean well be able to mimic OS X's

fast user switching or something?

#208833

Not exactly. As far as I understand it, the OS X desktop is an OpenGL viewport - windows are, in effect, textures mapped onto polygon surfaces. That's why it's so easy to do, as Herd said, the Genie effect when minimizing and so on. It also allows hardware acceleration, so when you're moving or Expose's resizing windows, it's no slower than, say, running around in Bugdom.

#208851