drv.c revision befced03fd84a13590b8ce8be8c2480e9bc568c6
/** @file
*
* VirtualBox Windows NT/2000/XP guest video driver
*
* Display driver screen draw entry points.
*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/* The driver operates in 3 modes:
* 1) BASE : Driver does not report to host about any operations.
* All Drv* are immediately routed to Eng*.
* 2) VBVA : Driver reports dirty rectangles to host.
* 3) VBVA + VRDP : Driver also creates orders pipeline from which VRDP
* can reconstruct all drawing operations, including
* bitmap updates.
*
* These modes affect only Drv* functions in this file.
*
* VBVA mode is enabled by a registry key for the miniport driver
* (as it is implemented now).
*
* VRDP mode is enabled when a VRDP client connects and VBVA is enabled.
* The host sets a bit flag in VBVAMemory when VRDP client is connected.
*
* The VRDP mode pipeline consists of 3 types of commands:
*
* 1) RDP orders: BitBlt, RectFill, Text.
* These are the simpliest ones.
*
* 2) Caching: Bitmap, glyph, brush.
* The driver maintains a bitmap (or other objects) cache.
* All source bitmaps are cached. The driver verifies
* iUniq and also computes CRC for these bitmaps
* for searching. The driver will use SURFOBJ::dhsurf
* field to save a pointer to in driver structure, even
* for Engine managed bitmaps (hope that will work).
*
*
* 3) Bitmap updates, when given draw operation can not be done
* using orders.
*
*/
#include "driver.h"
#ifdef STAT_sunlover
{
if (pso)
{
}
}
#else
#define dumpsurf(a, b)
#endif /* STAT_sunlover */
{
if (pso)
{
/* The screen surface has the 'pso->dhpdev' field,
* and is either the screen device surface with handle = hsurfScreen,
* or a surface derived from DDRAW with address equal to the framebuffer.
*/
if ( ppdev
)
)
{
return TRUE;
}
}
return FALSE;
}
#ifndef VBOX_WITH_HGSMI
if (bIsScreenSurface(__psoDest)) \
{ \
\
{ \
\
{ \
\
} \
\
& VBVA_F_MODE_VRDP) \
{ \
} \
\
} \
} \
} while (0)
#else
if (bIsScreenSurface(__psoDest)) \
{ \
\
{ \
\
{ \
\
} \
\
& VBVA_F_MODE_VRDP) \
{ \
} \
\
} \
} \
} while (0)
#endif /* VBOX_WITH_HGSMI */
//#undef VBVA_OPERATION
//#define VBVA_OPERATION(_psoDest, __fn, __a) do { } while (0)
#if 0
typedef struct _SURFOBJ {
} SURFOBJ;
#endif
)
{
DISPDBG((1, "psoTrg = %p, psoSrc = %p, psoMask = %p, pco = %p, pxlo = %p, prclTrg = %p, pptlSrc = %p, pptlMask = %p, pbo = %p, pptlBrush = %p, rop4 = %08X\n",
bRc = EngBitBlt(CONV_SURF(psoTrg), CONV_SURF(psoSrc), psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4);
return bRc;
}
)
{
bRc = EngTextOut(CONV_SURF(pso), pstro, pfo, pco, prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix);
return bRc;
}
)
{
return bRc;
}
)
{
return bRc;
}
)
{
#ifdef VBOX_VBVA_ADJUST_RECT
/* Experimental fix for too large bitmap updates.
*
* Some application do a large bitmap update event if only
* a small part of the bitmap is actually changed.
*
* The driver will find the changed rectangle by comparing
* the current framebuffer content with the source bitmap.
*
* The optimization is only active when:
* - the VBVA extension is enabled;
* - the source bitmap is not cacheable;
* - the bitmap formats of both the source and the screen surfaces are equal.
*
*/
if ( psoSrc
&& !bIsScreenSurface(psoSrc)
&& bIsScreenSurface(psoDest))
{
#ifndef VBOX_WITH_HGSMI
if ( pVbvaMemory
#else
#endif /* VBOX_WITH_HGSMI */
{
{
DISPDBG((1, "non-cacheable %d->%d (ppdev %p)\n", psoSrc->iBitmapFormat, psoDest->iBitmapFormat, ppdev));
/* It is possible to apply the fix. */
}
}
}
if (!bDo)
{
/* The operation is a NOP. Just return success. */
return TRUE;
}
#endif /* VBOX_VBVA_ADJUST_RECT */
return bRc;
}
)
{
return bRc;
}
)
{
return bRc;
}
)
{
return bRc;
}
)
{
bRc = EngStrokeAndFillPath(CONV_SURF(pso), ppo, pco, pxo, pboStroke, plineattrs, pboFill, pptlBrushOrg, mixFill, flOptions);
return bRc;
}
{
{
}
pSSB->ident = 0;
}
{
{
}
}
{
DISPDBG((1, "ssbCopy: pSSB = %p, pso = %p, prcl = %p, bToScreen = %d\n", pSSB, pso, prcl, bToScreen));
if (cbPixel == 0)
{
return FALSE;
}
if (bToScreen)
{
{
return FALSE;
}
}
else
{
{
return FALSE;
}
{
return FALSE;
}
}
while (cHeight--)
{
}
return TRUE;
}
ULONG_PTR ident,
)
{
if (!ppdev)
{
return rc;
}
/* Order the rectangle. */
{
}
else
{
}
{
}
else
{
}
* requires "the sequencing of saves and restores is such that they
* behave as a last-in, first-out stack.".
*/
switch (iMode)
{
case SS_SAVE:
{
{
/* All slots are already in use. Fail. */
break;
}
/* Get pointer to the slot where bits will be saved. */
/* Allocate memory for screen bits and copy them to the buffer. */
{
/* Bits where successfully copied. Increase the active slot number
* and call VBVA levels, 'ident' is also assigned, the VBVA level
* will use it even for the SS_SAVE.
*/
}
} break;
case SS_RESTORE:
{
|| ident == 0
{
break;
}
{
ssbDiscardUpperSlots (ppdev, ident);
}
VBVA_ASSERT(ident != 0);
/* Bits must be discarded. */
} break;
case SS_FREE:
{
|| ident == 0
{
break;
}
{
ssbDiscardUpperSlots (ppdev, ident);
}
VBVA_ASSERT(ident != 0);
/* Bits must be discarded. */
} break;
}
if (bCallVBVA)
{
}
return rc;
}
)
{
if (bIsScreenSurface(psoTarget))
{
#ifndef VBOX_WITH_HGSMI
{
{
}
{
}
}
#else
{
{
}
{
}
}
#endif /* VBOX_WITH_HGSMI */
}
return bRc;
}
#ifdef STAT_sunlover
ULONG gStatBitmapsCRC = 0;
ULONG gStatEnablePDEV = 0;
ULONG gStatCompletePDEV = 0;
ULONG gStatDisablePDEV = 0;
ULONG gStatEnableSurface = 0;
ULONG gStatDisableSurface = 0;
ULONG gStatAssertMode = 0;
ULONG gStatDisableDriver = 0;
ULONG gStatDitherColor = 0;
ULONG gStatStrokePath = 0;
ULONG gStatFillPath = 0;
ULONG gStatPaint = 0;
ULONG gStatBitBlt = 0;
ULONG gStatCopyBits = 0;
ULONG gStatStretchBlt = 0;
ULONG gStatSetPalette = 0;
ULONG gStatTextOut = 0;
ULONG gStatMovePointer = 0;
ULONG gStatLineTo = 0;
ULONG gStatSynchronize = 0;
ULONG gStatGetModes = 0;
ULONG gStatGradientFill = 0;
ULONG gStatStretchBltROP = 0;
ULONG gStatPlgBlt = 0;
ULONG gStatAlphaBlend = 0;
ULONG gStatTransparentBlt = 0;
void statPrint (void)
{
DISPDBG((0,
"BMPSTAT:\n"
" gStatCopyBitsOffscreenToScreen = %u\n"
" gStatCopyBitsScreenToScreen = %u\n"
" gStatBitBltOffscreenToScreen = %u\n"
" gStatBitBltScreenToScreen = %u\n"
" gStatUnchangedOffscreenToScreen = %u\n"
" gStatUnchangedOffscreenToScreenCRC = %u\n"
" gStatNonTransientEngineBitmaps = %u\n"
" gStatTransientEngineBitmaps = %u\n"
" gStatUnchangedBitmapsCRC = %u\n"
" gStatUnchangedBitmapsDeviceCRC = %u\n"
" gStatBitmapsCRC = %u\n"
" gStatBitBltScreenPattern = %u\n"
" gStatBitBltScreenSquare = %u\n"
" gStatBitBltScreenPatternReported = %u\n"
" gStatBitBltScreenSquareReported = %u\n"
" gStatCopyBitsScreenSquare = %u\n"
"\n"
" gStatEnablePDEV = %u\n"
" gStatCompletePDEV = %u\n"
" gStatDisablePDEV = %u\n"
" gStatEnableSurface = %u\n"
" gStatDisableSurface = %u\n"
" gStatAssertMode = %u\n"
" gStatDisableDriver = %u\n"
" gStatCreateDeviceBitmap = %u\n"
" gStatDeleteDeviceBitmap = %u\n"
" gStatDitherColor = %u\n"
" gStatStrokePath = %u\n"
" gStatFillPath = %u\n"
" gStatStrokeAndFillPath = %u\n"
" gStatPaint = %u\n"
" gStatBitBlt = %u\n"
" gStatCopyBits = %u\n"
" gStatStretchBlt = %u\n"
" gStatSetPalette = %u\n"
" gStatTextOut = %u\n"
" gStatSetPointerShape = %u\n"
" gStatMovePointer = %u\n"
" gStatLineTo = %u\n"
" gStatSynchronize = %u\n"
" gStatGetModes = %u\n"
" gStatGradientFill = %u\n"
" gStatStretchBltROP = %u\n"
" gStatPlgBlt = %u\n"
" gStatAlphaBlend = %u\n"
" gStatTransparentBlt = %u\n",
));
}
#endif /* STAT_sunlover */