Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 140805
Collapse All | Expand All

(-)a/dlls/wined3d/surface.c (-1 / +15 lines)
Lines 75-80 ULONG WINAPI IWineD3DSurfaceImpl_Release Link Here
75
            LEAVE_GL();
75
            LEAVE_GL();
76
        }
76
        }
77
77
78
        if(This->update_thread)
79
        {
80
            HANDLE event = This->update_event;
81
            This->update_event = 0;
82
            SetEvent(event);
83
84
            TRACE("waiting for update thread to terminate...\n");
85
            WaitForSingleObject(This->update_thread, INFINITE);
86
87
            CloseHandle(event);
88
            CloseHandle(This->update_thread);
89
            CloseHandle(This->refresh_event);
90
            DeleteCriticalSection(&This->crit);
91
        }
92
78
        if(This->Flags & SFLAG_DIBSECTION) {
93
        if(This->Flags & SFLAG_DIBSECTION) {
79
            /* Release the DC */
94
            /* Release the DC */
80
            SelectObject(This->hDC, This->dib.holdbitmap);
95
            SelectObject(This->hDC, This->dib.holdbitmap);
Lines 91-97 ULONG WINAPI IWineD3DSurfaceImpl_Release Link Here
91
106
92
        TRACE("(%p) Released\n", This);
107
        TRACE("(%p) Released\n", This);
93
        HeapFree(GetProcessHeap(), 0, This);
108
        HeapFree(GetProcessHeap(), 0, This);
94
95
    }
109
    }
96
    return ref;
110
    return ref;
97
}
111
}
(-)a/dlls/wined3d/surface_gdi.c (+98 lines)
Lines 36-41 Link Here
36
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
36
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
37
WINE_DECLARE_DEBUG_CHANNEL(fps);
37
WINE_DECLARE_DEBUG_CHANNEL(fps);
38
38
39
#ifndef SYNC_UPDATE
40
static DWORD CALLBACK User_update_thread(void *);
41
static void IWineGDISurface_wait_update(IWineD3DSurfaceImpl* This);
42
#endif
43
39
/*****************************************************************************
44
/*****************************************************************************
40
 * x11_copy_to_screen
45
 * x11_copy_to_screen
41
 *
46
 *
Lines 178-183 IWineGDISurfaceImpl_LockRect(IWineD3DSur Link Here
178
    TRACE("(%p) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n",
183
    TRACE("(%p) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n",
179
          This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
184
          This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
180
185
186
#ifndef SYNC_UPDATE
187
    if (iface == This->resource.wineD3DDevice->ddraw_primary && Flags & DDLOCK_WAIT) IWineGDISurface_wait_update(This);
188
#endif
189
181
    pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
190
    pLockedRect->Pitch = IWineD3DSurface_GetPitch(iface);
182
191
183
    if (NULL == pRect)
192
    if (NULL == pRect)
Lines 231-236 IWineGDISurfaceImpl_LockRect(IWineD3DSur Link Here
231
    TRACE("returning memory@%p, pitch(%d)\n", pLockedRect->pBits, pLockedRect->Pitch);
240
    TRACE("returning memory@%p, pitch(%d)\n", pLockedRect->pBits, pLockedRect->Pitch);
232
241
233
    This->Flags |= SFLAG_LOCKED;
242
    This->Flags |= SFLAG_LOCKED;
243
    This->dirtyRect = This->lockedRect;
234
    return D3D_OK;
244
    return D3D_OK;
235
}
245
}
236
246
Lines 281-287 IWineGDISurfaceImpl_UnlockRect(IWineD3DS Link Here
281
    /* Update the screen */
291
    /* Update the screen */
282
    if(This == (IWineD3DSurfaceImpl *) dev->ddraw_primary)
292
    if(This == (IWineD3DSurfaceImpl *) dev->ddraw_primary)
283
    {
293
    {
294
#ifdef SYNC_UPDATE
284
        x11_copy_to_screen(This, &This->lockedRect);
295
        x11_copy_to_screen(This, &This->lockedRect);
296
#else
297
        SetEvent(This->update_event);
298
#endif
285
    }
299
    }
286
300
287
    This->Flags &= ~SFLAG_LOCKED;
301
    This->Flags &= ~SFLAG_LOCKED;
Lines 378-384 IWineGDISurfaceImpl_Flip(IWineD3DSurface Link Here
378
#endif
392
#endif
379
393
380
    /* Update the screen */
394
    /* Update the screen */
395
#ifdef SYNC_UPDATE
381
    x11_copy_to_screen(This, NULL);
396
    x11_copy_to_screen(This, NULL);
397
#else
398
    if (Flags & DDFLIP_WAIT) IWineGDISurface_wait_update(This);
399
    This->dirtyRect.left = 0;
400
    This->dirtyRect.top = 0;
401
    This->dirtyRect.right = This->currentDesc.Width;
402
    This->dirtyRect.bottom = This->currentDesc.Height;
403
    SetEvent(This->update_event);
404
#endif
382
405
383
    /* FPS support */
406
    /* FPS support */
384
    if (TRACE_ON(fps))
407
    if (TRACE_ON(fps))
Lines 1531-1539 IWineGDISurfaceImpl_PrivateSetup(IWineD3 Link Here
1531
        return hr;
1554
        return hr;
1532
    }
1555
    }
1533
1556
1557
#ifndef SYNC_UPDATE
1558
    if(iface == This->resource.wineD3DDevice->ddraw_primary)
1559
    {
1560
        InitializeCriticalSection(&This->crit);
1561
        This->refresh_event = CreateEventW(NULL, TRUE, FALSE, NULL);
1562
        This->update_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1563
        This->update_thread = CreateThread(NULL, 0, User_update_thread, This, 0, NULL);
1564
    }
1565
#endif
1534
    return WINED3D_OK;
1566
    return WINED3D_OK;
1535
}
1567
}
1536
1568
1569
#ifndef SYNC_UPDATE
1570
static DWORD CALLBACK User_update_thread(LPVOID arg)
1571
{
1572
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)arg;
1573
    volatile HANDLE *pActive = (volatile HANDLE *)&This->update_event;
1574
    HANDLE event = *pActive;
1575
1576
    /* the point of this is that many games lock the primary surface
1577
     * multiple times per frame; this thread will then simply copy as
1578
     * often as it can without keeping the main thread waiting for
1579
    * each unlock, thus keeping the frame rate high */
1580
    do
1581
    {
1582
        DWORD ret = WaitForSingleObject(event, INFINITE);
1583
1584
        if (ret == WAIT_OBJECT_0)
1585
        {
1586
            if (*pActive)
1587
            {
1588
                This->in_refresh = TRUE;
1589
                x11_copy_to_screen(This, &This->dirtyRect);
1590
                EnterCriticalSection(&This->crit);
1591
                This->in_refresh = FALSE;
1592
                if (This->wait_count)
1593
                    SetEvent(This->refresh_event);
1594
                LeaveCriticalSection(&This->crit);
1595
            }
1596
            else break;
1597
        }
1598
        else if (ret != WAIT_OBJECT_0+1) break;
1599
    } while (TRUE);
1600
1601
    SetEvent(This->refresh_event);
1602
1603
    return 0;
1604
}
1605
1606
static int IWineGDISurface_init_wait(IWineD3DSurfaceImpl* This)
1607
{
1608
    int need_wait;
1609
    EnterCriticalSection(&This->crit);
1610
    This->wait_count++;
1611
    need_wait = This->in_refresh;
1612
    LeaveCriticalSection(&This->crit);
1613
    return need_wait;
1614
}
1615
1616
static void IWineGDISurface_end_wait(IWineD3DSurfaceImpl* This)
1617
{
1618
    EnterCriticalSection(&This->crit);
1619
    if (!--This->wait_count)
1620
        ResetEvent(This->refresh_event);
1621
    LeaveCriticalSection(&This->crit);
1622
}
1623
1624
static void IWineGDISurface_wait_update(IWineD3DSurfaceImpl* This)
1625
{
1626
    if (This->in_refresh) {
1627
        if (IWineGDISurface_init_wait(This))
1628
            WaitForSingleObject(This->refresh_event, 2);
1629
        IWineGDISurface_end_wait(This);
1630
    }
1631
}
1632
1633
#endif
1634
1537
const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
1635
const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
1538
{
1636
{
1539
    /* IUnknown */
1637
    /* IUnknown */
(-)a/dlls/wined3d/wined3d_private.h (-1 / +4 lines)
Lines 876-881 struct IWineD3DSurfaceImpl Link Here
876
    DDCOLORKEY                SrcBltCKey;
876
    DDCOLORKEY                SrcBltCKey;
877
    DWORD                     CKeyFlags;
877
    DWORD                     CKeyFlags;
878
878
879
    /* Async surface updates */
880
    HANDLE update_thread, update_event, refresh_event;
881
    CRITICAL_SECTION crit;
882
    volatile int wait_count, in_refresh;
879
};
883
};
880
884
881
extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl;
885
extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl;
882
- 

Return to bug 140805