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