On 5/18/22 01:49, Zhiyi Zhang wrote:
@@ -1046,6 +1060,135 @@ HRESULT CDECL wined3d_adapter_get_video_memory_info(const struct wined3d_adapter return WINED3D_OK; }
+static DWORD CALLBACK notification_thread_func(void *stop_event) +{
- struct wined3d_adapter_budget_change_notification *notification;
- struct wined3d_video_memory_info info;
- HRESULT hr;
- while (TRUE)
- {
wined3d_mutex_lock();
LIST_FOR_EACH_ENTRY(notification, &adapter_budget_change_notifications,
struct wined3d_adapter_budget_change_notification, entry)
{
hr = wined3d_adapter_get_video_memory_info(notification->adapter, 0,
WINED3D_MEMORY_SEGMENT_GROUP_LOCAL, &info);
if (SUCCEEDED(hr) && info.budget != notification->last_local_budget)
{
notification->last_local_budget = info.budget;
SetEvent(notification->event);
continue;
}
hr = wined3d_adapter_get_video_memory_info(notification->adapter, 0,
WINED3D_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info);
if (SUCCEEDED(hr) && info.budget != notification->last_non_local_budget)
{
notification->last_non_local_budget = info.budget;
SetEvent(notification->event);
}
}
wined3d_mutex_unlock();
if (WaitForSingleObject(stop_event, 1000) == WAIT_OBJECT_0)
break;
The test also waits for 1 second, which seems like it'd be liable to fail intermittently, if I read this correctly. Should we increase the polling interval here? (Or reduce it in the test?)
- }
- return TRUE;
+}
+HRESULT CDECL wined3d_adapter_register_budget_change_notification(const struct wined3d_adapter *adapter,
HANDLE event, DWORD *cookie)
+{
- static DWORD cookie_counter;
- static BOOL wrapped;
- struct wined3d_adapter_budget_change_notification *notification, *new_notification;
- HANDLE thread = NULL;
- BOOL found = FALSE;
- new_notification = heap_alloc_zero(sizeof(*new_notification));
- if (!new_notification)
return E_OUTOFMEMORY;
- wined3d_mutex_lock();
- new_notification->adapter = adapter;
- new_notification->event = event;
- new_notification->cookie = cookie_counter++;
- if (cookie_counter < new_notification->cookie)
wrapped = TRUE;
- if (wrapped)
- {
while (TRUE)
{
LIST_FOR_EACH_ENTRY(notification, &adapter_budget_change_notifications,
struct wined3d_adapter_budget_change_notification, entry)
{
if (notification->cookie == new_notification->cookie)
{
found = TRUE;
break;
}
}
if (!found)
break;
new_notification->cookie = cookie_counter++;
}
- }
- *cookie = new_notification->cookie;
- list_add_head(&adapter_budget_change_notifications, &new_notification->entry);
- if (!notification_thread)
- {
notification_thread_stop_event = CreateEventW(0, FALSE, FALSE, NULL);
thread = CreateThread(NULL, 0, notification_thread_func, notification_thread_stop_event,
CREATE_SUSPENDED, NULL);
notification_thread = thread;
- }
- wined3d_mutex_unlock();
- if (thread)
ResumeThread(thread);
What's the reason for creating the thread suspended?
- return WINED3D_OK;
+}