Hi all.
I’m developing Mirror Display Driver and I can’t find a good solution to track dirty regions(pixels which was modified).
For example If I take rendering of screen cursor.
As I understood the cursor rendering implemented through DrvCopyBits.
BOOL
DrvCopyBits(
IN SURFOBJ *psoDest,
IN SURFOBJ *psoSrc,
IN CLIPOBJ *pco,
IN XLATEOBJ *pxlo,
IN RECTL *prclDest,
IN POINTL *pptlSrc
);
If I track cursor using pco, I get nothing.
If I track cursor using prclDest, I only get rectangle but I want get pixels which only were modified (without pixels around) http://img175.imageshack.us/img175/6787/cursorte1.png (black pixels on the picture).
I tried to take piece of prclDest area before screen change, after and compare them, but it takes a lot of CPU speed. So this method isn’t good.
Now I at dead end and I don’t see any good solution.
Could anyone can express his opinion about this situation, idea, method. Please.
xxxxx@gmail.com wrote:
I’m developing Mirror Display Driver and I can’t find a good solution to track dirty regions(pixels which was modified).
For example If I take rendering of screen cursor.
As I understood the cursor rendering implemented through DrvCopyBits.
BOOL
DrvCopyBits(
IN SURFOBJ *psoDest,
IN SURFOBJ *psoSrc,
IN CLIPOBJ *pco,
IN XLATEOBJ *pxlo,
IN RECTL *prclDest,
IN POINTL *pptlSrc
);
If I track cursor using pco, I get nothing.
If I track cursor using prclDest, I only get rectangle but I want get pixels which only were modified (without pixels around) http://img175.imageshack.us/img175/6787/cursorte1.png (black pixels on the picture).
I tried to take piece of prclDest area before screen change, after and compare them, but it takes a lot of CPU speed. So this method isn’t good.
Now I at dead end and I don’t see any good solution.
Could anyone can express his opinion about this situation, idea, method. Please.
What do you hope to save? The average cursor is only 64x64. It’s true
that cursor images often have large areas that are transparent, but
there is no inexpensive way to determine that. Even if you did, how
would you communicate it? Cursor images (and icons) contain a mask
bitmap showing the areas to be drawn. It’s not stored as rectangles.
This is a foolish optimization.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
>Cursor images (and icons) contain a mask bitmap showing the areas to be drawn.
Tim, how it’s possible to access to this mask inside DrvCopyBits function (If it’s)?
I took cursor rendering on surface just for example, because I want to find a way how to calculate changed pixels which was modified on surface with EngCopyBits and others Eng functions.
xxxxx@gmail.com wrote:
> Cursor images (and icons) contain a mask bitmap showing the areas to be drawn.
>
Tim, how it’s possible to access to this mask inside DrvCopyBits function (If it’s)?
I took cursor rendering on surface just for example, because I want to find a way how to calculate changed pixels which was modified on surface with EngCopyBits and others Eng functions.
By the time you’re in DrvCopyBits, it’s too late. You don’t ever see
the cursor image – it’s just GDI grabbing a copy of the old bits,
drawing the cursor on its own, and sending you the replacement bits back
again.
The cursor should have been handed to DrvBitBlt first, where the
background mask and the foreground bits come it separately. Only after
DrvBitBlt rejects it (probably because it has a ROP4 showing that there
is a mask) should GDI fall back to CopyBits.
But again, I want to ask you what you would do with this information
even if you got it? Are you going to try to scan through the mask pixel
by pixel, and add the non-transparent pixels to your dirty list as a set
of 1x1 rectangles? That’s not going to be cheap.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
>of 1x1 rectangles?
I can split near pixels then into rectangles and then add them.
Tim, where I can get them then?
I see that
BOOL
DrvBitBlt(
IN SURFOBJ *psoTrg,
IN SURFOBJ *psoSrc,
IN SURFOBJ *psoMask,
IN CLIPOBJ *pco,
IN XLATEOBJ *pxlo,
IN RECTL *prclTrg,
IN POINTL *pptlSrc,
IN POINTL *pptlMask,
IN BRUSHOBJ *pbo,
IN POINTL *pptlBrush,
IN ROP4 rop4
);
Has psoMask, but how can use it?
xxxxx@gmail.com wrote:
> of 1x1 rectangles?
>
I can split near pixels then into rectangles and then add them.
You are wasting your time. The overhead of determining the enclosing
rectangle will cost you more than just adding the whole rectangle to the
list.
Tim, where I can get them then?
I see that
BOOL
DrvBitBlt(
IN SURFOBJ *psoTrg,
IN SURFOBJ *psoSrc,
IN SURFOBJ *psoMask,
IN CLIPOBJ *pco,
IN XLATEOBJ *pxlo,
IN RECTL *prclTrg,
IN POINTL *pptlSrc,
IN POINTL *pptlMask,
IN BRUSHOBJ *pbo,
IN POINTL *pptlBrush,
IN ROP4 rop4
);
Has psoMask, but how can use it?
First you need to make sure you are actually seeing the request come in
there. Do you see requests at cursor time where the top and bottom
halves of the ROP4 are different? Or do you see a series of ROPs, one
of which has a monochrome source, that is making room for the cursor?
Once you know how they arrive, you can figure out how to find the bits.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Sorry for delay.
Yes I see ROP4 with diffrent values.
Hmm does psoMask->pvBits store inverted like in bmp monochrome?
“Tim Roberts” wrote in message news:xxxxx@ntdev…
> xxxxx@gmail.com wrote:
>>> of 1x1 rectangles?
>>>
>> I can split near pixels then into rectangles and then add them.
>>
>
> You are wasting your time. The overhead of determining the enclosing
> rectangle will cost you more than just adding the whole rectangle to the
> list.
>
>> Tim, where I can get them then?
>> I see that BOOL
>> DrvBitBlt(
>> IN SURFOBJ *psoTrg,
>> IN SURFOBJ *psoSrc,
>> IN SURFOBJ *psoMask,
>> IN CLIPOBJ *pco,
>> IN XLATEOBJ *pxlo,
>> IN RECTL *prclTrg,
>> IN POINTL *pptlSrc,
>> IN POINTL *pptlMask,
>> IN BRUSHOBJ *pbo,
>> IN POINTL *pptlBrush,
>> IN ROP4 rop4
>> );
>> Has psoMask, but how can use it?
>
> First you need to make sure you are actually seeing the request come in
> there. Do you see requests at cursor time where the top and bottom halves
> of the ROP4 are different? Or do you see a series of ROPs, one of which
> has a monochrome source, that is making room for the cursor?
>
> Once you know how they arrive, you can figure out how to find the bits.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
User5 wrote:
Sorry for delay.
Yes I see ROP4 with diffrent values.
Hmm does psoMask->pvBits store inverted like in bmp monochrome?
“Inverted” has no meaning here. The MSDN page on DrvBitBlt is quite
clear on how the mask is used.
/rop4/
[in] Raster operation that defines how the mask, pattern, source,
and destination pixels are combined to write to the destination
surface.
This is a quaternary raster operation, which is an extension of the
ternary Rop3 operation. A Rop4 has 16 relevant bits, which are
similar to the 8 defining bits of a Rop3. The simplest way to
implement a Rop4 is to consider its 2 bytes separately. The low byte
specifies a Rop3 that should be calculated if the mask is 1, and the
high byte specifies a Rop3 that can be calculated and applied if the
mask is zero.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
If I understood right, I need to do something like this
switch (rop4)
{
case ROP3_TO_ROP4(MERGECOPY):
{
}
break;
…
}
When MERGECOPY in this case the dirty area will be the mask monochrome
bitmap.
When PATINVERT I need to calculate pattern from mask …
Do I think in right direction?
“Tim Roberts” wrote in message news:xxxxx@ntdev…
> User5 wrote:
>> Sorry for delay.
>> Yes I see ROP4 with diffrent values.
>> Hmm does psoMask->pvBits store inverted like in bmp monochrome?
>>
>
> “Inverted” has no meaning here. The MSDN page on DrvBitBlt is quite clear
> on how the mask is used.
>
> /rop4/
>
> [in] Raster operation that defines how the mask, pattern, source,
> and destination pixels are combined to write to the destination
> surface.
>
> This is a quaternary raster operation, which is an extension of the
> ternary Rop3 operation. A Rop4 has 16 relevant bits, which are
> similar to the 8 defining bits of a Rop3. The simplest way to
> implement a Rop4 is to consider its 2 bytes separately. The low byte
> specifies a Rop3 that should be calculated if the mask is 1, and the
> high byte specifies a Rop3 that can be calculated and applied if the
> mask is zero.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
User5 wrote:
If I understood right, I need to do something like this
switch (rop4)
{
case ROP3_TO_ROP4(MERGECOPY):
{
}
break;
…
}
When MERGECOPY in this case the dirty area will be the mask monochrome
bitmap.
When PATINVERT I need to calculate pattern from mask …
Do I think in right direction?
I’m not sure what direction you are thinking. You said you were seeing
a DrvBitBlt call with a mask, which means the ROP4 had different values
in the upper and lower bytes. Your switch is never going to catch
that. ROP3_TO_ROP4 takes a ROP3 and multiplies it by 0x0101 so that it
has the SAME value in upper and lower bytes. So,
ROP3_TO_ROP4(MERGECOPY) produces 0xC0C0. That will never match a ROP
with a mask.
If your cursors are being drawn with two separate blts – one PATINVERT
to dig the hole, one MERGECOPY to draw the pointer – then this should
catch it.
I still say it will be more expensive for you to pick the dirty area out
of the mask than it is to assume the whole square is dirty.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
> This is a quaternary raster operation, which is an extension of the
ternary Rop3 operation. A Rop4 has 16 relevant bits, which are
In user mode, this is called MaskBlt.
–
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
Emmm If I catch PATINVERT for example(under debbuger) and I want to
canculate the area or pixels which will be modified on psoDst surfacer after
EngBitBlt call (inside DrvBitBlt).
What function’s variable I need to use to do this? (In this case)
As I undestood in this case dependency is Pattern & Destination (mask is
null), so in this case I just need consider modified area from pco or
prclDst as a rectangle?
User5 wrote:
Emmm If I catch PATINVERT for example(under debbuger) and I want to
canculate the area or pixels which will be modified on psoDst surfacer after
EngBitBlt call (inside DrvBitBlt).
What function’s variable I need to use to do this? (In this case)
As I undestood in this case dependency is Pattern & Destination (mask is
null), so in this case I just need consider modified area from pco or
prclDst as a rectangle?
The answer to this question is exactly the same, regardless of what the
ROP is, or whether there is a pattern or a mask. The affected area is
the prclDst rectangle, possibly clipped by the CLIPOBJ.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Yes. You’re right.
Now I can’t understand one moment.
I want to know what Height and Widht of mask surface. And
when I look at psoMask->sizlBitmap (not nulled) inside DrvBitBlt, I see for
example
x = 32
y = 5303
And that’s out of range of psoDst surface. It’s true that sizlBitmap
contains Height and Widht of mask surface? Or I look wrong?
“Tim Roberts” wrote in message news:xxxxx@ntdev…
> User5 wrote:
>> Emmm If I catch PATINVERT for example(under debbuger) and I want to
>> canculate the area or pixels which will be modified on psoDst surfacer
>> after EngBitBlt call (inside DrvBitBlt).
>> What function’s variable I need to use to do this? (In this case)
>> As I undestood in this case dependency is Pattern & Destination (mask is
>> null), so in this case I just need consider modified area from pco or
>> prclDst as a rectangle?
>
> The answer to this question is exactly the same, regardless of what the
> ROP is, or whether there is a pattern or a mask. The affected area is the
> prclDst rectangle, possibly clipped by the CLIPOBJ.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
User5 wrote:
Yes. You’re right.
Now I can’t understand one moment.
I want to know what Height and Widht of mask surface. And
when I look at psoMask->sizlBitmap (not nulled) inside DrvBitBlt, I see for
example
x = 32
y = 5303
And that’s out of range of psoDst surface. It’s true that sizlBitmap
contains Height and Widht of mask surface? Or I look wrong?
Those numbers are unlikely, but not impossible. Icons and cursors are
often cached together in one large bitmap. The pptlMask parameter tells
what part of the mask is going to be used for this blit. So, if there
are 100 cursors of size 32x32 in that surface, the surface would be
32x3200. If you were supposed to use the 50th one, pptlMask would be
(0, 1600).
However, for your purposes the size of the mask surface is completely
irrelevant. To repeat what I just said, the affected area is the
prclDst rectangle, possibly clipped by the CLIPOBJ. Both the source and
the mask bitmaps can be much larger than this area. The display driver
will simply extract the section that it needs for the current operation.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
I tried to calculate changed regeons from DrvBitBlt with mask/rect and from
DrvAlphaBlend. But I don’t get cursor area.
Now I’m at dead end. Could anyone can say something about this situation?
“Tim Roberts” wrote in message news:xxxxx@ntdev…
> User5 wrote:
>> Yes. You’re right.
>> Now I can’t understand one moment.
>> I want to know what Height and Widht of mask surface. And
>> when I look at psoMask->sizlBitmap (not nulled) inside DrvBitBlt, I see
>> for example
>> x = 32
>> y = 5303
>> And that’s out of range of psoDst surface. It’s true that sizlBitmap
>> contains Height and Widht of mask surface? Or I look wrong?
>>
>
> Those numbers are unlikely, but not impossible. Icons and cursors are
> often cached together in one large bitmap. The pptlMask parameter tells
> what part of the mask is going to be used for this blit. So, if there are
> 100 cursors of size 32x32 in that surface, the surface would be 32x3200.
> If you were supposed to use the 50th one, pptlMask would be (0, 1600).
>
> However, for your purposes the size of the mask surface is completely
> irrelevant. To repeat what I just said, the affected area is the prclDst
> rectangle, possibly clipped by the CLIPOBJ. Both the source and the mask
> bitmaps can be much larger than this area. The display driver will simply
> extract the section that it needs for the current operation.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
Could any could say what exactly Drv graphical function are using to draw
Start menu button?
I only see that when I move cursor to the button, DrvCopyBits occurs which
only copy the pixels, so I can get changed rectangle from it, but I can’t
get only pixels which were modified from this function, so I assume that
these is another diffrent Drv function call before DrvCopyBits, but I can’t
understand which.
User5 wrote:
I tried to calculate changed regeons from DrvBitBlt with mask/rect and from
DrvAlphaBlend. But I don’t get cursor area.
Now I’m at dead end. Could anyone can say something about this situation?
I don’t understand what you are saying here. Are you saying you do see
32x32 or 64x64 masked blits when the cursor moves? Or you do NOT see that?
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
User5 wrote:
Could any could say what exactly Drv graphical function are using to draw
Start menu button?
I only see that when I move cursor to the button, DrvCopyBits occurs which
only copy the pixels, so I can get changed rectangle from it, but I can’t
get only pixels which were modified from this function, so I assume that
these is another diffrent Drv function call before DrvCopyBits, but I can’t
understand which.
My assumption is that Explorer contains three separate bitmaps: one with
the button up, one with the button down, and one with the button’s
“hover” state. When you bring the mouse over the button, it just copies
the “hover” bitmap image to replace the entire button area. Thus, the
“changed rectangle” is the entire button.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Sorry. I was wrong.
I see DrvBitBlt call only when for example I click on shortcuts(only low bit
depth) on the desktop.
“Tim Roberts” wrote in message news:xxxxx@ntdev…
> User5 wrote:
>> I tried to calculate changed regeons from DrvBitBlt with mask/rect and
>> from DrvAlphaBlend. But I don’t get cursor area.
>> Now I’m at dead end. Could anyone can say something about this situation?
>>
>
> I don’t understand what you are saying here. Are you saying you do see
> 32x32 or 64x64 masked blits when the cursor moves? Or you do NOT see
> that?
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>