Maarten Lankhorst : dsound: Handle secondary hardware buffers more correctly.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Aug 27 06:07:47 CDT 2007


Module: wine
Branch: master
Commit: 7ce277d0186bf6577b6f09c76ccc595b62b3ef2a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7ce277d0186bf6577b6f09c76ccc595b62b3ef2a

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Sun Aug 26 17:34:45 2007 +0200

dsound: Handle secondary hardware buffers more correctly.

Only try hardware if asked for it, then return an error instead of
falling back to software.

---

 dlls/dsound/buffer.c |   91 ++++++++++++++++++--------------------------------
 1 files changed, 33 insertions(+), 58 deletions(-)

diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
index 4194403..1a99927 100644
--- a/dlls/dsound/buffer.c
+++ b/dlls/dsound/buffer.c
@@ -725,7 +725,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
 	if (!p2)
 		x2 = 0;
 
-	if (x1 || x2)
+	if (!This->hwbuf && (x1 || x2))
 	{
 		RtlAcquireResourceShared(&This->device->buffer_list_lock, TRUE);
 		LIST_FOR_EACH_ENTRY(iter, &This->buffer->buffers, IDirectSoundBufferImpl, entry )
@@ -1021,8 +1021,16 @@ HRESULT IDirectSoundBufferImpl_Create(
 	if (wfex->wBitsPerSample==16) capf |= DSCAPS_SECONDARY16BIT;
 	else capf |= DSCAPS_SECONDARY8BIT;
 
-	use_hw = (device->drvcaps.dwFlags & capf) == capf;
-	TRACE("use_hw = 0x%08x, capf = 0x%08x, device->drvcaps.dwFlags = 0x%08x\n", use_hw, capf, device->drvcaps.dwFlags);
+	use_hw = !!(dsbd->dwFlags & DSBCAPS_LOCHARDWARE);
+	TRACE("use_hw = %d, capf = 0x%08x, device->drvcaps.dwFlags = 0x%08x\n", use_hw, capf, device->drvcaps.dwFlags);
+	if (use_hw && (device->drvcaps.dwFlags & capf) != capf)
+	{
+		WARN("Format not supported for hardware buffer\n");
+		HeapFree(GetProcessHeap(),0,dsb->pwfx);
+		HeapFree(GetProcessHeap(),0,dsb);
+		*pdsb = NULL;
+		return DSERR_BADFORMAT;
+	}
 
 	/* FIXME: check hardware sample rate mixing capabilities */
 	/* FIXME: check app hints for software/hardware buffer (STATIC, LOCHARDWARE, etc) */
@@ -1050,10 +1058,6 @@ HRESULT IDirectSoundBufferImpl_Create(
 			*pdsb = NULL;
 			return DSERR_OUTOFMEMORY;
 		}
-		dsb->buffer->ref = 1;
-		list_init(&dsb->buffer->buffers);
-		list_add_head(&dsb->buffer->buffers, &dsb->entry);
-		FillMemory(dsb->buffer->memory, dsb->buflen, dsbd->lpwfxFormat->wBitsPerSample == 8 ? 128 : 0);
 	}
 
 	/* Allocate the hardware buffer */
@@ -1061,29 +1065,24 @@ HRESULT IDirectSoundBufferImpl_Create(
 		err = IDsDriver_CreateSoundBuffer(device->driver,wfex,dsbd->dwFlags,0,
 						  &(dsb->buflen),&(dsb->buffer->memory),
 						  (LPVOID*)&(dsb->hwbuf));
-                /* fall back to software buffer on failure */
-		if (err != DS_OK) {
-			TRACE("IDsDriver_CreateSoundBuffer failed, falling back to software buffer\n");
-			use_hw = 0;
-			if (device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
-				dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
-				if (dsb->buffer->memory == NULL) {
-					WARN("out of memory\n");
-					HeapFree(GetProcessHeap(),0,dsb->buffer);
-					HeapFree(GetProcessHeap(),0,dsb->pwfx);
-					HeapFree(GetProcessHeap(),0,dsb);
-					*pdsb = NULL;
-					return DSERR_OUTOFMEMORY;
-				}
-				dsb->buffer->ref = 1;
-				list_init(&dsb->buffer->buffers);
-				list_add_head(&dsb->buffer->buffers, &dsb->entry);
-				FillMemory(dsb->buffer->memory, dsb->buflen, dsbd->lpwfxFormat->wBitsPerSample == 8 ? 128 : 0);
-			}
-			err = DS_OK;
+		if (FAILED(err))
+		{
+			WARN("Failed to create hardware secondary buffer: %08x\n", err);
+			if (device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY)
+				HeapFree(GetProcessHeap(),0,dsb->buffer->memory);
+			HeapFree(GetProcessHeap(),0,dsb->buffer);
+			HeapFree(GetProcessHeap(),0,dsb->pwfx);
+			HeapFree(GetProcessHeap(),0,dsb);
+			*pdsb = NULL;
+			return DSERR_GENERIC;
 		}
 	}
 
+	dsb->buffer->ref = 1;
+	list_init(&dsb->buffer->buffers);
+	list_add_head(&dsb->buffer->buffers, &dsb->entry);
+	FillMemory(dsb->buffer->memory, dsb->buflen, dsbd->lpwfxFormat->wBitsPerSample == 8 ? 128 : 0);
+
 	/* It's not necessary to initialize values to zero since */
 	/* we allocated this structure with HEAP_ZERO_MEMORY... */
 	dsb->buf_mixpos = dsb->sec_mixpos = 0;
@@ -1201,40 +1200,16 @@ HRESULT IDirectSoundBufferImpl_Duplicate(
 
         hres = IDsDriver_DuplicateSoundBuffer(device->driver, pdsb->hwbuf,
                                               (LPVOID *)&dsb->hwbuf);
-        if (hres != DS_OK) {
-            TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to "
-                  "software buffer\n");
-            dsb->hwbuf = NULL;
-            /* allocate buffer */
-            if (device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
-                dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
-                if (dsb->buffer == NULL) {
-                    WARN("out of memory\n");
-                    HeapFree(GetProcessHeap(),0,dsb);
-                    *ppdsb = NULL;
-                    return DSERR_OUTOFMEMORY;
-                }
-
-                dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
-                if (dsb->buffer->memory == NULL) {
-                    WARN("out of memory\n");
-                    HeapFree(GetProcessHeap(),0,dsb->buffer);
-                    HeapFree(GetProcessHeap(),0,dsb);
-                    *ppdsb = NULL;
-                    return DSERR_OUTOFMEMORY;
-                }
-                dsb->buffer->ref = 1;
-                list_init(&dsb->buffer->buffers);
-                list_add_head(&dsb->buffer->buffers, &dsb->entry);
-                /* FIXME: copy buffer ? */
-            }
+        if (FAILED(hres)) {
+            WARN("IDsDriver_DuplicateSoundBuffer failed (%08x)\n", hres);
+            HeapFree(GetProcessHeap(),0,dsb);
+            *ppdsb = NULL;
+            return hres;
         }
-    } else {
-        dsb->hwbuf = NULL;
-        dsb->buffer->ref++;
-        list_add_head(&dsb->buffer->buffers, &dsb->entry);
     }
 
+    dsb->buffer->ref++;
+    list_add_head(&dsb->buffer->buffers, &dsb->entry);
     dsb->ref = 0;
     dsb->state = STATE_STOPPED;
     dsb->buf_mixpos = dsb->sec_mixpos = 0;




More information about the wine-cvs mailing list