VBoxFBDDRAW.cpp revision 05fb7454f402098331166b59778f1b03d2e7c8c1
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
* DDRAW framebuffer implementation
*/
/*
* Copyright (C) 2006-2007 innotek GmbH
*
* 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.
*/
#if defined (VBOX_GUI_USE_DDRAW)
#include "VBoxFrameBuffer.h"
#include "VBoxConsoleView.h"
#include <qapplication.h>
/* @todo
* - when paused in Guest VRAM mode after pause the screen is dimmed. because VRAM is dimmed.
* - when GUI window is resized, somehow take this into account, blit only visible parts.
*/
/*
* Helpers.
*/
static LPDIRECTDRAW7 getDDRAW (void)
{
{
}
else
{
{
}
else
{
{
}
}
}
}
{
sd.dwBackBufferCount = 0;
{
}
}
{
{
}
else
{
{
}
}
}
//
// VBoxDDRAWFrameBuffer class
/////////////////////////////////////////////////////////////////////////////
/** @class VBoxDDRAWFrameBuffer
*
* The VBoxDDRAWFrameBuffer class is a class that implements the IFrameBuffer
* interface and uses Win32 DirectDraw to store and render VM display data.
*/
mUsesGuestVRAM (false),
mWndX (0),
mWndY (0),
mSynchronousUpdates (true)
{
LOGDDRAW (("DDRAW: Creating\n"));
/* Release all created objects if something will go wrong. */
if (mDDRAW)
{
if (mClipper)
{
if (mPrimarySurface)
{
if (re)
{
resizeEvent (re);
delete re;
if (mSurface)
{
/* Everything was initialized. */
}
}
}
}
}
if (bReleaseObjects)
{
}
}
{
}
void VBoxDDRAWFrameBuffer::releaseObjects()
{
deleteSurface ();
if (mPrimarySurface)
{
if (mClipper)
{
}
mPrimarySurface->Release ();
}
if (mClipper)
{
}
if (mDDRAW)
{
}
}
/** @note This method is called on EMT from under this object's lock */
{
if (mSynchronousUpdates)
{
}
else
{
}
return S_OK;
}
{
LOGDDRAW (("DDRAW: paintEvent %d,%d %dx%d\n",
}
{
LOGDDRAW (("DDRAW: resizeEvent %d, %p, %d %d %dx%d\n",
{
/* try to create a fallback surface with indirect buffer
* (only if haven't done so already) */
}
}
{
}
/*
* Private methods.
*/
/**
* Creates a new surface in the requested format.
* On success, returns @c true and assigns the created surface to mSurface
* and its definition to mSurfaceDesc. On failure, returns @c false.
*
* If @a aPixelFormat is other than FramebufferPixelFormat_Opaque,
* then the method will attempt to attach @a aVRAM directly to the created
* surface. If this fails, the caller may call this method again with
* @a aPixelFormat set to FramebufferPixelFormat_Opaque to try
* setting up an indirect fallback buffer for the surface. This opeartion may
* theoretically also fail.
*
* @note Deletes the existing surface before attemting to create a new one.
*/
{
/* Prepare the surface description structure. */
/* Setup the desired pixel format on the surface. */
{
/* Try to use the guest VRAM directly */
switch (aBitsPerPixel)
{
case 32:
break;
case 24:
break;
case 16:
break;
default:
/* we don't directly support any other color depth */
return false;
}
mUsesGuestVRAM = true;
}
else
{
/* we don't directly support any other pixel format */
return false;
}
else
{
/* for the Opaque format, we use the indirect memory buffer as a
* 32 bpp surface. */
/* Allocate the memory buffer for the surface */
{
LOGDDRAW (("DDRAW: could not allocate memory for surface.\n"));
return false;
}
mUsesGuestVRAM = false;
}
/* create the surface */
{
return false;
}
/* Initialize the surface description member. It will be used to obtain
* address, bpp and bpl. */
mSurfaceDesc = sd;
LOGDDRAW(("DDRAW: Created %s surface: format = %d, address = %p\n",
aPixelFormat, address ()));
if (!mUsesGuestVRAM)
{
/* Clear just created surface. */
}
return true;
}
void VBoxDDRAWFrameBuffer::deleteSurface ()
{
if (mSurface)
{
if (!mUsesGuestVRAM)
{
}
mUsesGuestVRAM = false;
}
}
/**
* Draws a rectangular area of guest screen DDRAW surface onto the
* host screen primary surface.
*/
{
LOGDDRAW (("DDRAW: drawRect: %d,%d, %dx%d\n", x, y, w, h));
if (mSurface && w > 0 && h > 0)
{
/* DDBLT_ASYNC performs this blit asynchronously through the
* first in, first out (FIFO) hardware in the order received.
* If no room is available in the FIFO hardware, the call fails.
* DDBLT_WAIT waits if blitter is busy, and returns as soon as the
* blit can be set up or another error occurs.
*
* I assume that DDBLT_WAIT will also wait for a room in the FIFO.
*/
{
/* Repeat without DDBLT_ASYNC. */
{
}
}
}
return;
}
void VBoxDDRAWFrameBuffer::getWindowPosition (void)
{
// if (mPrimarySurface)
// {
// /* Lock surface to synchronize with Blt in drawRect. */
// DDSURFACEDESC2 sd;
// memset (&sd, 0, sizeof (sd));
// sd.dwSize = sizeof (sd);
//
// HRESULT rc = mPrimarySurface->Lock (NULL, &sd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
// LOGDDRAW(("DDRAW: getWindowPosition rc = 0x%08X\n", rc));
// }
// if (mPrimarySurface)
// {
// mPrimarySurface->Unlock (NULL);
// }
}
#endif /* defined (VBOX_GUI_USE_DDRAW) */