ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

surface.c
Go to the documentation of this file.
00001 /*
00002  * IDirect3DSurface8 implementation
00003  *
00004  * Copyright 2005 Oliver Stieber
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 #include <assert.h>
00023 #include "d3d8_private.h"
00024 
00025 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
00026 
00027 static inline IDirect3DSurface8Impl *impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface)
00028 {
00029     return CONTAINING_RECORD(iface, IDirect3DSurface8Impl, IDirect3DSurface8_iface);
00030 }
00031 
00032 /* IDirect3DSurface8 IUnknown parts follow: */
00033 static HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(IDirect3DSurface8 *iface, REFIID riid,
00034         void **ppobj)
00035 {
00036     IDirect3DSurface8Impl *This = impl_from_IDirect3DSurface8(iface);
00037 
00038     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
00039 
00040     if (IsEqualGUID(riid, &IID_IUnknown)
00041         || IsEqualGUID(riid, &IID_IDirect3DResource8)
00042         || IsEqualGUID(riid, &IID_IDirect3DSurface8)) {
00043         IUnknown_AddRef(iface);
00044         *ppobj = This;
00045         return S_OK;
00046     }
00047 
00048     WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
00049     *ppobj = NULL;
00050     return E_NOINTERFACE;
00051 }
00052 
00053 static ULONG WINAPI IDirect3DSurface8Impl_AddRef(IDirect3DSurface8 *iface)
00054 {
00055     IDirect3DSurface8Impl *This = impl_from_IDirect3DSurface8(iface);
00056 
00057     TRACE("iface %p.\n", iface);
00058 
00059     if (This->forwardReference) {
00060         /* Forward refcounting */
00061         TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
00062         return IUnknown_AddRef(This->forwardReference);
00063     } else {
00064         /* No container, handle our own refcounting */
00065         ULONG ref = InterlockedIncrement(&This->ref);
00066 
00067         TRACE("%p increasing refcount to %u.\n", iface, ref);
00068 
00069         if (ref == 1)
00070         {
00071             if (This->parentDevice) IUnknown_AddRef(This->parentDevice);
00072             wined3d_mutex_lock();
00073             wined3d_surface_incref(This->wined3d_surface);
00074             wined3d_mutex_unlock();
00075         }
00076 
00077         return ref;
00078     }
00079 }
00080 
00081 static ULONG WINAPI IDirect3DSurface8Impl_Release(IDirect3DSurface8 *iface)
00082 {
00083     IDirect3DSurface8Impl *This = impl_from_IDirect3DSurface8(iface);
00084 
00085     TRACE("iface %p.\n", iface);
00086 
00087     if (This->forwardReference) {
00088         /* Forward refcounting */
00089         TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
00090         return IUnknown_Release(This->forwardReference);
00091     } else {
00092         /* No container, handle our own refcounting */
00093         ULONG ref = InterlockedDecrement(&This->ref);
00094 
00095         TRACE("%p decreasing refcount to %u.\n", iface, ref);
00096 
00097         if (ref == 0) {
00098             IDirect3DDevice8 *parentDevice = This->parentDevice;
00099 
00100             /* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */
00101             wined3d_mutex_lock();
00102             wined3d_surface_decref(This->wined3d_surface);
00103             wined3d_mutex_unlock();
00104 
00105             if (parentDevice) IDirect3DDevice8_Release(parentDevice);
00106         }
00107 
00108         return ref;
00109     }
00110 }
00111 
00112 /* IDirect3DSurface8 IDirect3DResource8 Interface follow: */
00113 static HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(IDirect3DSurface8 *iface,
00114         IDirect3DDevice8 **device)
00115 {
00116     IDirect3DSurface8Impl *This = impl_from_IDirect3DSurface8(iface);
00117 
00118     TRACE("iface %p, device %p.\n", iface, device);
00119 
00120     if (This->forwardReference)
00121     {
00122         IDirect3DResource8 *resource;
00123         HRESULT hr;
00124 
00125         hr = IUnknown_QueryInterface(This->forwardReference, &IID_IDirect3DResource8, (void **)&resource);
00126         if (SUCCEEDED(hr))
00127         {
00128             hr = IDirect3DResource8_GetDevice(resource, device);
00129             IDirect3DResource8_Release(resource);
00130 
00131             TRACE("Returning device %p.\n", *device);
00132         }
00133 
00134         return hr;
00135     }
00136 
00137     *device = This->parentDevice;
00138     IDirect3DDevice8_AddRef(*device);
00139 
00140     TRACE("Returning device %p.\n", *device);
00141 
00142     return D3D_OK;
00143 }
00144 
00145 static HRESULT WINAPI IDirect3DSurface8Impl_SetPrivateData(IDirect3DSurface8 *iface, REFGUID guid,
00146         const void *data, DWORD data_size, DWORD flags)
00147 {
00148     IDirect3DSurface8Impl *surface = impl_from_IDirect3DSurface8(iface);
00149     struct wined3d_resource *resource;
00150     HRESULT hr;
00151 
00152     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
00153             iface, debugstr_guid(guid), data, data_size, flags);
00154 
00155     wined3d_mutex_lock();
00156     resource = wined3d_surface_get_resource(surface->wined3d_surface);
00157     hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
00158     wined3d_mutex_unlock();
00159 
00160     return hr;
00161 }
00162 
00163 static HRESULT WINAPI IDirect3DSurface8Impl_GetPrivateData(IDirect3DSurface8 *iface, REFGUID guid,
00164         void *data, DWORD *data_size)
00165 {
00166     IDirect3DSurface8Impl *surface = impl_from_IDirect3DSurface8(iface);
00167     struct wined3d_resource *resource;
00168     HRESULT hr;
00169 
00170     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
00171             iface, debugstr_guid(guid), data, data_size);
00172 
00173     wined3d_mutex_lock();
00174     resource = wined3d_surface_get_resource(surface->wined3d_surface);
00175     hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
00176     wined3d_mutex_unlock();
00177 
00178     return hr;
00179 }
00180 
00181 static HRESULT WINAPI IDirect3DSurface8Impl_FreePrivateData(IDirect3DSurface8 *iface, REFGUID guid)
00182 {
00183     IDirect3DSurface8Impl *surface = impl_from_IDirect3DSurface8(iface);
00184     struct wined3d_resource *resource;
00185     HRESULT hr;
00186 
00187     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
00188 
00189     wined3d_mutex_lock();
00190     resource = wined3d_surface_get_resource(surface->wined3d_surface);
00191     hr = wined3d_resource_free_private_data(resource, guid);
00192     wined3d_mutex_unlock();
00193 
00194     return hr;
00195 }
00196 
00197 /* IDirect3DSurface8 Interface follow: */
00198 static HRESULT WINAPI IDirect3DSurface8Impl_GetContainer(IDirect3DSurface8 *iface, REFIID riid,
00199         void **ppContainer)
00200 {
00201     IDirect3DSurface8Impl *This = impl_from_IDirect3DSurface8(iface);
00202     HRESULT res;
00203 
00204     TRACE("iface %p, riid %s, container %p.\n", iface, debugstr_guid(riid), ppContainer);
00205 
00206     if (!This->container) return E_NOINTERFACE;
00207 
00208     res = IUnknown_QueryInterface(This->container, riid, ppContainer);
00209 
00210     TRACE("(%p) : returning %p\n", This, *ppContainer);
00211     return res;
00212 }
00213 
00214 static HRESULT WINAPI IDirect3DSurface8Impl_GetDesc(IDirect3DSurface8 *iface, D3DSURFACE_DESC *desc)
00215 {
00216     IDirect3DSurface8Impl *This = impl_from_IDirect3DSurface8(iface);
00217     struct wined3d_resource_desc wined3d_desc;
00218     struct wined3d_resource *wined3d_resource;
00219 
00220     TRACE("iface %p, desc %p.\n", iface, desc);
00221 
00222     wined3d_mutex_lock();
00223     wined3d_resource = wined3d_surface_get_resource(This->wined3d_surface);
00224     wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
00225     wined3d_mutex_unlock();
00226 
00227     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
00228     desc->Type = wined3d_desc.resource_type;
00229     desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
00230     desc->Pool = wined3d_desc.pool;
00231     desc->Size = wined3d_desc.size;
00232     desc->MultiSampleType = wined3d_desc.multisample_type;
00233     desc->Width = wined3d_desc.width;
00234     desc->Height = wined3d_desc.height;
00235 
00236     return D3D_OK;
00237 }
00238 
00239 static HRESULT WINAPI IDirect3DSurface8Impl_LockRect(IDirect3DSurface8 *iface,
00240         D3DLOCKED_RECT *pLockedRect, const RECT *pRect, DWORD Flags)
00241 {
00242     IDirect3DSurface8Impl *This = impl_from_IDirect3DSurface8(iface);
00243     HRESULT hr;
00244 
00245     TRACE("iface %p, locked_rect %p, rect %p, flags %#x.\n", iface, pLockedRect, pRect, Flags);
00246 
00247     wined3d_mutex_lock();
00248     if (pRect) {
00249         D3DSURFACE_DESC desc;
00250         IDirect3DSurface8_GetDesc(iface, &desc);
00251 
00252         if ((pRect->left < 0)
00253                 || (pRect->top < 0)
00254                 || (pRect->left >= pRect->right)
00255                 || (pRect->top >= pRect->bottom)
00256                 || (pRect->right > desc.Width)
00257                 || (pRect->bottom > desc.Height)) {
00258             WARN("Trying to lock an invalid rectangle, returning D3DERR_INVALIDCALL\n");
00259             wined3d_mutex_unlock();
00260 
00261             return D3DERR_INVALIDCALL;
00262         }
00263     }
00264 
00265     hr = wined3d_surface_map(This->wined3d_surface, (struct wined3d_mapped_rect *)pLockedRect, pRect, Flags);
00266     wined3d_mutex_unlock();
00267 
00268     return hr;
00269 }
00270 
00271 static HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(IDirect3DSurface8 *iface)
00272 {
00273     IDirect3DSurface8Impl *This = impl_from_IDirect3DSurface8(iface);
00274     HRESULT hr;
00275 
00276     TRACE("iface %p.\n", iface);
00277 
00278     wined3d_mutex_lock();
00279     hr = wined3d_surface_unmap(This->wined3d_surface);
00280     wined3d_mutex_unlock();
00281 
00282     switch(hr)
00283     {
00284         case WINEDDERR_NOTLOCKED:       return D3DERR_INVALIDCALL;
00285         default:                        return hr;
00286     }
00287 }
00288 
00289 static const IDirect3DSurface8Vtbl Direct3DSurface8_Vtbl =
00290 {
00291     /* IUnknown */
00292     IDirect3DSurface8Impl_QueryInterface,
00293     IDirect3DSurface8Impl_AddRef,
00294     IDirect3DSurface8Impl_Release,
00295     /* IDirect3DResource8 */
00296     IDirect3DSurface8Impl_GetDevice,
00297     IDirect3DSurface8Impl_SetPrivateData,
00298     IDirect3DSurface8Impl_GetPrivateData,
00299     IDirect3DSurface8Impl_FreePrivateData,
00300     /* IDirect3DSurface8 */
00301     IDirect3DSurface8Impl_GetContainer,
00302     IDirect3DSurface8Impl_GetDesc,
00303     IDirect3DSurface8Impl_LockRect,
00304     IDirect3DSurface8Impl_UnlockRect
00305 };
00306 
00307 static void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
00308 {
00309     HeapFree(GetProcessHeap(), 0, parent);
00310 }
00311 
00312 static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
00313 {
00314     surface_wined3d_object_destroyed,
00315 };
00316 
00317 HRESULT surface_init(IDirect3DSurface8Impl *surface, IDirect3DDevice8Impl *device,
00318         UINT width, UINT height, D3DFORMAT format, BOOL lockable, BOOL discard, UINT level,
00319         DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
00320 {
00321     DWORD flags = 0;
00322     HRESULT hr;
00323 
00324     surface->IDirect3DSurface8_iface.lpVtbl = &Direct3DSurface8_Vtbl;
00325     surface->ref = 1;
00326 
00327     /* FIXME: Check MAX bounds of MultisampleQuality. */
00328     if (multisample_quality > 0)
00329     {
00330         FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality);
00331         multisample_quality = 0;
00332     }
00333 
00334     if (lockable)
00335         flags |= WINED3D_SURFACE_MAPPABLE;
00336     if (discard)
00337         flags |= WINED3D_SURFACE_DISCARD;
00338 
00339     wined3d_mutex_lock();
00340     hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format),
00341             level, usage & WINED3DUSAGE_MASK, (enum wined3d_pool)pool, multisample_type, multisample_quality,
00342             SURFACE_OPENGL, flags, surface, &d3d8_surface_wined3d_parent_ops, &surface->wined3d_surface);
00343     wined3d_mutex_unlock();
00344     if (FAILED(hr))
00345     {
00346         WARN("Failed to create wined3d surface, hr %#x.\n", hr);
00347         return hr;
00348     }
00349 
00350     surface->parentDevice = &device->IDirect3DDevice8_iface;
00351     IUnknown_AddRef(surface->parentDevice);
00352 
00353     return D3D_OK;
00354 }
00355 
00356 IDirect3DSurface8Impl *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface)
00357 {
00358     if (!iface)
00359         return NULL;
00360     assert(iface->lpVtbl == &Direct3DSurface8_Vtbl);
00361 
00362     return impl_from_IDirect3DSurface8(iface);
00363 }

Generated on Sun May 27 2012 04:22:04 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.