summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/vmware/vmware_2d.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/vmware/vmware_2d.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/vmware/vmware_2d.c402
1 files changed, 402 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/vmware/vmware_2d.c b/Source/DirectFB/gfxdrivers/vmware/vmware_2d.c
new file mode 100755
index 0000000..1e50978
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/vmware/vmware_2d.c
@@ -0,0 +1,402 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#include <core/state.h>
+#include <core/surface.h>
+
+#include <gfx/convert.h>
+
+#include "vmware_2d.h"
+#include "vmware_gfxdriver.h"
+
+
+D_DEBUG_DOMAIN( VMWare_2D, "VMWare/2D", "VMWare 2D Acceleration" );
+
+/*
+ * State validation flags.
+ *
+ * There's no prefix because of the macros below.
+ */
+enum {
+ DESTINATION = 0x00000001,
+ COLOR = 0x00000002,
+
+ SOURCE = 0x00000010,
+
+ ALL = 0x00000013
+};
+
+/*
+ * State handling macros.
+ */
+
+#define VMWARE_VALIDATE(flags) do { vdev->v_flags |= (flags); } while (0)
+#define VMWARE_INVALIDATE(flags) do { vdev->v_flags &= ~(flags); } while (0)
+
+#define VMWARE_CHECK_VALIDATE(flag) do { \
+ if (! (vdev->v_flags & flag)) \
+ vmware_validate_##flag( vdev, state ); \
+ } while (0)
+
+
+/**************************************************************************************************/
+
+/*
+ * Called by vmwareSetState() to ensure that the destination registers are properly set
+ * for execution of rendering functions.
+ */
+static inline void
+vmware_validate_DESTINATION( VMWareDeviceData *vdev,
+ CardState *state )
+{
+ /* Remember destination parameters for usage in rendering functions. */
+ vdev->dst_addr = state->dst.addr;
+ vdev->dst_pitch = state->dst.pitch;
+ vdev->dst_format = state->dst.buffer->format;
+ vdev->dst_bpp = DFB_BYTES_PER_PIXEL( vdev->dst_format );
+
+ /* Set the flag. */
+ VMWARE_VALIDATE( DESTINATION );
+}
+
+/*
+ * Called by vmwareSetState() to ensure that the color register is properly set
+ * for execution of rendering functions.
+ */
+static inline void
+vmware_validate_COLOR( VMWareDeviceData *vdev,
+ CardState *state )
+{
+ switch (vdev->dst_format) {
+ case DSPF_ARGB:
+ vdev->color_pixel = PIXEL_ARGB( state->color.a,
+ state->color.r,
+ state->color.g,
+ state->color.b );
+ break;
+
+ case DSPF_RGB32:
+ vdev->color_pixel = PIXEL_RGB32( state->color.r,
+ state->color.g,
+ state->color.b );
+ break;
+
+ case DSPF_RGB16:
+ vdev->color_pixel = PIXEL_RGB16( state->color.r,
+ state->color.g,
+ state->color.b );
+ break;
+
+ default:
+ D_BUG( "unexpected format %s", dfb_pixelformat_name(vdev->dst_format) );
+ }
+
+ /* Set the flag. */
+ VMWARE_VALIDATE( COLOR );
+}
+
+/*
+ * Called by vmwareSetState() to ensure that the source registers are properly set
+ * for execution of blitting functions.
+ */
+static inline void
+vmware_validate_SOURCE( VMWareDeviceData *vdev,
+ CardState *state )
+{
+ /* Remember source parameters for usage in rendering functions. */
+ vdev->src_addr = state->src.addr;
+ vdev->src_pitch = state->src.pitch;
+ vdev->src_format = state->src.buffer->format;
+ vdev->src_bpp = DFB_BYTES_PER_PIXEL( vdev->src_format );
+
+ /* Set the flag. */
+ VMWARE_VALIDATE( SOURCE );
+}
+
+/**************************************************************************************************/
+
+/*
+ * Wait for the blitter to be idle.
+ *
+ * This function is called before memory that has been written to by the hardware is about to be
+ * accessed by the CPU (software driver) or another hardware entity like video encoder (by Flip()).
+ * It can also be called by applications explicitly, e.g. at the end of a benchmark loop to include
+ * execution time of queued commands in the measurement.
+ */
+DFBResult
+vmwareEngineSync( void *drv, void *dev )
+{
+ return DFB_OK;
+}
+
+/*
+ * Reset the graphics engine.
+ */
+void
+vmwareEngineReset( void *drv, void *dev )
+{
+}
+
+/*
+ * Start processing of queued commands if required.
+ *
+ * This function is called before returning from the graphics core to the application.
+ * Usually that's after each rendering function. The only functions causing multiple commands
+ * to be queued with a single emition at the end are DrawString(), TileBlit(), BatchBlit(),
+ * DrawLines() and possibly FillTriangle() which is emulated using multiple FillRectangle() calls.
+ */
+void
+vmwareEmitCommands( void *drv, void *dev )
+{
+}
+
+/*
+ * Check for acceleration of 'accel' using the given 'state'.
+ */
+void
+vmwareCheckState( void *drv,
+ void *dev,
+ CardState *state,
+ DFBAccelerationMask accel )
+{
+ D_DEBUG_AT( VMWare_2D, "vmwareCheckState (state %p, accel 0x%08x) <- dest %p\n",
+ state, accel, state->destination );
+
+ /* Return if the desired function is not supported at all. */
+ if (accel & ~(VMWARE_SUPPORTED_DRAWINGFUNCTIONS | VMWARE_SUPPORTED_BLITTINGFUNCTIONS))
+ return;
+
+ /* Return if the destination format is not supported. */
+ switch (state->destination->config.format) {
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ case DSPF_RGB16:
+ break;
+
+ default:
+ return;
+ }
+
+ /* Check if drawing or blitting is requested. */
+ if (DFB_DRAWING_FUNCTION( accel )) {
+ /* Return if unsupported drawing flags are set. */
+ if (state->drawingflags & ~VMWARE_SUPPORTED_DRAWINGFLAGS)
+ return;
+ }
+ else {
+ /* Return if the source format is not supported. */
+ switch (state->source->config.format) {
+ case DSPF_ARGB:
+ case DSPF_RGB32:
+ case DSPF_RGB16:
+ /* FIXME: Currently only copying blits supported. */
+ if (state->source->config.format == state->destination->config.format)
+ break;
+
+ default:
+ return;
+ }
+
+ /* Return if unsupported blitting flags are set. */
+ if (state->blittingflags & ~VMWARE_SUPPORTED_BLITTINGFLAGS)
+ return;
+ }
+
+ /* Enable acceleration of the function. */
+ state->accel |= accel;
+}
+
+/*
+ * Make sure that the hardware is programmed for execution of 'accel' according to the 'state'.
+ */
+void
+vmwareSetState( void *drv,
+ void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state,
+ DFBAccelerationMask accel )
+{
+ VMWareDeviceData *vdev = (VMWareDeviceData*) dev;
+ StateModificationFlags modified = state->mod_hw;
+
+ D_DEBUG_AT( VMWare_2D, "vmwareSetState (state %p, accel 0x%08x) <- dest %p, modified 0x%08x\n",
+ state, accel, state->destination, modified );
+
+ /*
+ * 1) Invalidate hardware states
+ *
+ * Each modification to the hw independent state invalidates one or more hardware states.
+ */
+
+ /* Simply invalidate all? */
+ if (modified == SMF_ALL) {
+ VMWARE_INVALIDATE( ALL );
+ }
+ else if (modified) {
+ /* Invalidate destination registers. */
+ if (modified & SMF_DESTINATION)
+ VMWARE_INVALIDATE( DESTINATION | COLOR );
+ else if (modified & SMF_COLOR)
+ VMWARE_INVALIDATE( COLOR );
+
+ if (modified & SMF_SOURCE)
+ VMWARE_INVALIDATE( SOURCE );
+ }
+
+ /*
+ * 2) Validate hardware states
+ *
+ * Each function has its own set of states that need to be validated.
+ */
+
+ /* Always requiring valid destination... */
+ VMWARE_CHECK_VALIDATE( DESTINATION );
+
+ /* Depending on the function... */
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ /* ...require valid drawing color. */
+ VMWARE_CHECK_VALIDATE( COLOR );
+
+ /*
+ * 3) Tell which functions can be called without further validation, i.e. SetState()
+ *
+ * When the hw independent state is changed, this collection is reset.
+ */
+ state->set = VMWARE_SUPPORTED_DRAWINGFUNCTIONS;
+ break;
+
+ case DFXL_BLIT:
+ /* ...require valid source. */
+ VMWARE_CHECK_VALIDATE( SOURCE );
+
+ /*
+ * 3) Tell which functions can be called without further validation, i.e. SetState()
+ *
+ * When the hw independent state is changed, this collection is reset.
+ */
+ state->set = VMWARE_SUPPORTED_BLITTINGFUNCTIONS;
+ break;
+
+ default:
+ D_BUG( "unexpected drawing/blitting function" );
+ break;
+ }
+
+ /*
+ * 4) Clear modification flags
+ *
+ * All flags have been evaluated in 1) and remembered for further validation.
+ * If the hw independent state is not modified, this function won't get called
+ * for subsequent rendering functions, unless they aren't defined by 3).
+ */
+ state->mod_hw = 0;
+}
+
+/*
+ * Render a filled rectangle using the current hardware state.
+ */
+bool
+vmwareFillRectangle( void *drv, void *dev, DFBRectangle *rect )
+{
+ VMWareDeviceData *vdev = (VMWareDeviceData*) dev;
+ void *addr = vdev->dst_addr + rect->y * vdev->dst_pitch +
+ DFB_BYTES_PER_LINE(vdev->dst_format, rect->x);
+
+ D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ) );
+
+ switch (vdev->dst_bpp) {
+ case 4:
+ while (rect->h--) {
+ int w = rect->w;
+ u32 *dst = addr;
+
+ while (w--)
+ *dst++ = vdev->color_pixel;
+
+ addr += vdev->dst_pitch;
+ }
+ break;
+
+ case 2:
+ while (rect->h--) {
+ int w = rect->w;
+ u16 *dst = addr;
+
+ while (w--)
+ *dst++ = vdev->color_pixel;
+
+ addr += vdev->dst_pitch;
+ }
+ break;
+
+ case 1:
+ while (rect->h--) {
+ int w = rect->w;
+ u8 *dst = addr;
+
+ while (w--)
+ *dst++ = vdev->color_pixel;
+
+ addr += vdev->dst_pitch;
+ }
+ break;
+ }
+
+ return true;
+}
+
+/*
+ * Render a filled rectangle using the current hardware state.
+ */
+bool
+vmwareBlit( void *drv, void *dev, DFBRectangle *srect, int dx, int dy )
+{
+ VMWareDeviceData *vdev = (VMWareDeviceData*) dev;
+ void *dst = vdev->dst_addr + dy * vdev->dst_pitch +
+ DFB_BYTES_PER_LINE(vdev->dst_format, dx);
+ void *src = vdev->src_addr + srect->y * vdev->src_pitch +
+ DFB_BYTES_PER_LINE(vdev->src_format, srect->x);
+
+ D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d -> %d, %d )\n", __FUNCTION__,
+ DFB_RECTANGLE_VALS( srect ), dx, dy );
+
+ while (srect->h--) {
+ direct_memcpy( dst, src, srect->w * vdev->dst_bpp );
+
+ dst += vdev->dst_pitch;
+ src += vdev->src_pitch;
+ }
+
+ return true;
+}
+