xref: /trunk/main/canvas/source/directx/dx_spritedevicehelper.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*25ea7f45SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*25ea7f45SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*25ea7f45SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*25ea7f45SAndrew Rist  * distributed with this work for additional information
6*25ea7f45SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*25ea7f45SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*25ea7f45SAndrew Rist  * "License"); you may not use this file except in compliance
9*25ea7f45SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*25ea7f45SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*25ea7f45SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*25ea7f45SAndrew Rist  * software distributed under the License is distributed on an
15*25ea7f45SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*25ea7f45SAndrew Rist  * KIND, either express or implied.  See the License for the
17*25ea7f45SAndrew Rist  * specific language governing permissions and limitations
18*25ea7f45SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*25ea7f45SAndrew Rist  *************************************************************/
21*25ea7f45SAndrew Rist 
22*25ea7f45SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include <ctype.h> // don't ask. msdev breaks otherwise...
25cdf0e10cSrcweir #include <vcl/window.hxx>
26cdf0e10cSrcweir #include <canvas/debug.hxx>
27cdf0e10cSrcweir #include <canvas/verbosetrace.hxx>
28cdf0e10cSrcweir #include <canvas/canvastools.hxx>
29cdf0e10cSrcweir #include <tools/diagnose_ex.h>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <osl/mutex.hxx>
32cdf0e10cSrcweir #include <cppuhelper/compbase1.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include <com/sun/star/lang/NoSupportException.hpp>
35cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx>
36cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
37cdf0e10cSrcweir #include "dx_linepolypolygon.hxx"
38cdf0e10cSrcweir #include "dx_spritecanvas.hxx"
39cdf0e10cSrcweir #include "dx_canvasbitmap.hxx"
40cdf0e10cSrcweir #include "dx_spritedevicehelper.hxx"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #undef WB_LEFT
44cdf0e10cSrcweir #undef WB_RIGHT
45cdf0e10cSrcweir #include "dx_winstuff.hxx"
46cdf0e10cSrcweir 
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include <vcl/sysdata.hxx>
49cdf0e10cSrcweir 
50cdf0e10cSrcweir using namespace ::com::sun::star;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir namespace dxcanvas
53cdf0e10cSrcweir {
SpriteDeviceHelper()54cdf0e10cSrcweir     SpriteDeviceHelper::SpriteDeviceHelper() :
55cdf0e10cSrcweir         DeviceHelper(),
56cdf0e10cSrcweir         mpSpriteCanvas( NULL ),
57cdf0e10cSrcweir         mpSurfaceProxyManager(),
58cdf0e10cSrcweir         mpRenderModule(),
59cdf0e10cSrcweir         mpBackBuffer()
60cdf0e10cSrcweir     {
61cdf0e10cSrcweir     }
62cdf0e10cSrcweir 
init(Window & rWindow,SpriteCanvas & rSpriteCanvas,const awt::Rectangle & rRect,bool)63cdf0e10cSrcweir     void SpriteDeviceHelper::init( Window&               rWindow,
64cdf0e10cSrcweir                                    SpriteCanvas&         rSpriteCanvas,
65cdf0e10cSrcweir                                    const awt::Rectangle& rRect,
66cdf0e10cSrcweir                                    bool                  /*bFullscreen*/ )
67cdf0e10cSrcweir     {
68cdf0e10cSrcweir         // #i60490# ensure backbuffer has sensible minimal size
69cdf0e10cSrcweir         const sal_Int32 w( ::std::max(sal_Int32(1),sal_Int32(rRect.Width)));
70cdf0e10cSrcweir         const sal_Int32 h( ::std::max(sal_Int32(1),sal_Int32(rRect.Height)));
71cdf0e10cSrcweir 
72cdf0e10cSrcweir         rSpriteCanvas.setWindow(
73cdf0e10cSrcweir             uno::Reference<awt::XWindow2>(
74cdf0e10cSrcweir                 VCLUnoHelper::GetInterface(&rWindow),
75cdf0e10cSrcweir                 uno::UNO_QUERY_THROW) );
76cdf0e10cSrcweir 
77cdf0e10cSrcweir         const SystemEnvData *pData = rWindow.GetSystemData();
78cdf0e10cSrcweir         const HWND hWnd = reinterpret_cast<HWND>(pData->hWnd);
79cdf0e10cSrcweir         if( !IsWindow( hWnd ) )
80cdf0e10cSrcweir             throw lang::NoSupportException(
81cdf0e10cSrcweir                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
82cdf0e10cSrcweir                                      "Passed window has invalid system window, or canvas out-of-process!")),
83cdf0e10cSrcweir                 NULL);
84cdf0e10cSrcweir 
85cdf0e10cSrcweir         mpSpriteCanvas = &rSpriteCanvas;
86cdf0e10cSrcweir 
87cdf0e10cSrcweir         try
88cdf0e10cSrcweir         {
89cdf0e10cSrcweir             // setup directx rendermodule
90cdf0e10cSrcweir             mpRenderModule = createRenderModule( rWindow );
91cdf0e10cSrcweir         }
92cdf0e10cSrcweir         catch (...) {
93cdf0e10cSrcweir 
94cdf0e10cSrcweir             throw lang::NoSupportException(
95cdf0e10cSrcweir                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
96cdf0e10cSrcweir                                      "Could not create DirectX device!") ),
97cdf0e10cSrcweir                 static_cast< ::cppu::OWeakObject* >(&rSpriteCanvas) );
98cdf0e10cSrcweir         }
99cdf0e10cSrcweir 
100cdf0e10cSrcweir         // create the surfaceproxy manager
101cdf0e10cSrcweir         mpSurfaceProxyManager = ::canvas::createSurfaceProxyManager( mpRenderModule );
102cdf0e10cSrcweir 
103cdf0e10cSrcweir         // #i60490# ensure backbuffer has sensible minimal size
104cdf0e10cSrcweir         mpBackBuffer.reset(new DXSurfaceBitmap(
105cdf0e10cSrcweir                                ::basegfx::B2ISize(w,h),
106cdf0e10cSrcweir                                mpSurfaceProxyManager,
107cdf0e10cSrcweir                                mpRenderModule,
108cdf0e10cSrcweir                                false));
109cdf0e10cSrcweir 
110cdf0e10cSrcweir         // Assumes: SystemChildWindow() has CS_OWNDC
111cdf0e10cSrcweir         DeviceHelper::init(GetDC(mpRenderModule->getHWND()),
112cdf0e10cSrcweir                            rSpriteCanvas);
113cdf0e10cSrcweir     }
114cdf0e10cSrcweir 
disposing()115cdf0e10cSrcweir     void SpriteDeviceHelper::disposing()
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         // release all references
118cdf0e10cSrcweir         mpBackBuffer.reset();
119cdf0e10cSrcweir         mpSurfaceProxyManager.reset();
120cdf0e10cSrcweir         mpRenderModule.reset();
121cdf0e10cSrcweir         mpSpriteCanvas = NULL;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir         DeviceHelper::disposing();
124cdf0e10cSrcweir     }
125cdf0e10cSrcweir 
createCompatibleBitmap(const uno::Reference<rendering::XGraphicDevice> &,const geometry::IntegerSize2D & size)126cdf0e10cSrcweir     uno::Reference< rendering::XBitmap > SpriteDeviceHelper::createCompatibleBitmap(
127cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >&  /*rDevice*/,
128cdf0e10cSrcweir         const geometry::IntegerSize2D&                      size )
129cdf0e10cSrcweir     {
130cdf0e10cSrcweir         if( !getDevice() )
131cdf0e10cSrcweir             return uno::Reference< rendering::XBitmap >(); // we're disposed
132cdf0e10cSrcweir 
133cdf0e10cSrcweir         DXSurfaceBitmapSharedPtr pBitmap(
134cdf0e10cSrcweir             new DXSurfaceBitmap(
135cdf0e10cSrcweir                 ::basegfx::unotools::b2ISizeFromIntegerSize2D(size),
136cdf0e10cSrcweir                 mpSurfaceProxyManager,
137cdf0e10cSrcweir                 mpRenderModule,
138cdf0e10cSrcweir                 false));
139cdf0e10cSrcweir 
140cdf0e10cSrcweir         // create a 24bit RGB system memory surface
141cdf0e10cSrcweir         return uno::Reference< rendering::XBitmap >(new CanvasBitmap(pBitmap,getDevice()));
142cdf0e10cSrcweir     }
143cdf0e10cSrcweir 
createVolatileBitmap(const uno::Reference<rendering::XGraphicDevice> &,const geometry::IntegerSize2D &)144cdf0e10cSrcweir     uno::Reference< rendering::XVolatileBitmap > SpriteDeviceHelper::createVolatileBitmap(
145cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >&  /*rDevice*/,
146cdf0e10cSrcweir         const geometry::IntegerSize2D&                      /*size*/ )
147cdf0e10cSrcweir     {
148cdf0e10cSrcweir         return uno::Reference< rendering::XVolatileBitmap >();
149cdf0e10cSrcweir     }
150cdf0e10cSrcweir 
createCompatibleAlphaBitmap(const uno::Reference<rendering::XGraphicDevice> &,const geometry::IntegerSize2D & size)151cdf0e10cSrcweir     uno::Reference< rendering::XBitmap > SpriteDeviceHelper::createCompatibleAlphaBitmap(
152cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >&  /*rDevice*/,
153cdf0e10cSrcweir         const geometry::IntegerSize2D&                      size )
154cdf0e10cSrcweir     {
155cdf0e10cSrcweir         if( !getDevice() )
156cdf0e10cSrcweir             return uno::Reference< rendering::XBitmap >(); // we're disposed
157cdf0e10cSrcweir 
158cdf0e10cSrcweir         DXSurfaceBitmapSharedPtr pBitmap(
159cdf0e10cSrcweir             new DXSurfaceBitmap(
160cdf0e10cSrcweir                 ::basegfx::unotools::b2ISizeFromIntegerSize2D(size),
161cdf0e10cSrcweir                 mpSurfaceProxyManager,
162cdf0e10cSrcweir                 mpRenderModule,
163cdf0e10cSrcweir                 true));
164cdf0e10cSrcweir 
165cdf0e10cSrcweir         // create a 32bit ARGB system memory surface
166cdf0e10cSrcweir         return uno::Reference< rendering::XBitmap >(new CanvasBitmap(pBitmap,getDevice()));
167cdf0e10cSrcweir     }
168cdf0e10cSrcweir 
createVolatileAlphaBitmap(const uno::Reference<rendering::XGraphicDevice> &,const geometry::IntegerSize2D &)169cdf0e10cSrcweir     uno::Reference< rendering::XVolatileBitmap > SpriteDeviceHelper::createVolatileAlphaBitmap(
170cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >&  /*rDevice*/,
171cdf0e10cSrcweir         const geometry::IntegerSize2D&                      /*size*/ )
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         return uno::Reference< rendering::XVolatileBitmap >();
174cdf0e10cSrcweir     }
175cdf0e10cSrcweir 
hasFullScreenMode()176cdf0e10cSrcweir     sal_Bool SpriteDeviceHelper::hasFullScreenMode()
177cdf0e10cSrcweir     {
178cdf0e10cSrcweir         // TODO(F3): offer fullscreen mode the XCanvas way
179cdf0e10cSrcweir         return false;
180cdf0e10cSrcweir     }
181cdf0e10cSrcweir 
enterFullScreenMode(sal_Bool)182cdf0e10cSrcweir     sal_Bool SpriteDeviceHelper::enterFullScreenMode( sal_Bool /*bEnter*/ )
183cdf0e10cSrcweir     {
184cdf0e10cSrcweir         // TODO(F3): offer fullscreen mode the XCanvas way
185cdf0e10cSrcweir         return false;
186cdf0e10cSrcweir     }
187cdf0e10cSrcweir 
createBuffers(::sal_Int32)188cdf0e10cSrcweir     ::sal_Int32 SpriteDeviceHelper::createBuffers( ::sal_Int32 /*nBuffers*/ )
189cdf0e10cSrcweir     {
190cdf0e10cSrcweir         // TODO(F3): implement XBufferStrategy interface. For now, we
191cdf0e10cSrcweir         // _always_ will have exactly one backbuffer
192cdf0e10cSrcweir         return 1;
193cdf0e10cSrcweir     }
194cdf0e10cSrcweir 
destroyBuffers()195cdf0e10cSrcweir     void SpriteDeviceHelper::destroyBuffers()
196cdf0e10cSrcweir     {
197cdf0e10cSrcweir         // TODO(F3): implement XBufferStrategy interface. For now, we
198cdf0e10cSrcweir         // _always_ will have exactly one backbuffer
199cdf0e10cSrcweir     }
200cdf0e10cSrcweir 
showBuffer(bool,::sal_Bool)201cdf0e10cSrcweir     ::sal_Bool SpriteDeviceHelper::showBuffer( bool, ::sal_Bool )
202cdf0e10cSrcweir     {
203cdf0e10cSrcweir         OSL_ENSURE(false,"Not supposed to be called, handled by SpriteCanvas");
204cdf0e10cSrcweir         return sal_False;
205cdf0e10cSrcweir     }
206cdf0e10cSrcweir 
switchBuffer(bool,::sal_Bool)207cdf0e10cSrcweir     ::sal_Bool SpriteDeviceHelper::switchBuffer( bool, ::sal_Bool )
208cdf0e10cSrcweir     {
209cdf0e10cSrcweir         OSL_ENSURE(false,"Not supposed to be called, handled by SpriteCanvas");
210cdf0e10cSrcweir         return sal_False;
211cdf0e10cSrcweir     }
212cdf0e10cSrcweir 
isAccelerated() const213cdf0e10cSrcweir     uno::Any SpriteDeviceHelper::isAccelerated() const
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         return ::com::sun::star::uno::makeAny(true);
216cdf0e10cSrcweir     }
217cdf0e10cSrcweir 
notifySizeUpdate(const awt::Rectangle & rBounds)218cdf0e10cSrcweir     void SpriteDeviceHelper::notifySizeUpdate( const awt::Rectangle& rBounds )
219cdf0e10cSrcweir     {
220cdf0e10cSrcweir         // #i60490# ensure backbuffer has sensible minimal size
221cdf0e10cSrcweir         const sal_Int32 x(rBounds.X);
222cdf0e10cSrcweir         const sal_Int32 y(rBounds.Y);
223cdf0e10cSrcweir         const sal_Int32 w(::std::max(sal_Int32(1),sal_Int32(rBounds.Width)));
224cdf0e10cSrcweir         const sal_Int32 h(::std::max(sal_Int32(1),sal_Int32(rBounds.Height)));
225cdf0e10cSrcweir 
226cdf0e10cSrcweir         if( mpRenderModule )
227cdf0e10cSrcweir             mpRenderModule->resize(::basegfx::B2IRange(x,y,x+w,y+h));
228cdf0e10cSrcweir 
229cdf0e10cSrcweir         resizeBackBuffer(::basegfx::B2ISize(w,h));
230cdf0e10cSrcweir     }
231cdf0e10cSrcweir 
resizeBackBuffer(const::basegfx::B2ISize & rNewSize)232cdf0e10cSrcweir     void SpriteDeviceHelper::resizeBackBuffer( const ::basegfx::B2ISize& rNewSize )
233cdf0e10cSrcweir     {
234cdf0e10cSrcweir         // disposed?
235cdf0e10cSrcweir         if(!(mpBackBuffer))
236cdf0e10cSrcweir             return;
237cdf0e10cSrcweir 
238cdf0e10cSrcweir         mpBackBuffer->resize(rNewSize);
239cdf0e10cSrcweir         mpBackBuffer->clear();
240cdf0e10cSrcweir     }
241cdf0e10cSrcweir 
getHwnd() const242cdf0e10cSrcweir     HWND SpriteDeviceHelper::getHwnd() const
243cdf0e10cSrcweir     {
244cdf0e10cSrcweir         if( mpRenderModule )
245cdf0e10cSrcweir             return mpRenderModule->getHWND();
246cdf0e10cSrcweir         else
247cdf0e10cSrcweir             return 0;
248cdf0e10cSrcweir     }
249cdf0e10cSrcweir 
dumpScreenContent() const250cdf0e10cSrcweir     void SpriteDeviceHelper::dumpScreenContent() const
251cdf0e10cSrcweir     {
252cdf0e10cSrcweir         if( mpRenderModule )
253cdf0e10cSrcweir             mpRenderModule->screenShot();
254cdf0e10cSrcweir     }
255cdf0e10cSrcweir }
256