diff options
-rw-r--r-- | canvas/Library_directx5canvas.mk | 103 | ||||
-rw-r--r-- | canvas/Module_canvas.mk | 6 | ||||
-rw-r--r-- | canvas/source/directx/directx5canvas.component | 34 | ||||
-rw-r--r-- | canvas/source/directx/dx_5rm.cxx | 2283 | ||||
-rw-r--r-- | postprocess/packcomponents/makefile.mk | 4 | ||||
-rw-r--r-- | scp2/source/canvas/directxcanvas.scp | 3 | ||||
-rw-r--r-- | scp2/source/canvas/makefile.mk | 3 | ||||
-rwxr-xr-x | set_soenv.in | 2 |
8 files changed, 0 insertions, 2438 deletions
diff --git a/canvas/Library_directx5canvas.mk b/canvas/Library_directx5canvas.mk deleted file mode 100644 index 13e24676d62b..000000000000 --- a/canvas/Library_directx5canvas.mk +++ /dev/null @@ -1,103 +0,0 @@ -# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- -#************************************************************************* -# -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# Copyright 2000, 2011 Oracle and/or its affiliates. -# -# OpenOffice.org - a multi-platform office productivity suite -# -# This file is part of OpenOffice.org. -# -# OpenOffice.org is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3 -# only, as published by the Free Software Foundation. -# -# OpenOffice.org 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 version 3 for more details -# (a copy is included in the LICENSE file that accompanied this code). -# -# You should have received a copy of the GNU Lesser General Public License -# version 3 along with OpenOffice.org. If not, see -# <http://www.openoffice.org/license.html> -# for a copy of the LGPLv3 License. -# -#************************************************************************* - -$(eval $(call gb_Library_Library,directx5canvas)) - -$(eval $(call gb_Library_set_componentfile,directx5canvas,canvas/source/directx/directx5canvas)) - -$(eval $(call gb_Library_set_include,directx5canvas,\ - $$(INCLUDE) \ - -I$(SRCDIR)/canvas/inc \ - -I$(SRCDIR)/canvas/source/directx \ -)) - -$(eval $(call gb_Library_add_api,directx5canvas,\ - offapi \ - udkapi \ -)) - -# clear NOMINMAX because GdiplusTypes.h uses those macros :( -$(eval $(call gb_Library_add_defs,directx5canvas,\ - -DDIRECTX_VERSION=0x0500 \ - -UNOMINMAX \ -)) - -$(eval $(call gb_Library_add_linked_libs,directx5canvas,\ - cppu \ - tk \ - sal \ - comphelper \ - cppuhelper \ - basegfx \ - canvastools \ - vcl \ - tl \ - utl \ - i18nisolang1 \ - $(gb_STDLIBS) \ -)) - -ifeq ($(OS),WNT) -$(eval $(call gb_Library_add_linked_libs,directx5canvas,\ - d3dx \ - gdi32 \ - gdiplus \ - ddraw \ -)) -endif - -$(WORKDIR)/CustomTarget/canvas/source/directx/%.cxx : $(SRCDIR)/canvas/source/directx/%.cxx - mkdir -p $(dir $@) && \ - cp $< $@ - -$(eval $(call gb_Library_add_generated_exception_objects,directx5canvas,\ - CustomTarget/canvas/source/directx/dx_5rm \ - CustomTarget/canvas/source/directx/dx_bitmap \ - CustomTarget/canvas/source/directx/dx_bitmapcanvashelper \ - CustomTarget/canvas/source/directx/dx_canvasbitmap \ - CustomTarget/canvas/source/directx/dx_canvascustomsprite \ - CustomTarget/canvas/source/directx/dx_canvasfont \ - CustomTarget/canvas/source/directx/dx_canvashelper \ - CustomTarget/canvas/source/directx/dx_canvashelper_texturefill \ - CustomTarget/canvas/source/directx/dx_config \ - CustomTarget/canvas/source/directx/dx_devicehelper \ - CustomTarget/canvas/source/directx/dx_gdiplususer \ - CustomTarget/canvas/source/directx/dx_impltools \ - CustomTarget/canvas/source/directx/dx_linepolypolygon \ - CustomTarget/canvas/source/directx/dx_spritecanvas \ - CustomTarget/canvas/source/directx/dx_spritecanvashelper \ - CustomTarget/canvas/source/directx/dx_spritedevicehelper \ - CustomTarget/canvas/source/directx/dx_spritehelper \ - CustomTarget/canvas/source/directx/dx_surfacebitmap \ - CustomTarget/canvas/source/directx/dx_surfacegraphics \ - CustomTarget/canvas/source/directx/dx_textlayout \ - CustomTarget/canvas/source/directx/dx_textlayout_drawhelper \ - CustomTarget/canvas/source/directx/dx_vcltools \ -)) - -# vim: set noet sw=4 ts=4: diff --git a/canvas/Module_canvas.mk b/canvas/Module_canvas.mk index 31791984a7c3..859561193680 100644 --- a/canvas/Module_canvas.mk +++ b/canvas/Module_canvas.mk @@ -46,12 +46,6 @@ endif ifeq ($(strip $(OS)),WNT) ifneq ($(strip $(ENABLE_DIRECTX)),) -ifneq ($(strip $(USE_DIRECTX5)),) -$(eval $(call gb_Module_add_targets,canvas,\ - Library_directx5canvas \ -)) -endif - $(eval $(call gb_Module_add_targets,canvas,\ Library_directx9canvas \ Library_gdipluscanvas \ diff --git a/canvas/source/directx/directx5canvas.component b/canvas/source/directx/directx5canvas.component deleted file mode 100644 index f7bcdbffe517..000000000000 --- a/canvas/source/directx/directx5canvas.component +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!--********************************************************************** -* -* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -* -* Copyright 2000, 2010 Oracle and/or its affiliates. -* -* OpenOffice.org - a multi-platform office productivity suite -* -* This file is part of OpenOffice.org. -* -* OpenOffice.org is free software: you can redistribute it and/or modify -* it under the terms of the GNU Lesser General Public License version 3 -* only, as published by the Free Software Foundation. -* -* OpenOffice.org 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 version 3 for more details -* (a copy is included in the LICENSE file that accompanied this code). -* -* You should have received a copy of the GNU Lesser General Public License -* version 3 along with OpenOffice.org. If not, see -* <http://www.openoffice.org/license.html> -* for a copy of the LGPLv3 License. -* -**********************************************************************--> - -<component loader="com.sun.star.loader.SharedLibrary" prefix="directx5canvas" - xmlns="http://openoffice.org/2010/uno-components"> - <implementation name="com.sun.star.comp.rendering.SpriteCanvas.DX5"> - <service name="com.sun.star.rendering.SpriteCanvas.DX5"/> - </implementation> -</component> diff --git a/canvas/source/directx/dx_5rm.cxx b/canvas/source/directx/dx_5rm.cxx deleted file mode 100644 index 1d2ac0ac7926..000000000000 --- a/canvas/source/directx/dx_5rm.cxx +++ /dev/null @@ -1,2283 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org 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 version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -#if DIRECTX_VERSION < 0x0900 - -// Nvidia GeForce Go 6800 crashes with a bluescreen if we take the -// maximum texture size, which would be twice as large. this behaviors -// has only been observed on directx5. -// This value is simply the maximum size for textures we request from -// the system, it has absolutely nothing to do with the size of primitives -// we're able to render, both concepts are totally independent from each other. -#define MAX_TEXTURE_SIZE (2048) -#define MIN_TEXTURE_SIZE (32) -//#define FAKE_MAX_NUMBER_TEXTURES (2) -//#define FAKE_MAX_TEXTURE_SIZE (512) - -////////////////////////////////////////////////////////////////////////////////// -// includes -////////////////////////////////////////////////////////////////////////////////// -#include <vcl/syschild.hxx> -#include <vcl/window.hxx> -#include <canvas/debug.hxx> -#include <canvas/verbosetrace.hxx> -#include <canvas/elapsedtime.hxx> -#include <canvas/canvastools.hxx> -#include <canvas/rendering/icolorbuffer.hxx> -#include <canvas/rendering/isurface.hxx> -#include <canvas/rendering/irendermodule.hxx> -#include <tools/diagnose_ex.h> -#include <basegfx/numeric/ftools.hxx> -#include <basegfx/vector/b2dsize.hxx> -#include <basegfx/vector/b2isize.hxx> -#include <basegfx/point/b2ipoint.hxx> -#include <basegfx/range/b2irectangle.hxx> -#include <boost/scoped_ptr.hpp> -#include <com/sun/star/lang/NoSupportException.hpp> - -#define COMPILE_MULTIMON_STUBS - -#include "dx_rendermodule.hxx" -#include "dx_surfacegraphics.hxx" -#include <vcl/sysdata.hxx> - -#undef WB_LEFT -#undef WB_RIGHT - -#include "dx_impltools.hxx" -#include <malloc.h> - -#if defined(DX_DEBUG_IMAGES) -# if OSL_DEBUG_LEVEL > 0 -# include <imdebug.h> -# undef min -# undef max -# endif -#endif - -#undef COMPILE_MULTIMON_STUBS - -#include <stdio.h> - -#define MONITOR_DEFAULTTONULL 0x00000000 -#define MONITOR_DEFAULTTOPRIMARY 0x00000001 -#define MONITOR_DEFAULTTONEAREST 0x00000002 - -using namespace ::com::sun::star; - -////////////////////////////////////////////////////////////////////////////////// -// 'dxcanvas' namespace -////////////////////////////////////////////////////////////////////////////////// - -namespace dxcanvas -{ - namespace - { - bool doBlit( const ::basegfx::B2IPoint& rDestPos, - IDirectDrawSurface& rOutSurface, - const ::basegfx::B2IRange& rSourceArea, - IDirectDrawSurface& rSourceSurface, - DDBLTFX* pBltFx, - bool bForceSoftware ) - { - if( !bForceSoftware ) - { - // blit surface to backbuffer - RECT aOutRect = - { - rDestPos.getX(), - rDestPos.getY(), - rDestPos.getX() + static_cast<sal_Int32>(rSourceArea.getWidth()), - rDestPos.getY() + static_cast<sal_Int32>(rSourceArea.getHeight()), - }; - RECT aSourceRect = - { - rSourceArea.getMinX(), - rSourceArea.getMinY(), - rSourceArea.getMaxX(), - rSourceArea.getMaxY() - }; - - if( SUCCEEDED(rOutSurface.Blt( &aOutRect, - &rSourceSurface, - &aSourceRect, - DDBLT_WAIT, - pBltFx )) ) - { - return true; - } - } - - // failed, or forced to use SW copy. attempt manual copy. - bool bResult = false; - - // lock source surface - DDSURFACEDESC aDescSrc; - rtl_fillMemory(&aDescSrc,sizeof(DDSURFACEDESC),0); - aDescSrc.dwSize = sizeof(DDSURFACEDESC); - const DWORD dwSrcFlags = DDLOCK_NOSYSLOCK| - DDLOCK_SURFACEMEMORYPTR| - DDLOCK_WAIT| - DDLOCK_READONLY; - if(SUCCEEDED(rSourceSurface.Lock(NULL, - &aDescSrc, - dwSrcFlags, - NULL))) - { - // lock destination surface - DDSURFACEDESC aDescDst; - rtl_fillMemory(&aDescDst,sizeof(DDSURFACEDESC),0); - aDescDst.dwSize = sizeof(DDSURFACEDESC); - const DWORD dwDstFlags = DDLOCK_NOSYSLOCK| - DDLOCK_SURFACEMEMORYPTR| - DDLOCK_WAIT| - DDLOCK_WRITEONLY; - if(SUCCEEDED(rOutSurface.Lock(NULL, - &aDescDst, - dwDstFlags, - NULL))) - { - sal_uInt32 nSrcFormat; - nSrcFormat = ::canvas::tools::bitcount32(aDescSrc.ddpfPixelFormat.dwRGBAlphaBitMask)<<12; - nSrcFormat |= ::canvas::tools::bitcount32(aDescSrc.ddpfPixelFormat.dwRBitMask)<<8; - nSrcFormat |= ::canvas::tools::bitcount32(aDescSrc.ddpfPixelFormat.dwGBitMask)<<4; - nSrcFormat |= ::canvas::tools::bitcount32(aDescSrc.ddpfPixelFormat.dwBBitMask); - - sal_uInt32 nDstFormat; - nDstFormat = ::canvas::tools::bitcount32(aDescDst.ddpfPixelFormat.dwRGBAlphaBitMask)<<12; - nDstFormat |= ::canvas::tools::bitcount32(aDescDst.ddpfPixelFormat.dwRBitMask)<<8; - nDstFormat |= ::canvas::tools::bitcount32(aDescDst.ddpfPixelFormat.dwGBitMask)<<4; - nDstFormat |= ::canvas::tools::bitcount32(aDescDst.ddpfPixelFormat.dwBBitMask); - - // TODO(E1): Use numeric_cast to catch overflow here - const sal_uInt32 nWidth( static_cast<sal_uInt32>( - rSourceArea.getWidth() ) ); - const sal_uInt32 nHeight( static_cast<sal_uInt32>( - rSourceArea.getHeight() ) ); - - if((nSrcFormat == 0x8888) && (nDstFormat == 0x0565)) - { - // medium range 8888 to 0565 pixel format conversion. - bResult = true; - sal_uInt8 *pSrcSurface = (sal_uInt8 *)aDescSrc.lpSurface + - rSourceArea.getMinY()*aDescSrc.lPitch + - (rSourceArea.getMinX()<<2); - sal_uInt8 *pDstSurface = (sal_uInt8 *)aDescDst.lpSurface + - rDestPos.getY()*aDescDst.lPitch + - (rDestPos.getX()<<1); - for(sal_uInt32 y=0; y<nHeight; ++y) - { - sal_uInt32 *pSrcScanline = (sal_uInt32 *)pSrcSurface; - sal_uInt16 *pDstScanline = (sal_uInt16 *)pDstSurface; - for(sal_uInt32 x=0; x<nWidth; ++x) - { - sal_uInt32 srcPixel = *pSrcScanline++; - sal_uInt16 dstPixel; - dstPixel = (sal_uInt16)((srcPixel & 0x0000F8) >> 3); - dstPixel |= (srcPixel & 0x00FC00) >> 5; - dstPixel |= (srcPixel & 0xF80000) >> 8; - *pDstScanline++ = dstPixel; - } - pSrcSurface += aDescSrc.lPitch; - pDstSurface += aDescDst.lPitch; - } - } - else if((nSrcFormat == 0x8888) && (nDstFormat == 0x0888)) - { - // medium range 8888 to 0888 pixel format conversion. - bResult = true; - sal_uInt8 *pSrcSurface = (sal_uInt8 *)aDescSrc.lpSurface + - rSourceArea.getMinY()*aDescSrc.lPitch + - (rSourceArea.getMinX()<<2); - sal_uInt8 *pDstSurface = (sal_uInt8 *)aDescDst.lpSurface + - rDestPos.getY()*aDescDst.lPitch + - (rDestPos.getX()<<2); - for(sal_uInt32 y=0; y<nHeight; ++y) - { - sal_uInt32 *pSrcScanline = (sal_uInt32 *)pSrcSurface; - sal_uInt16 *pDstScanline = (sal_uInt16 *)pDstSurface; - for(sal_uInt32 x=0; x<nWidth; ++x) - { - *pDstScanline++ = (sal_uInt16)*pSrcScanline++; - } - pSrcSurface += aDescSrc.lPitch; - pDstSurface += aDescDst.lPitch; - } - } - else if((nSrcFormat == 0x8888) && (nDstFormat == 0x1555)) - { - // medium range 8888 to 1555 pixel format conversion. - bResult = true; - sal_uInt8 *pSrcSurface = (sal_uInt8 *)aDescSrc.lpSurface + - rSourceArea.getMinY()*aDescSrc.lPitch + - (rSourceArea.getMinX()<<2); - sal_uInt8 *pDstSurface = (sal_uInt8 *)aDescDst.lpSurface + - rDestPos.getY()*aDescDst.lPitch + - (rDestPos.getX()<<1); - for(sal_uInt32 y=0; y<nHeight; ++y) - { - sal_uInt32 *pSrcScanline = (sal_uInt32*)pSrcSurface; - sal_uInt16 *pDstScanline = (sal_uInt16 *)pDstSurface; - for(sal_uInt32 x=0; x<nWidth; ++x) - { - sal_uInt32 srcPixel = *pSrcScanline++; - sal_uInt16 dstPixel; - dstPixel = (sal_uInt16)((srcPixel & 0x000000F8) >> 3); - dstPixel |= (srcPixel & 0x0000F800) >> 6; - dstPixel |= (srcPixel & 0x00F80000) >> 9; - dstPixel |= (srcPixel & 0x80000000) >> 16; - *pDstScanline++ = dstPixel; - } - pSrcSurface += aDescSrc.lPitch; - pDstSurface += aDescDst.lPitch; - } - } - - // unlock destination surface - rOutSurface.Unlock(NULL); - } - - // unlock source surface - rSourceSurface.Unlock(NULL); - } - - return bResult; - } - - void dumpSurface( const COMReference<IDirectDrawSurface> &pSurface, const char *szFilename ) - { - if(!(pSurface.get())) - return; - - DDSURFACEDESC aSurfaceDesc; - rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 ); - aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); - - if( FAILED(pSurface->Lock( NULL, - &aSurfaceDesc, - DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY, - NULL)) ) - return; - - const std::size_t dwBitmapSize(aSurfaceDesc.dwWidth*aSurfaceDesc.dwHeight*4); - sal_uInt8 *pBuffer = static_cast<sal_uInt8 *>(_alloca(dwBitmapSize)); - if(pBuffer) - { - sal_uInt8 *pSource = reinterpret_cast<sal_uInt8 *>(aSurfaceDesc.lpSurface); - sal_uInt8 *pDest = reinterpret_cast<sal_uInt8 *>(pBuffer); - const std::size_t dwDestPitch(aSurfaceDesc.dwWidth<<2); - pDest += aSurfaceDesc.dwHeight*dwDestPitch; - for(sal_uInt32 y=0; y<aSurfaceDesc.dwHeight; ++y) - { - pDest -= dwDestPitch; - rtl_copyMemory( pDest, pSource, dwDestPitch ); - pSource += aSurfaceDesc.lPitch; - } - - if(FILE *fp = fopen(szFilename,"wb")) - { - BITMAPINFOHEADER bitmapInfo; - - bitmapInfo.biSize = sizeof(BITMAPINFOHEADER); - bitmapInfo.biWidth = aSurfaceDesc.dwWidth; - bitmapInfo.biHeight = aSurfaceDesc.dwHeight; - bitmapInfo.biPlanes = 1; - bitmapInfo.biBitCount = 32; - bitmapInfo.biCompression = BI_RGB; - bitmapInfo.biSizeImage = 0; - bitmapInfo.biXPelsPerMeter = 0; - bitmapInfo.biYPelsPerMeter = 0; - bitmapInfo.biClrUsed = 0; - bitmapInfo.biClrImportant = 0; - - const std::size_t dwFileSize(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwBitmapSize); - - BITMAPFILEHEADER header; - header.bfType = 'MB'; - header.bfSize = dwFileSize; - header.bfReserved1 = 0; - header.bfReserved2 = 0; - header.bfOffBits = sizeof(BITMAPFILEHEADER) + bitmapInfo.biSize; - - fwrite(&header,1,sizeof(BITMAPFILEHEADER),fp); - fwrite(&bitmapInfo,1,sizeof(BITMAPINFOHEADER),fp); - fwrite(pBuffer,1,dwBitmapSize,fp); - - fclose(fp); - } - } - - pSurface->Unlock(NULL); - } - - void clearSurface( const COMReference<IDirectDrawSurface>& pSurface ) - { - if(!(pSurface.is())) - return; - - DDBLTFX aBltFx; - - rtl_fillMemory( &aBltFx, - sizeof(DDBLTFX), 0 ); - aBltFx.dwSize = sizeof(DDBLTFX); - aBltFx.dwFillColor = 0; - - pSurface->Blt( NULL, - NULL, - NULL, - DDBLT_COLORFILL | DDBLT_WAIT, - &aBltFx ); - } - - // Define struct for MonitorEntry - struct MonitorEntry - { - GUID mnGUID; - HMONITOR mhMonitor; - MONITORINFO maMonitorInfo; - }; - - // define type for MonitorList - typedef ::std::vector< MonitorEntry > MonitorList; - - // Win32 system callback for DirectDrawEnumerateExA call - BOOL WINAPI EnumerateExA_Callback( GUID FAR* lpGUID, - LPSTR /*lpDriverDescription*/, - LPSTR /*lpDriverName*/, - LPVOID lpContext, - HMONITOR hMonitor ) - { - if(lpGUID) - { - MonitorList* pMonitorList = (MonitorList*)lpContext; - MonitorEntry aEntry; - - aEntry.mnGUID = *lpGUID; - aEntry.mhMonitor = hMonitor; - aEntry.maMonitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo( hMonitor, - &aEntry.maMonitorInfo ); - - pMonitorList->push_back(aEntry); - } - - return DDENUMRET_OK; - } - - void fillMonitorList( MonitorList& rMonitorList ) - { - // Try to fill MonitorList. If neither lib or call to - // DirectDrawEnumerateExA does not exist, it's an old - // DX version (< 5.0), or system does not support - // multiple monitors. - HINSTANCE hInstance = LoadLibrary("ddraw.dll"); - - if(hInstance) - { - LPDIRECTDRAWENUMERATEEX lpDDEnumEx = - (LPDIRECTDRAWENUMERATEEX)GetProcAddress(hInstance,"DirectDrawEnumerateExA"); - - if(lpDDEnumEx) - lpDDEnumEx( (LPDDENUMCALLBACKEXA) EnumerateExA_Callback, - &rMonitorList, - DDENUM_ATTACHEDSECONDARYDEVICES ); - - FreeLibrary(hInstance); - } - } - - IDirectDraw2* createDirectDraw( const MonitorList& rMonitorList, - MONITORINFO& rMonitorInfo, - HWND renderWindow ) - { - GUID* gpSelectedDriverGUID = NULL; - - // if we have multiple monitors, choose a gpSelectedDriverGUID from monitor list - HMONITOR hMonitor = MonitorFromWindow(renderWindow, - MONITOR_DEFAULTTONEAREST); - - MonitorList::const_iterator aCurr = rMonitorList.begin(); - const MonitorList::const_iterator aEnd = rMonitorList.end(); - while( !gpSelectedDriverGUID && aCurr != aEnd ) - { - if(hMonitor == aCurr->mhMonitor) - { - // This is the monitor we are running on - gpSelectedDriverGUID = const_cast<GUID*>(&aCurr->mnGUID); - rMonitorInfo = aCurr->maMonitorInfo; - } - - ++aCurr; - } - - IDirectDraw* pDirectDraw; - if( FAILED( DirectDrawCreate( gpSelectedDriverGUID, &pDirectDraw, NULL ))) - return NULL; - - IDirectDraw2* pDirectDraw2; - if( FAILED( pDirectDraw->QueryInterface( IID_IDirectDraw2, (LPVOID*)&pDirectDraw2 ))) - return NULL; - - // queryInterface bumped up the refcount, so release the - // reference to the original IDirectDraw interface. - pDirectDraw->Release(); - - return pDirectDraw2; - } - - HRESULT WINAPI EnumTextureFormatsCallback( LPDDSURFACEDESC pSurfaceDesc, - LPVOID pContext ) - { - // dirty cast of given context back to result ModeSelectContext - DDPIXELFORMAT* pResult = (DDPIXELFORMAT*)pContext; - - if( pResult == NULL || pSurfaceDesc == NULL ) - return DDENUMRET_CANCEL; - - VERBOSE_TRACE( "EnumTextureFormatsCallback: advertised texture format has dwRGBBitCount %d, dwRBitMask %x, " - "dwGBitMask %x, dwBBitMask %x and dwRGBAlphaBitMask %x. The format uses %s alpha.", - pSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, - pSurfaceDesc->ddpfPixelFormat.dwRBitMask, - pSurfaceDesc->ddpfPixelFormat.dwGBitMask, - pSurfaceDesc->ddpfPixelFormat.dwBBitMask, - pSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask, - pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPREMULT ? "premultiplied" : "non-premultiplied" ); - - // Only accept RGB surfaces with alpha channel - if( (DDPF_ALPHAPIXELS | DDPF_RGB) == - (pSurfaceDesc->ddpfPixelFormat.dwFlags & (DDPF_ALPHAPIXELS | DDPF_RGB)) ) - { - // ignore formats with the DDPF_ALPHAPREMULT flag - if(!(pSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPREMULT)) - { - // take widest alpha channel available - if( pSurfaceDesc->ddpfPixelFormat.dwAlphaBitDepth > pResult->dwAlphaBitDepth ) - { - // take new format - rtl_copyMemory( pResult, &pSurfaceDesc->ddpfPixelFormat, sizeof(DDPIXELFORMAT) ); - } - else if( pSurfaceDesc->ddpfPixelFormat.dwAlphaBitDepth == pResult->dwAlphaBitDepth ) - { - // tie-breaking: take highest bitcount - if( pSurfaceDesc->ddpfPixelFormat.dwRGBBitCount > pResult->dwRGBBitCount ) - { - // take new format - rtl_copyMemory( pResult, &pSurfaceDesc->ddpfPixelFormat, sizeof(DDPIXELFORMAT) ); - } - } - } - } - - return DDENUMRET_OK; - } - - class DXRenderModule; - - ////////////////////////////////////////////////////////////////////////////////// - // DXSurface - ////////////////////////////////////////////////////////////////////////////////// - - /** ISurface implemenation. - - @attention holds the DXRenderModule via non-refcounted - reference! This is safe with current state of affairs, since - the canvas::PageManager holds surface and render module via - shared_ptr (and makes sure all surfaces are deleted before its - render module member goes out of scope). - */ - class DXSurface : public canvas::ISurface - { - public: - DXSurface( DXRenderModule& rRenderModule, - const ::basegfx::B2ISize& rSize ); - ~DXSurface(); - - virtual bool selectTexture(); - virtual bool isValid(); - virtual bool update( const ::basegfx::B2IPoint& rDestPos, - const ::basegfx::B2IRange& rSourceRect, - ::canvas::IColorBuffer& rSource ); - virtual ::basegfx::B2IVector getSize(); - - private: - /// Guard local methods against concurrent acces to RenderModule - class ImplRenderModuleGuard : private ::boost::noncopyable - { - public: - explicit inline ImplRenderModuleGuard( DXRenderModule& rRenderModule ); - inline ~ImplRenderModuleGuard(); - - private: - DXRenderModule& mrRenderModule; - }; - - DXRenderModule& mrRenderModule; - - COMReference<IDirectDrawSurface> mpSurface; - COMReference<IDirect3DTexture2> mpTexture; - - ::basegfx::B2IVector maSize; - }; - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule - ////////////////////////////////////////////////////////////////////////////////// - - /// Default implementation of IDXRenderModule - class DXRenderModule : public IDXRenderModule - { - public: - explicit DXRenderModule( const ::Window& rWindow ); - - virtual void lock() const { maMutex.acquire(); } - virtual void unlock() const { maMutex.release(); } - - virtual COMReference<IDirectDrawSurface> - createSystemMemorySurface( const ::basegfx::B2IVector& rSize ); - - virtual bool flip( const ::basegfx::B2IRectangle& rUpdateArea, - const ::basegfx::B2IRectangle& rCurrWindowArea ); - - virtual void resize( const ::basegfx::B2IRange& rect ); - virtual HWND getHWND() const { return mhWnd; } - virtual void disposing(); - virtual void screenShot(); - virtual ::basegfx::B2IVector getPageSize(); - virtual ::canvas::ISurfaceSharedPtr createSurface( const ::basegfx::B2IVector& surfaceSize ); - virtual void beginPrimitive( PrimitiveType eType ); - virtual void endPrimitive(); - virtual void pushVertex( const ::canvas::Vertex& vertex ); - virtual bool isError(); - - const D3DDEVICEDESC& getDeviceDesc() const { return maDeviceDesc; } - const DDPIXELFORMAT& getTextureFormat() const { return maTextureFormat; } - COMReference<IDirectDraw2> getDirectDraw() { return mpDirectDraw; } - COMReference< IDirect3DDevice2 > getDevice() { return mpDirect3DDevice; } - - void flushVertexCache(); - - struct ModeSelectContext - { - DDSURFACEDESC selectedDesc; - ::basegfx::B2ISize requestedSize; - }; - - /** Query actual size of the device - - This is especially interesting for fullscreen devices - */ - ::basegfx::B2ISize getFramebufferSize() const; - - /** Query the amount of memory available for new surfaces - - This might differ from getAvailableTextureMem() - @see getAvailableTextureMem() - - @param bWithAGPMema - When true, returned value includes non-local, - i.e. AGP-able memory, too. - - @return the amount of free surface mem - */ - std::size_t getAvailableSurfaceMem( bool bWithAGPMem=true ) const; - - /** Query the amount of memory available for new textures - - This might differ from getAvailableSurfaceMem() - @see getAvailableSurfaceMem() - - @param bWithAGPMema - When true, returned value includes non-local, - i.e. AGP-able memory, too. - - @return the amount of free texture mem - */ - std::size_t getAvailableTextureMem( bool bWithAGPMem=true ) const; - - private: - bool queryCaps(); - bool validateCaps(); - bool setup3DDevice(); - unsigned int getDisplayFormat() const; - - void convert2Screen( ::basegfx::B2IPoint& io_rDestPos, - ::basegfx::B2IRange& io_rDestArea ); - - void renderInfoText( const ::rtl::OUString& rStr, - const Gdiplus::PointF& rPos ) const; - void renderFPSCounter() const; - void renderMemAvailable() const; - - bool create( const ::Window& rWindow ); - bool validateMainSurfaces(); - - /** This object represents the DirectX state machine. In order - to serialize access to DirectX's global state, a global - mutex is required. - */ - static ::osl::Mutex maMutex; - - HWND mhWnd; - ::boost::scoped_ptr<SystemChildWindow> mpWindow; - ::basegfx::B2IVector maSize; - - ModeSelectContext maSelectedFullscreenMode; - DDPIXELFORMAT maTextureFormat; - - MONITORINFO maMonitorInfo; // monitor info for mpDirectDraw's monitor - COMReference<IDirectDraw2> mpDirectDraw; - COMReference<IDirectDrawSurface> mpPrimarySurface; - COMReference<IDirectDrawSurface> mpBackBufferSurface; - - COMReference< IDirect3D2 > mpDirect3D; - COMReference< IDirect3DDevice2 > mpDirect3DDevice; - - mutable ::canvas::tools::ElapsedTime maLastUpdate; // for the frame counter - - D3DDEVICEDESC maDeviceDesc; - - typedef std::vector<canvas::Vertex> vertexCache_t; - vertexCache_t maVertexCache; - std::size_t mnCount; - - int mnBeginSceneCount; - - const bool mbPageFlipping; - bool mbHasNoTearingBlt; - bool mbError; - PrimitiveType meType; - - ::canvas::ISurfaceSharedPtr mpTexture; - ::basegfx::B2IVector maPageSize; - }; - - ::osl::Mutex DXRenderModule::maMutex; - - ////////////////////////////////////////////////////////////////////////////////// - // DXSurface::ImplRenderModuleGuard - ////////////////////////////////////////////////////////////////////////////////// - - inline DXSurface::ImplRenderModuleGuard::ImplRenderModuleGuard( - DXRenderModule& rRenderModule ) : - mrRenderModule( rRenderModule ) - { - mrRenderModule.lock(); - } - - inline DXSurface::ImplRenderModuleGuard::~ImplRenderModuleGuard() - { - mrRenderModule.unlock(); - } - -#ifdef FAKE_MAX_NUMBER_TEXTURES - static sal_uInt32 gNumSurfaces = 0; -#endif - - void fillRect( sal_uInt32 *pDest, - sal_uInt32 dwWidth, - sal_uInt32 dwHeight, - sal_uInt32 dwPitch, - sal_uInt32 dwColor ) - { - for(sal_uInt32 i=0; i<dwWidth; ++i) - { - pDest[i]=dwColor; - pDest[((dwHeight-1)*dwPitch)+i]=dwColor; - } - - for(sal_uInt32 j=0; j<dwHeight; ++j) - { - pDest[0]=dwColor; - pDest[dwWidth-1]=dwColor; - pDest += dwPitch; - } - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXSurface::DXSurface - ////////////////////////////////////////////////////////////////////////////////// - - DXSurface::DXSurface( DXRenderModule& rRenderModule, - const ::basegfx::B2ISize& rSize ) : - mrRenderModule(rRenderModule), - mpTexture(NULL), - mpSurface(NULL), - maSize() - { - ImplRenderModuleGuard aGuard( mrRenderModule ); - -#ifdef FAKE_MAX_NUMBER_TEXTURES - ++gNumSurfaces; - if(gNumSurfaces >= FAKE_MAX_NUMBER_TEXTURES) - return; -#endif - -#ifdef FAKE_MAX_TEXTURE_SIZE - if(rSize.getX() > FAKE_MAX_TEXTURE_SIZE) - return; - if(rSize.getY() > FAKE_MAX_TEXTURE_SIZE) - return; -#endif - - ENSURE_ARG_OR_THROW(rSize.getX() > 0 && rSize.getY() > 0, - "DXSurface::DXSurface(): request for zero-sized surface"); - - const D3DDEVICEDESC &deviceDesc = rRenderModule.getDeviceDesc(); - - DDSURFACEDESC aSurfaceDesc; - rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 ); - aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); - aSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; - aSurfaceDesc.dwWidth = ::std::min(deviceDesc.dwMaxTextureWidth,::canvas::tools::nextPow2(rSize.getX())); - aSurfaceDesc.dwHeight = ::std::min(deviceDesc.dwMaxTextureHeight,::canvas::tools::nextPow2(rSize.getY())); - aSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | - DDSCAPS_VIDEOMEMORY | - DDSCAPS_LOCALVIDMEM; - rtl_copyMemory(&aSurfaceDesc.ddpfPixelFormat,&rRenderModule.getTextureFormat(),sizeof(DDPIXELFORMAT)); - - IDirectDrawSurface *pSurface; - COMReference<IDirectDraw2> pDirectDraw(rRenderModule.getDirectDraw()); - HRESULT hr = pDirectDraw->CreateSurface(&aSurfaceDesc, &pSurface, NULL); - if(FAILED(hr)) - { - // if the call failed due to 'out of videomemory', - // retry with request for AGP memory. - if(DDERR_OUTOFVIDEOMEMORY == hr) - { - aSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | - DDSCAPS_VIDEOMEMORY | - DDSCAPS_NONLOCALVIDMEM; - hr = pDirectDraw->CreateSurface(&aSurfaceDesc, &pSurface, NULL); - } - } - - if(SUCCEEDED(hr)) - { - IDirect3DTexture2* pTexture; - if( FAILED(pSurface->QueryInterface(IID_IDirect3DTexture2, (LPVOID *)&pTexture)) ) - { - pSurface->Release(); - return; - } - - maSize.setX(aSurfaceDesc.dwWidth); - maSize.setY(aSurfaceDesc.dwHeight); - - mpSurface=COMReference<IDirectDrawSurface>(pSurface); - mpTexture=COMReference<IDirect3DTexture2>(pTexture); - - // #122683# Clear texture, to avoid ugly artifacts at the - // border to invisible sprite areas (note that the textures - // are usually only partly utilized). - clearSurface( mpSurface ); - } - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXSurface::~DXSurface - ////////////////////////////////////////////////////////////////////////////////// - - DXSurface::~DXSurface() - { - ImplRenderModuleGuard aGuard( mrRenderModule ); - -#ifdef FAKE_MAX_NUMBER_TEXTURES - gNumSurfaces--; -#endif - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXSurface::selectTexture - ////////////////////////////////////////////////////////////////////////////////// - - bool DXSurface::selectTexture() - { - ImplRenderModuleGuard aGuard( mrRenderModule ); - - mrRenderModule.flushVertexCache(); - - D3DTEXTUREHANDLE aTextureHandle; - if(FAILED(mpTexture->GetHandle( - mrRenderModule.getDevice().get(), - &aTextureHandle))) - { - return false; - } - - // select texture for next primitive - if(FAILED(mrRenderModule.getDevice()->SetRenderState( - D3DRENDERSTATE_TEXTUREHANDLE,aTextureHandle))) - { - return false; - } - -#if defined(DX_DEBUG_IMAGES) -# if OSL_DEBUG_LEVEL > 0 - if( mpSurface.is() ) - { - DDSURFACEDESC aSurfaceDesc; - rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 ); - aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); - - if( SUCCEEDED(mpSurface->Lock( NULL, - &aSurfaceDesc, - DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY, - NULL)) ) - { - imdebug( "rgba w=%d h=%d %p", - aSurfaceDesc.dwWidth, - aSurfaceDesc.dwHeight, - aSurfaceDesc.lpSurface ); - - mpSurface->Unlock(NULL); - } - } -# endif -#endif - - return true; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXSurface::isValid - ////////////////////////////////////////////////////////////////////////////////// - - bool DXSurface::isValid() - { - ImplRenderModuleGuard aGuard( mrRenderModule ); - - if(!(mpSurface.is())) - return false; - - if(mpSurface->IsLost() == DDERR_SURFACELOST) - { - mpSurface->Restore(); - return false; - } - - return true; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXSurface::update - ////////////////////////////////////////////////////////////////////////////////// - - bool DXSurface::update( const ::basegfx::B2IPoint& rDestPos, - const ::basegfx::B2IRange& rSourceRect, - ::canvas::IColorBuffer& rSource ) - { - ImplRenderModuleGuard aGuard( mrRenderModule ); - - // can't update if surface is not valid, that means - // either not existent nor restored... - if(!(isValid())) - return false; - - DDSURFACEDESC aSurfaceDesc; - rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 ); - aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); - - // TODO(P2): only lock the region we want to update - if( FAILED(mpSurface->Lock( NULL, - &aSurfaceDesc, - DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY, - NULL)) ) - return false; - - if(sal_uInt8* pImage = rSource.lock()) - { - switch( rSource.getFormat() ) - { - case ::canvas::IColorBuffer::FMT_A8R8G8B8: - { - const std::size_t nSourceBytesPerPixel(4); - const std::size_t nSourcePitchInBytes(rSource.getStride()); - pImage += rSourceRect.getMinY()*nSourcePitchInBytes; - pImage += rSourceRect.getMinX()*nSourceBytesPerPixel; - - // calculate the destination memory address - sal_uInt8 *pDst = ((sal_uInt8*)aSurfaceDesc.lpSurface+ - (rDestPos.getY()*aSurfaceDesc.lPitch) + - (4*rDestPos.getX())); - - const sal_uInt32 nNumBytesToCopy( - static_cast<sal_uInt32>( - rSourceRect.getWidth())* - nSourceBytesPerPixel); - const sal_uInt64 nNumLines(rSourceRect.getHeight()); - - for(sal_uInt32 i=0; i<nNumLines; ++i) - { - rtl_copyMemory(pDst,pImage,nNumBytesToCopy); - - pDst += aSurfaceDesc.lPitch; - pImage += nSourcePitchInBytes; - } - } - break; - - case ::canvas::IColorBuffer::FMT_R8G8B8: - { - const std::size_t nSourceBytesPerPixel(3); - const std::size_t nSourcePitchInBytes(rSource.getStride()); - pImage += rSourceRect.getMinY()*nSourcePitchInBytes; - pImage += rSourceRect.getMinX()*nSourceBytesPerPixel; - - // calculate the destination memory address - sal_uInt8 *pDst = ((sal_uInt8*)aSurfaceDesc.lpSurface+ - (rDestPos.getY()*aSurfaceDesc.lPitch) + - (4*rDestPos.getX())); - - const sal_uInt64 nNumColumns(rSourceRect.getWidth()); - const sal_uInt64 nNumLines(rSourceRect.getHeight()); - for(sal_uInt32 i=0; i<nNumLines; ++i) - { - sal_uInt32 *pDstScanline = reinterpret_cast<sal_uInt32 *>(pDst); - sal_uInt8 *pSrcScanline = reinterpret_cast<sal_uInt8 *>(pImage); - for(sal_uInt32 x=0; x<nNumColumns; ++x) - { - sal_uInt32 color(0xFF000000); - color |= pSrcScanline[2]<<16; - color |= pSrcScanline[1]<<8; - color |= pSrcScanline[0]; - pSrcScanline += 3; - *pDstScanline++ = color; - } - - pDst += aSurfaceDesc.lPitch; - pImage += nSourcePitchInBytes; - } - } - break; - - case ::canvas::IColorBuffer::FMT_X8R8G8B8: - { - const std::size_t nSourceBytesPerPixel(4); - const std::size_t nSourcePitchInBytes(rSource.getStride()); - pImage += rSourceRect.getMinY()*nSourcePitchInBytes; - pImage += rSourceRect.getMinX()*nSourceBytesPerPixel; - - // calculate the destination memory address - sal_uInt8 *pDst = ((sal_uInt8*)aSurfaceDesc.lpSurface+ - (rDestPos.getY()*aSurfaceDesc.lPitch) + - (4*rDestPos.getX())); - - const sal_uInt64 nNumLines(rSourceRect.getHeight()); - - for(sal_uInt32 i=0; i<nNumLines; ++i) - { - sal_uInt32 *pSrc32 = reinterpret_cast<sal_uInt32 *>(pImage); - sal_uInt32 *pDst32 = reinterpret_cast<sal_uInt32 *>(pDst); - for(sal_uInt32 j=0; j<rSourceRect.getWidth(); ++j) - pDst32[j] = 0xFF000000 | pSrc32[j]; - - pDst += aSurfaceDesc.lPitch; - pImage += nSourcePitchInBytes; - } - } - break; - - default: - ENSURE_OR_RETURN_FALSE(false, - "DXSurface::update(): Unknown/unimplemented buffer format" ); - break; - } - - rSource.unlock(); - } - - return SUCCEEDED(mpSurface->Unlock(NULL)); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXSurface::getSize - ////////////////////////////////////////////////////////////////////////////////// - - ::basegfx::B2IVector DXSurface::getSize() - { - return maSize; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::DXRenderModule - ////////////////////////////////////////////////////////////////////////////////// - - DXRenderModule::DXRenderModule( const ::Window& rWindow ) : - mhWnd(0), - mpWindow(), - maSize(), - maSelectedFullscreenMode(), - maTextureFormat(), - maMonitorInfo(), - mpDirectDraw(), - mpPrimarySurface(), - mpBackBufferSurface(), - mpDirect3D(), - mpDirect3DDevice(), - maLastUpdate(), - maDeviceDesc(), - maVertexCache(), - mnCount(0), - mnBeginSceneCount(0), - mbPageFlipping( false ), - mbHasNoTearingBlt( false ), - mbError( false ), - meType( PRIMITIVE_TYPE_UNKNOWN ), - mpTexture(), - maPageSize() - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - if(!(create(rWindow))) - { - throw lang::NoSupportException( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( - "Could not create DirectX device!") ),NULL); - } - - // allocate a single texture surface which can be used later. - // we also use this to calibrate the page size. - ::basegfx::B2IVector aPageSize( - ::std::min( - static_cast<sal_uInt32>(maDeviceDesc.dwMaxTextureWidth), - static_cast<sal_uInt32>(MAX_TEXTURE_SIZE)), - ::std::min( - static_cast<sal_uInt32>(maDeviceDesc.dwMaxTextureHeight), - static_cast<sal_uInt32>(MAX_TEXTURE_SIZE))); - while(true) - { - mpTexture = ::canvas::ISurfaceSharedPtr( - new DXSurface(*this,aPageSize)); - if(mpTexture->isValid()) - break; - - aPageSize.setX(aPageSize.getX()>>1); - aPageSize.setY(aPageSize.getY()>>1); - if((aPageSize.getX() < MIN_TEXTURE_SIZE) || - (aPageSize.getY() < MIN_TEXTURE_SIZE)) - { - throw lang::NoSupportException( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( - "Could not create DirectX device!") ),NULL); - } - } - maPageSize=aPageSize; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::create - ////////////////////////////////////////////////////////////////////////////////// - - bool DXRenderModule::create( const ::Window& rWindow ) - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - maVertexCache.reserve(1024); - - mpWindow.reset( - new SystemChildWindow( - const_cast<Window *>(&rWindow), 0) ); - - // system child window must not receive mouse events - mpWindow->SetMouseTransparent( sal_True ); - - // parent should receive paint messages as well - // [PARENTCLIPMODE_NOCLIP], the argument is here - // passed as plain numeric value since the stupid - // define utilizes a USHORT cast. - mpWindow->SetParentClipMode(0x0002); - - // the system child window must not clear its background - mpWindow->EnableEraseBackground( sal_False ); - - mpWindow->SetControlForeground(); - mpWindow->SetControlBackground(); - mpWindow->EnablePaint(sal_False); - - const SystemEnvData *pData = mpWindow->GetSystemData(); - const HWND hwnd(reinterpret_cast<HWND>(pData->hWnd)); - mhWnd = const_cast<HWND>(hwnd); - - ENSURE_OR_THROW( IsWindow( reinterpret_cast<HWND>(mhWnd) ), - "DXRenderModuleDXRenderModuleWin32() No valid HWND given." ); - - // retrieve position and size of the parent window - const ::Size &rSizePixel(rWindow.GetSizePixel()); - - // remember the size of the parent window, since we - // need to use this for our child window. - maSize.setX(static_cast<sal_Int32>(rSizePixel.Width())); - maSize.setY(static_cast<sal_Int32>(rSizePixel.Height())); - - // let the child window cover the same size as the parent window. - mpWindow->SetPosSizePixel(0,0,maSize.getX(),maSize.getY()); - - MonitorList aMonitorList; - fillMonitorList( aMonitorList ); - - mpDirectDraw = COMReference<IDirectDraw2>( - createDirectDraw(aMonitorList, maMonitorInfo, mhWnd)); - - if(!mpDirectDraw.is()) - return false; - - if( !queryCaps() ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): GetCaps failed" ); - mpDirectDraw.reset(); - return false; - } - - if( !validateCaps() ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): Insufficient DirectX capabilities, failed" ); - mpDirectDraw.reset(); - return false; - } - - if( FAILED( mpDirectDraw->SetCooperativeLevel( mhWnd, - DDSCL_NORMAL|DDSCL_MULTITHREADED|DDSCL_FPUPRESERVE ) ) ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): SetCooperativeLevel failed" ); - mpDirectDraw.reset(); - return false; - } - - // setup query struct - rtl_fillMemory( &maSelectedFullscreenMode.selectedDesc, - sizeof(DDSURFACEDESC), 0 ); - maSelectedFullscreenMode.selectedDesc.dwSize = sizeof(DDSURFACEDESC); - - // read current display mode, e.g. for screen dimension - if( FAILED( mpDirectDraw->GetDisplayMode( &maSelectedFullscreenMode.selectedDesc )) ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): GetDisplayMode failed" ); - mpDirectDraw.reset(); - return false; - } - - // check for supported primary surface formats... - unsigned int nDisplayFormat = getDisplayFormat() & 0x00000FFF; - if(nDisplayFormat != 0x888 && nDisplayFormat != 0x565) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): Unsupported DisplayFormat" ); - mpDirectDraw.reset(); - return false; - } - - // create primary surface reference - DDSURFACEDESC aSurfaceDesc; - IDirectDrawSurface* pPrimarySurface; - - rtl_fillMemory( &aSurfaceDesc, - sizeof(DDSURFACEDESC), 0 ); - aSurfaceDesc.dwSize = sizeof(aSurfaceDesc); - aSurfaceDesc.dwFlags = DDSD_CAPS; - aSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE; - - if( FAILED(mpDirectDraw->CreateSurface(&aSurfaceDesc, &pPrimarySurface, NULL)) ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): CreateSurface failed" ); - mpDirectDraw.reset(); - return false; - } - - mpPrimarySurface = COMReference< IDirectDrawSurface >(pPrimarySurface); - - // create a Clipper and associate it with the primary surface - // and the render window - LPDIRECTDRAWCLIPPER pClipper; - if( FAILED(mpDirectDraw->CreateClipper( 0, &pClipper, NULL )) ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): CreateClipper failed" ); - mpPrimarySurface.reset(); - mpDirectDraw.reset(); - return false; - } - if( FAILED(pClipper->SetHWnd(0, mhWnd)) ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): Clipper->SetHWnd failed" ); - pClipper->Release(); - mpPrimarySurface.reset(); - mpDirectDraw.reset(); - return false; - } - if( FAILED(mpPrimarySurface->SetClipper( pClipper )) ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): SetClipper failed" ); - pClipper->Release(); - mpPrimarySurface.reset(); - mpDirectDraw.reset(); - return false; - } - - // clipper is now owned by mpPrimarySurface, release our reference - pClipper->Release(); - - // TODO(F3): Check whether palette needs any setup here - - // get us a backbuffer for simulated flipping - IDirectDrawSurface* pSurface; - - // Strictly speaking, we don't need a full screen worth of - // backbuffer here. We could also scale dynamically with - // the current window size, but this will make it - // necessary to temporarily have two buffers while copying - // from the old to the new one. What's more, at the time - // we need a larger buffer, DX might not have sufficient - // resources available, and we're then left with too small - // a back buffer, and no way of falling back to a - // different canvas implementation. - const ::basegfx::B2ISize aSize( getFramebufferSize() ); - - rtl_fillMemory( &aSurfaceDesc, - sizeof(DDSURFACEDESC), 0 ); - aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); - aSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - aSurfaceDesc.dwHeight= aSize.getY(); - aSurfaceDesc.dwWidth = aSize.getX(); - - aSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; - - HRESULT nRes = mpDirectDraw->CreateSurface(&aSurfaceDesc, &pSurface, NULL); - - if( FAILED( nRes ) ) - { - if( nRes == DDERR_OUTOFVIDEOMEMORY ) - { - // local vid mem failed. Maybe AGP mem works? - aSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM; - if( FAILED(mpDirectDraw->CreateSurface(&aSurfaceDesc, &pSurface, NULL)) ) - { - // no chance, go defunct, and exit - VERBOSE_TRACE( "Device::Device(): CreateSurface for backbuffer failed" ); - mpPrimarySurface.reset(); - mpDirectDraw.reset(); - return false; - } - - VERBOSE_TRACE( "Device::Device(): CreateSurface for backbuffer reverted to non-local video mem" ); - } - else - { - // no chance, go defunct, and exit - VERBOSE_TRACE( "Device::Device(): CreateSurface for backbuffer failed" ); - mpPrimarySurface.reset(); - mpDirectDraw.reset(); - return false; - } - } - - VERBOSE_TRACE( "Device::Device(): created backbuffer of size %d times %d pixel", - aSurfaceDesc.dwWidth, - aSurfaceDesc.dwHeight ); - - mpBackBufferSurface = COMReference< IDirectDrawSurface >(pSurface); - clearSurface(mpBackBufferSurface); - - if( !setup3DDevice() ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::Device(): setup3DDevice failed" ); - mpBackBufferSurface.reset(); - mpPrimarySurface.reset(); - mpDirectDraw.reset(); - return false; - } - - mpWindow->Show(); - - return true; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::getSize - ////////////////////////////////////////////////////////////////////////////////// - - ::basegfx::B2ISize DXRenderModule::getFramebufferSize() const - { - return mpDirectDraw.is() ? - ::basegfx::B2ISize( maSelectedFullscreenMode.selectedDesc.dwWidth, - maSelectedFullscreenMode.selectedDesc.dwHeight ) : - ::basegfx::B2ISize(); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::setup3DDevice - ////////////////////////////////////////////////////////////////////////////////// - - bool DXRenderModule::setup3DDevice() - { - // create and setup 3D device - // ========================== - LPDIRECT3D2 pDirect3D; - if( FAILED( mpDirectDraw->QueryInterface( IID_IDirect3D2, (LPVOID*)&pDirect3D ) ) ) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::setup3DDevice(): QueryInterface() for Direct3D failed" ); - return false; - } - - mpDirect3D = COMReference< IDirect3D2 >(pDirect3D); - - LPDIRECT3DDEVICE2 pDirect3DDevice; - // try HW-accelerated device first - if( FAILED(mpDirect3D->CreateDevice( IID_IDirect3DHALDevice, - mpBackBufferSurface.get(), - &pDirect3DDevice )) ) - { - // no HW 3D support - go defunct, and exit - VERBOSE_TRACE( "Device::setup3DDevice(): CreateDevice() for HW Direct3D rendering failed" ); - mpDirect3D.reset(); - return false; - } - - D3DDEVICEDESC aHELDeviceDesc; - rtl_fillMemory(&maDeviceDesc,sizeof(maDeviceDesc),0); - rtl_fillMemory(&aHELDeviceDesc,sizeof(aHELDeviceDesc),0); - maDeviceDesc.dwSize = sizeof(maDeviceDesc); - aHELDeviceDesc.dwSize = sizeof(aHELDeviceDesc); - if(FAILED(pDirect3DDevice->GetCaps(&maDeviceDesc,&aHELDeviceDesc))) - { - // go defunct, and exit - VERBOSE_TRACE( "Device::setup3DDevice(): GetCaps() for Direct3DDevice failed" ); - mpDirect3D.reset(); - return false; - } - - mpDirect3DDevice = COMReference< IDirect3DDevice2 >(pDirect3DDevice); - - // select appropriate texture format (_need_ alpha channel here) - rtl_fillMemory( &maTextureFormat, - sizeof(DDPIXELFORMAT), 0 ); - maTextureFormat.dwSize = sizeof(DDPIXELFORMAT); - if( SUCCEEDED(mpDirect3DDevice->EnumTextureFormats( EnumTextureFormatsCallback, &maTextureFormat )) ) - { - bool bSupportedFormat = true; - if((maTextureFormat.dwFlags & (DDPF_ALPHAPIXELS | DDPF_RGB)) != (DDPF_ALPHAPIXELS | DDPF_RGB)) - bSupportedFormat = false; - else if(maTextureFormat.dwRGBAlphaBitMask != 0xFF000000) - bSupportedFormat = false; - else if(maTextureFormat.dwRBitMask != 0x00FF0000) - bSupportedFormat = false; - else if(maTextureFormat.dwGBitMask != 0x0000FF00) - bSupportedFormat = false; - else if(maTextureFormat.dwBBitMask != 0x000000FF) - bSupportedFormat = false; - - if(bSupportedFormat) - { - VERBOSE_TRACE( "Device::setup3DDevice(): chose texture format dwRGBBitCount %d, dwRBitMask %x, " - "dwGBitMask %x, dwBBitMask %x and dwRGBAlphaBitMask %x. The texture uses %s alpha.", - maTextureFormat.dwRGBBitCount, - maTextureFormat.dwRBitMask, - maTextureFormat.dwGBitMask, - maTextureFormat.dwBBitMask, - maTextureFormat.dwRGBAlphaBitMask, - maTextureFormat.dwFlags & DDPF_ALPHAPREMULT ? "premultiplied" : "non-premultiplied" ); - - // setup the device (with as much as we can possibly do here) - // ========================================================== - - LPDIRECT3DVIEWPORT2 pViewport; - - if( SUCCEEDED(mpDirect3D->CreateViewport( &pViewport, NULL )) ) - { - if( SUCCEEDED(mpDirect3DDevice->AddViewport( pViewport )) ) - { - // setup viewport (to whole backbuffer) - D3DVIEWPORT2 aViewport; - - aViewport.dwSize = sizeof(D3DVIEWPORT2); - aViewport.dwX = 0; - aViewport.dwY = 0; - aViewport.dwWidth = maSelectedFullscreenMode.selectedDesc.dwWidth; - aViewport.dwHeight = maSelectedFullscreenMode.selectedDesc.dwHeight; - aViewport.dvClipX = -1.0; - aViewport.dvClipY = -1.0; - aViewport.dvClipWidth = 2.0; - aViewport.dvClipHeight = 2.0; - aViewport.dvMinZ = 0.0; - aViewport.dvMaxZ = 1.0; - - if( SUCCEEDED(pViewport->SetViewport2( &aViewport )) ) - { - if( SUCCEEDED(mpDirect3DDevice->SetCurrentViewport( pViewport )) ) - { - // Viewport was handed over to 3DDevice, thus we can release now - pViewport->Release(); - - // currently, no need for any - // matrix or light source - // setup, since we only render - // transformed&lighted - // vertices - - // done; successfully - return true; - } - else - { - VERBOSE_TRACE( "Device::setup3DDevice(): SetCurrentViewport failed" ); - } - } - else - { - VERBOSE_TRACE( "Device::setup3DDevice(): SetViewport2 failed" ); - } - } - else - { - VERBOSE_TRACE( "Device::setup3DDevice(): AddViewport failed" ); - } - - pViewport->Release(); - } - else - { - VERBOSE_TRACE( "Device::setup3DDevice(): CreateViewport failed" ); - } - } - else - { - VERBOSE_TRACE( "Device::setup3DDevice(): No supported pixelformat" ); - } - } - else - { - VERBOSE_TRACE( "Device::setup3DDevice(): EnumTextureFormats failed" ); - } - - // go defunct, and exit - mpDirect3DDevice.reset(); - mpDirect3D.reset(); - - return false; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::queryCaps - ////////////////////////////////////////////////////////////////////////////////// - - bool DXRenderModule::queryCaps() - { - DDCAPS aHWCaps; - DDCAPS aHELCaps; - - rtl_fillMemory( &aHWCaps, - sizeof(aHWCaps), 0 ); - rtl_fillMemory( &aHELCaps, - sizeof(aHELCaps), 0 ); - aHWCaps.dwSize = sizeof( aHWCaps ); - aHELCaps.dwSize = sizeof( aHELCaps ); - - if( FAILED( mpDirectDraw->GetCaps( &aHWCaps, - &aHELCaps ) ) ) - { - return false; - } - - mbHasNoTearingBlt = aHWCaps.dwFXCaps & DDBLTFX_NOTEARING; - - VERBOSE_TRACE( "dxcanvas initialization: %d bytes VRAM free for surfaces (%d with AGP mem), " - "%d bytes VRAM free for textures (%d with AGP mem)", - getAvailableSurfaceMem( false ), - getAvailableSurfaceMem( true ), - getAvailableTextureMem( false ), - getAvailableTextureMem( true ) ); - - return true; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::validateCaps - ////////////////////////////////////////////////////////////////////////////////// - - bool DXRenderModule::validateCaps() - { - // TODO(E3): Validate HW capabilities. Depending on primary - // surface size, reject HW e.g. on the grounds of insufficient - // VRAM. - - // setup query struct - DDSURFACEDESC desc; - rtl_fillMemory(&desc,sizeof(DDSURFACEDESC),0); - desc.dwSize = sizeof(DDSURFACEDESC); - - // read current display mode, e.g. for screen dimension - if(FAILED( mpDirectDraw->GetDisplayMode(&desc))) - return false; - - // simple heuristic: we need at least 3 times the desktop - // resolution based on ARGB color values... - std::size_t nMinimumVRAMSize = ((desc.dwWidth*desc.dwHeight)<<2)*3; - if(getAvailableSurfaceMem() < nMinimumVRAMSize) - return false; - - return true; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::getDisplayFormat - ////////////////////////////////////////////////////////////////////////////////// - - unsigned int DXRenderModule::getDisplayFormat() const - { - unsigned int nFormat; - nFormat = ::canvas::tools::bitcount32(maSelectedFullscreenMode.selectedDesc.ddpfPixelFormat.dwRGBAlphaBitMask)<<12; - nFormat |= ::canvas::tools::bitcount32(maSelectedFullscreenMode.selectedDesc.ddpfPixelFormat.dwRBitMask)<<8; - nFormat |= ::canvas::tools::bitcount32(maSelectedFullscreenMode.selectedDesc.ddpfPixelFormat.dwGBitMask)<<4; - nFormat |= ::canvas::tools::bitcount32(maSelectedFullscreenMode.selectedDesc.ddpfPixelFormat.dwBBitMask); - return nFormat; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::getAvailableSurfaceMem - ////////////////////////////////////////////////////////////////////////////////// - - std::size_t DXRenderModule::getAvailableSurfaceMem( bool bWithAGPMem ) const - { - if( !mpDirectDraw.is() ) - return 0; - - std::size_t nRes( 0 ); - - DDSCAPS aSurfaceCaps; - DWORD nTotal, nFree; - - // real VRAM (const_cast, since GetAvailableVidMem is non-const) - aSurfaceCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; - if( FAILED(const_cast<IDirectDraw2&>(*mpDirectDraw).GetAvailableVidMem( &aSurfaceCaps, &nTotal, &nFree )) ) - return 0; - - nRes += nFree; - - if( bWithAGPMem ) - { - // AGP RAM (const_cast, since GetAvailableVidMem is non-const) - aSurfaceCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM; - if( FAILED(const_cast<IDirectDraw2&>(*mpDirectDraw).GetAvailableVidMem( &aSurfaceCaps, &nTotal, &nFree )) ) - return 0; - - nRes += nFree; - } - - return nRes; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::getAvailableTextureMem - ////////////////////////////////////////////////////////////////////////////////// - - std::size_t DXRenderModule::getAvailableTextureMem( bool bWithAGPMem ) const - { - if( !mpDirectDraw.is() ) - return 0; - - std::size_t nRes( 0 ); - - DDSCAPS aSurfaceCaps; - DWORD nTotal, nFree; - - // TODO(F1): Check if flags are applicable - - // real VRAM (const_cast, since GetAvailableVidMem is non-const) - aSurfaceCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; - if( FAILED(const_cast<IDirectDraw2&>(*mpDirectDraw).GetAvailableVidMem( &aSurfaceCaps, &nTotal, &nFree )) ) - return 0; - - nRes += nFree; - - if( bWithAGPMem ) - { - // AGP RAM (const_cast, since GetAvailableVidMem is non-const) - aSurfaceCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM; - if( FAILED(const_cast<IDirectDraw2&>(*mpDirectDraw).GetAvailableVidMem( &aSurfaceCaps, &nTotal, &nFree )) ) - return 0; - - nRes += nFree; - } - - // TODO(F1): Add pool mem - - return nRes; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::convert2Screen - ////////////////////////////////////////////////////////////////////////////////// - - void DXRenderModule::convert2Screen( ::basegfx::B2IPoint& io_rDestPos, - ::basegfx::B2IRange& io_rDestArea ) - { - POINT aPoint = { 0, 0 }; - ClientToScreen( mhWnd, &aPoint ); - - // i52230 make sure given screen coordinate is relative to - // this monitor's area (the device rendering is always - // contained to a single monitor) - aPoint.x -= maMonitorInfo.rcMonitor.left; - aPoint.y -= maMonitorInfo.rcMonitor.top; - - io_rDestPos.setX( io_rDestPos.getX() + aPoint.x ); - io_rDestPos.setY( io_rDestPos.getY() + aPoint.y ); - - const ::basegfx::B2ISize& rSize( getFramebufferSize() ); - - // calc output bounds (clip against framebuffer bounds) - io_rDestArea = ::basegfx::B2IRange( - ::std::max( sal_Int32(0), - ::std::min( sal_Int32(rSize.getX()), - sal_Int32(io_rDestArea.getMinX() + aPoint.x) ) ), - ::std::max( sal_Int32(0), - ::std::min( sal_Int32(rSize.getY()), - sal_Int32(io_rDestArea.getMinY() + aPoint.y) ) ), - ::std::max( sal_Int32(0), - ::std::min( sal_Int32(rSize.getX()), - sal_Int32(io_rDestArea.getMaxX() + aPoint.x) ) ), - ::std::max( sal_Int32(0), - ::std::min( sal_Int32(rSize.getY()), - sal_Int32(io_rDestArea.getMaxY() + aPoint.y) ) ) ); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::createSystemMemorySurface - ////////////////////////////////////////////////////////////////////////////////// - - COMReference<IDirectDrawSurface> DXRenderModule::createSystemMemorySurface( const ::basegfx::B2IVector& rSize ) - { - DDSURFACEDESC aSurfaceDesc; - IDirectDrawSurface* pSurface; - - aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); - aSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;; - aSurfaceDesc.dwWidth = rSize.getX(); - aSurfaceDesc.dwHeight= rSize.getY(); - - rtl_copyMemory( &aSurfaceDesc.ddpfPixelFormat, &maTextureFormat, sizeof(DDPIXELFORMAT) ); - - aSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - - HRESULT nRes = mpDirectDraw->CreateSurface(&aSurfaceDesc, &pSurface, NULL); - if(FAILED(nRes)) - return COMReference<IDirectDrawSurface>(NULL); - - return COMReference<IDirectDrawSurface>(pSurface); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::flip - ////////////////////////////////////////////////////////////////////////////////// - - bool DXRenderModule::flip( const ::basegfx::B2IRectangle& rUpdateArea, - const ::basegfx::B2IRectangle& rCurrWindowArea ) - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - // see if the main surfaces got lost. if so, try to - // restore them. bail out if this operation fails. - if(!(validateMainSurfaces())) - return false; - - flushVertexCache(); - - ENSURE_OR_THROW( !mnBeginSceneCount, - "Device::flip(): within 3D scene" ); - - // TODO(E3): handle DX errors more thoroughly. For fullscreen - // exclusive mode, actually even our primary surface can get - // lost and needs restore! - - if( mpDirectDraw.is() && - mpPrimarySurface.is() && - mpBackBufferSurface.is() ) - { - // ignore area and offset for page flipping device - if( mbPageFlipping ) - { -#if OSL_DEBUG_LEVEL > 2 - renderFPSCounter(); - renderMemAvailable(); -#endif - VERBOSE_TRACE( "Device::flip(): Using true page flipping" ); - - // use true page flipping. Hopefully, the 3D hardware - // is flushed on this flip call (rumours have it that - // way), otherwise, perform the Lock hack as for the - // Blt below. - if( SUCCEEDED(mpPrimarySurface->Flip( NULL, DDFLIP_WAIT )) ) - return true; - } - else - { - VERBOSE_TRACE( "Device::flip(): Using blt for page flipping" ); - - // determine actual window position - ::basegfx::B2IPoint aDestPoint( rUpdateArea.getMinimum() ); - ::basegfx::B2IRange aSourceArea( rUpdateArea ); - ::basegfx::B2IRange aDestArea( 0,0, - static_cast<sal_Int32>(rCurrWindowArea.getWidth()), - static_cast<sal_Int32>(rCurrWindowArea.getHeight()) ); - convert2Screen( aDestPoint, aDestArea ); - - // perform clipping - if( !::canvas::tools::clipBlit( aSourceArea, - aDestPoint, - rUpdateArea, - aDestArea ) ) - return true; // fully clipped, but still, in a way, - // successful. - - // TODO(P1): Rumours have it that the 3D hardware - // _might_ still be rendering with flaky drivers, - // which don't flush properly on Blt(). It was said, - // that 'usually', it works to lock the 3D render - // target (the backbuffer in this case). OTOH, I've - // found that this tends to degrade performance - // significantly on complying cards... - - // TODO(P1): Up until rev. 1.3, this method contained - // code to make sure the blit will start _immediately_ - // after the Blt call. If this is not warranted, wait - // for the next vsync. As this case was found to be - // extremely seldom, kicked out (what's more, there's - // simply no guarantee that the blitter will be - // available at any point in the code - Windows still - // is a preemptive multi-processing environment. And - // _if_ we're competing with someone over the blitter, - // we will do so the next VBLANK interval, and the - // following...) - - // screen update seems to be smoother when waiting - // for vblank in every case - even when blitter - // supports the DDBLTFX_NOTEARING flag. - if( FAILED(mpDirectDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, - NULL)) ) - return false; - - DDBLTFX aBltFx; - DDBLTFX* pBltFX = NULL; - if( mbHasNoTearingBlt ) - { - // Blt can internally schedule for no-tearing - // =========================================== - - rtl_fillMemory( &aBltFx, - sizeof(aBltFx), 0 ); - aBltFx.dwSize = sizeof(aBltFx); - aBltFx.dwDDFX = DDBLTFX_NOTEARING; - - pBltFX = &aBltFx; - } - - if( doBlit( aDestPoint, - *mpPrimarySurface, - aSourceArea, - *mpBackBufferSurface, - pBltFX,false ) ) - { -#if OSL_DEBUG_LEVEL > 2 - renderFPSCounter(); - renderMemAvailable(); -#endif - return true; - } - } - } - return false; - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::disposing - ////////////////////////////////////////////////////////////////////////////////// - - void DXRenderModule::disposing() - { - if(!(mhWnd)) - return; - - mpTexture.reset(); - mpWindow.reset(); - mhWnd=NULL; - - // refrain from releasing the DX5 objects - deleting the - // DX5 device seems to kill the whole engine, including - // all objects we might still hold references to - // (surfaces, e.g.) - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::screenshot - ////////////////////////////////////////////////////////////////////////////////// - - void DXRenderModule::screenShot() - { - if(!(mpBackBufferSurface.get())) - return; - char filename[256]; - static sal_uInt32 counter = 0; - sprintf(filename,"c:\\shot%d.bmp",counter++); - dumpSurface(mpBackBufferSurface,filename); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::validateMainSurfaces - ////////////////////////////////////////////////////////////////////////////////// - - bool DXRenderModule::validateMainSurfaces() - { - if(mpPrimarySurface.get()) { - if(mpPrimarySurface->IsLost() == DDERR_SURFACELOST) { - if(FAILED(mpPrimarySurface->Restore())) - return false; - } - } - - if(mpBackBufferSurface.get()) { - if(mpBackBufferSurface->IsLost() == DDERR_SURFACELOST) - { - // TODO(F1): simply restoring the backbuffer does not - // work as expected, we need to re-create everything - // from scratch. find out why... - //if(SUCCEEDED(mpBackBufferSurface->Restore())) - // return setup3DDevice(); - - mpBackBufferSurface.reset(); - - // get us a backbuffer for simulated flipping - IDirectDrawSurface* pSurface; - - // TODO(P2): Strictly speaking, we don't need a full screen worth of - // backbuffer here. We could also scale dynamically with the current - // window size, but this will make it necessary to temporarily have two - // buffers while copying from the old to the new one. YMMV. - const ::basegfx::B2ISize aSize( getFramebufferSize() ); - - DDSURFACEDESC aSurfaceDesc; - rtl_fillMemory( &aSurfaceDesc, sizeof(DDSURFACEDESC), 0 ); - aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); - aSurfaceDesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - aSurfaceDesc.dwHeight= aSize.getY(); - aSurfaceDesc.dwWidth = aSize.getX(); - - aSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; - - HRESULT nRes = mpDirectDraw->CreateSurface(&aSurfaceDesc, &pSurface, NULL); - - if( FAILED( nRes ) ) - { - if( nRes == DDERR_OUTOFVIDEOMEMORY ) - { - // local vid mem failed. Maybe AGP mem works? - aSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM; - if( FAILED(mpDirectDraw->CreateSurface(&aSurfaceDesc, &pSurface, NULL)) ) - { - // no chance - return false; - } - - VERBOSE_TRACE( "Device::Device(): CreateSurface for backbuffer reverted to non-local video mem" ); - } - else - { - // no chance - VERBOSE_TRACE( "Device::Device(): CreateSurface for backbuffer failed" ); - return false; - } - } - - VERBOSE_TRACE( "Device::Device(): created backbuffer of size %d times %d pixel", - aSurfaceDesc.dwWidth, - aSurfaceDesc.dwHeight ); - - mpBackBufferSurface = COMReference< IDirectDrawSurface >(pSurface); - - return setup3DDevice(); - } - } - - return true; - } - - void DXRenderModule::renderInfoText( const ::rtl::OUString& rStr, - const Gdiplus::PointF& rPos ) const - { - ENSURE_OR_THROW( !mnBeginSceneCount, - "Device::renderInfoText(): within 3D scene" ); - - // render text directly to primary surface - GraphicsSharedPtr pGraphics; - - if( mbPageFlipping ) - { - // render on top of backbuffer. We have - // page flipping, anyway, thus this will - // cost us nothing. - pGraphics = createSurfaceGraphics( mpBackBufferSurface ); - } - else - { - // render FPS directly to front buffer. - // That saves us another explicit blit, - // and for me, the FPS counter can blink, - // if it likes to... - pGraphics = createSurfaceGraphics( mpPrimarySurface ); - } - - if( !mbPageFlipping ) - { - // clear background. We might be doing optimized redraws, - // and the background under the FPS count will then not be - // cleared. - Gdiplus::SolidBrush aBrush( - Gdiplus::Color( 255, 255, 255 ) ); - - pGraphics->FillRectangle( &aBrush, - rPos.X, rPos.Y, 80.0, 20.0 ); - } - - Gdiplus::SolidBrush aBrush( - Gdiplus::Color( 255, 0, 255 ) ); - Gdiplus::Font aFont( NULL, - 16, - Gdiplus::FontStyleRegular, - Gdiplus::UnitWorld, - NULL ); - pGraphics->DrawString( reinterpret_cast<LPCWSTR>(rStr.getStr()), - rStr.getLength(), - &aFont, - rPos, - &aBrush ); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::renderMemAvailable - ////////////////////////////////////////////////////////////////////////////////// - - void DXRenderModule::renderMemAvailable() const - { - ENSURE_OR_THROW( !mnBeginSceneCount, - "DXRenderModule::renderMemAvailable(): within 3D scene" ); - - const double nSurfaceMem( getAvailableSurfaceMem()/1024 ); - - ::rtl::OUString text( ::rtl::math::doubleToUString( nSurfaceMem, - rtl_math_StringFormat_F, - 2,'.',NULL,' ') ); - - // pad with leading space - while( text.getLength() < 6 ) - text = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM (" ")) + text; - - text = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("S: ")) + text; - - renderInfoText( text, - Gdiplus::PointF( 0.0, 20) ); - - - const double nTexMem( getAvailableTextureMem()/1024 ); - - text = ::rtl::math::doubleToUString( nTexMem, - rtl_math_StringFormat_F, - 2,'.',NULL,' '); - // pad with leading space - while( text.getLength() < 6 ) - text = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM (" ")) + text; - - text = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("T: ")) + text; - - renderInfoText( text, - Gdiplus::PointF( 0.0, 40) ); - - VERBOSE_TRACE( "dxcanvas: %f free surface mem, %f free texture mem", - nSurfaceMem, nTexMem ); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::renderFPSCounter - ////////////////////////////////////////////////////////////////////////////////// - - void DXRenderModule::renderFPSCounter() const - { - ENSURE_OR_THROW( !mnBeginSceneCount, - "DXRenderModule::ren derFPSCounter(): within 3D scene" ); - - const double denominator( maLastUpdate.getElapsedTime() ); - maLastUpdate.reset(); - - ::rtl::OUString text( ::rtl::math::doubleToUString( denominator == 0.0 ? 100.0 : 1.0/denominator, - rtl_math_StringFormat_F, - 2,'.',NULL,' ') ); - - // pad with leading space - while( text.getLength() < 6 ) - text = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM (" ")) + text; - - text += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM (" fps")); - - renderInfoText( text, - Gdiplus::PointF() ); - - VERBOSE_TRACE( "dxcanvas: %f FPS", - denominator == 0.0 ? 100.0 : 1.0/denominator ); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::resize - ////////////////////////////////////////////////////////////////////////////////// - - void DXRenderModule::resize( const ::basegfx::B2IRange& rect ) - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - if( mhWnd==0 ) - return; - - // don't do anything if the size didn't change. - if(maSize.getX() == static_cast<sal_Int32>(rect.getWidth()) && - maSize.getY() == static_cast<sal_Int32>(rect.getHeight())) - return; - - // TODO(Q2): use numeric cast to prevent overflow - maSize.setX(static_cast<sal_Int32>(rect.getWidth())); - maSize.setY(static_cast<sal_Int32>(rect.getHeight())); - - mpWindow->SetPosSizePixel(0,0,maSize.getX(),maSize.getY()); - } - - ////////////////////////////////////////////////////////////////////////////////// - // DXRenderModule::getPageSize - ////////////////////////////////////////////////////////////////////////////////// - - ::basegfx::B2IVector DXRenderModule::getPageSize() - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - return maPageSize; - } - - ::canvas::ISurfaceSharedPtr DXRenderModule::createSurface( const ::basegfx::B2IVector& surfaceSize ) - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - const ::basegfx::B2IVector& rPageSize( getPageSize() ); - ::basegfx::B2ISize aSize(surfaceSize); - if(!(aSize.getX())) - aSize.setX(rPageSize.getX()); - if(!(aSize.getY())) - aSize.setY(rPageSize.getY()); - - if(mpTexture.use_count() == 1) - return mpTexture; - - return ::canvas::ISurfaceSharedPtr( - new DXSurface(*this, - aSize) ); - } - - void DXRenderModule::beginPrimitive( PrimitiveType eType ) - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - ENSURE_OR_THROW( !mnBeginSceneCount, - "DXRenderModule::beginPrimitive(): nested call" ); - - ++mnBeginSceneCount; - meType=eType; - mnCount=0; - } - - void DXRenderModule::endPrimitive() - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - --mnBeginSceneCount; - meType=PRIMITIVE_TYPE_UNKNOWN; - mnCount=0; - } - - void DXRenderModule::pushVertex( const ::canvas::Vertex& vertex ) - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - switch(meType) - { - case PRIMITIVE_TYPE_TRIANGLE: - { - maVertexCache.push_back(vertex); - ++mnCount; - mnCount &= 3; - break; - } - - case PRIMITIVE_TYPE_QUAD: - { - if(mnCount == 3) - { - const std::size_t size(maVertexCache.size()); - ::canvas::Vertex v0(maVertexCache[size-1]); - ::canvas::Vertex v2(maVertexCache[size-3]); - maVertexCache.push_back(v0); - maVertexCache.push_back(vertex); - maVertexCache.push_back(v2); - mnCount=0; - } - else - { - maVertexCache.push_back(vertex); - ++mnCount; - } - break; - } - - default: - OSL_FAIL( "DXRenderModule::pushVertex(): unexpected primitive types" ); - break; - } - } - - bool DXRenderModule::isError() - { - // TODO(P2): get rid of those fine-grained locking - ::osl::MutexGuard aGuard( maMutex ); - - return mbError; - } - - void DXRenderModule::flushVertexCache() - { - if(!(maVertexCache.size())) - return; - - mbError=true; - - if( FAILED(mpDirect3DDevice->BeginScene()) ) - return; - - // enable texture alpha blending - if( FAILED(mpDirect3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,TRUE))) - return; - - // enable texture alpha modulation, for honoring fAlpha - if( FAILED(mpDirect3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMAPBLEND, - D3DTBLEND_MODULATEALPHA)) ) - return; - - // enable texture magnification filtering (don't care if this - // fails, it's just visually more pleasant) - mpDirect3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMAG, - D3DFILTER_LINEAR); - - // enable texture minification filtering (don't care if this - // fails, it's just visually more pleasant) - mpDirect3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMIN, - D3DFILTER_LINEAR); - - // enable subpixel texture output (don't care if this - // fails, it's just visually more pleasant) - mpDirect3DDevice->SetRenderState(D3DRENDERSTATE_SUBPIXEL, - TRUE); - - // normal combination of object... - if( FAILED(mpDirect3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, - D3DBLEND_SRCALPHA)) ) - return; - - // ..and background color - if( FAILED(mpDirect3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, - D3DBLEND_INVSRCALPHA)) ) - return; - - // disable backface culling; this enables us to mirror sprites - // by simply reverting the triangles, which, with enabled - // culling, would be invisible otherwise - if( FAILED(mpDirect3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, - D3DCULL_NONE)) ) - return; - - mbError=false; - - const float nHalfPixelSizeX(0.5f/maPageSize.getX()); - const float nHalfPixelSizeY(0.5f/maPageSize.getY()); - sal_uInt32 nIndex(0); - const std::size_t size(maVertexCache.size()); - D3DTLVERTEX *vertices = static_cast<D3DTLVERTEX *>(_alloca(sizeof(D3DTLVERTEX)*size)); - vertexCache_t::const_iterator it(maVertexCache.begin()); - while(it != maVertexCache.end()) - { - vertices[nIndex++] = D3DTLVERTEX( - D3DVECTOR(static_cast<D3DVALUE>(it->x), - static_cast<D3DVALUE>(it->y), - static_cast<D3DVALUE>(it->z)), - 1, - D3DRGBA(1,1,1,it->a), - D3DRGBA(0,0,0,0), - static_cast<float>(it->u + nHalfPixelSizeX), - static_cast<float>(it->v + nHalfPixelSizeY)); - ++it; - } - - maVertexCache.clear(); - - mbError |= FAILED(mpDirect3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DVT_TLVERTEX, - (LPVOID)vertices, - size, - 0)); - - mbError |= FAILED(mpDirect3DDevice->EndScene()); - } - } - - IDXRenderModuleSharedPtr createRenderModule( const ::Window& rParent ) - { - return IDXRenderModuleSharedPtr( new DXRenderModule(rParent) ); - } -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/postprocess/packcomponents/makefile.mk b/postprocess/packcomponents/makefile.mk index e0b37df49052..c79a28a57de6 100644 --- a/postprocess/packcomponents/makefile.mk +++ b/postprocess/packcomponents/makefile.mk @@ -343,10 +343,6 @@ my_components += \ component/canvas/source/directx/gdipluscanvas .END -.IF "$(OS)" == "WNT" && "$(ENABLE_DIRECTX)" != "" && "$(USE_DIRECTX5)" != "" -my_components += component/canvas/source/directx/directx5canvas -.END - .IF "$(OS)" != "MACOSX" && "$(SYSTEM_MOZILLA)" != "YES" && \ "$(WITH_MOZILLA)" != "NO" my_components += mozab diff --git a/scp2/source/canvas/directxcanvas.scp b/scp2/source/canvas/directxcanvas.scp index e79f711aaacd..cfa762d3175c 100644 --- a/scp2/source/canvas/directxcanvas.scp +++ b/scp2/source/canvas/directxcanvas.scp @@ -28,9 +28,6 @@ #include "macros.inc" #ifdef WNT -# ifdef USE_DIRECTX5 -SPECIAL_COMPONENT_LIB_FILE(gid_File_Lib_DirectX5Canvas,directx5canvas.uno) -# endif SPECIAL_COMPONENT_LIB_FILE(gid_File_Lib_DirectX9Canvas, directx9canvas.uno) SPECIAL_COMPONENT_LIB_FILE(gid_File_Lib_GdiPlusCanvas, gdipluscanvas.uno) #endif diff --git a/scp2/source/canvas/makefile.mk b/scp2/source/canvas/makefile.mk index d0d8362513e9..24cacaaed2e7 100644 --- a/scp2/source/canvas/makefile.mk +++ b/scp2/source/canvas/makefile.mk @@ -46,9 +46,6 @@ PARFILES+= cairocanvas.par .ENDIF .IF "$(ENABLE_DIRECTX)" != "" -.IF "$(USE_DIRECTX5)" != "" -SCPDEFS+=-DUSE_DIRECTX5 -.ENDIF PARFILES+= directxcanvas.par .ENDIF diff --git a/set_soenv.in b/set_soenv.in index e0f6cfea337f..ecff1a97db9b 100755 --- a/set_soenv.in +++ b/set_soenv.in @@ -169,7 +169,6 @@ if ( $platform =~ m/cygwin|mingw32/ ) $SHOWINCLUDES_PREFIX = '@SHOWINCLUDES_PREFIX@'; $WINDOWS_SDK_HOME = PathFormat('@WINDOWS_SDK_HOME@'); $DIRECTXSDK_LIB = PathFormat('@DIRECTXSDK_LIB@'); - $USE_DIRECTX5 = ""; $DOTNET_FRAMEWORK_HOME = PathFormat('@DOTNET_FRAMEWORK_HOME@'); $wps = ';' if '@build_os@' eq 'cygwin'; # Windows style path seperator } @@ -735,7 +734,6 @@ if ( $platform =~ m/cygwin/ ) { ToFile( "CYGWIN_PATH", $CYGWIN_PATH, "e" ); ToFile( "WINDOWS_SDK_HOME", $WINDOWS_SDK_HOME, "e" ); ToFile( "DIRECTXSDK_LIB", $DIRECTXSDK_LIB, "e" ); - ToFile( "USE_DIRECTX5", $USE_DIRECTX5, "e" ); ToFile( "DISABLE_ACTIVEX", "@DISABLE_ACTIVEX@","e" ); ToFile( "DISABLE_ATL", "@DISABLE_ATL@","e" ); ToFile( "INCLUDE", "", "e" ); |