058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync/* $Id$ */
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync/** @file
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync *
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * VBox extension to Wine D3D
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync *
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * Copyright (C) 2011 Oracle Corporation
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync *
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * available from http://www.virtualbox.org. This file is free software;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * you can redistribute it and/or modify it under the terms of the GNU
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * General Public License (GPL) as published by the Free Software
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync */
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#ifndef ___VBOXEXT_H__
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define ___VBOXEXT_H__
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#ifdef VBOX_WINE_WITHOUT_LIBWINE
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync# include <windows.h>
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#endif
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#include <iprt/list.h>
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncHRESULT VBoxExtCheckInit();
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncHRESULT VBoxExtCheckTerm();
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync# ifndef VBOX_WITH_WDDM
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync/* Windows destroys HDC created by a given thread when the thread is terminated
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * this leads to a mess-up in Wine & Chromium code in some situations, e.g.
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * D3D device is created in one thread, then the thread is terminated,
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * then device is started to be used in another thread */
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncHDC VBoxExtGetDC(HWND hWnd);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncint VBoxExtReleaseDC(HWND hWnd, HDC hDC);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync# endif
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync/* We need to do a VBoxTlsRefRelease for the current thread context on thread exit to avoid memory leaking
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * Calling VBoxTlsRefRelease may result in a call to context dtor callback, which is supposed to be run under wined3d lock.
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * We can not acquire a wined3d lock in DllMain since this would result in a lock order violation, which may result in a deadlock.
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * In other words, wined3d may internally call Win32 API functions which result in a DLL lock acquisition while holding wined3d lock.
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * So lock order should always be "wined3d lock" -> "dll lock".
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync * To avoid possible deadlocks we make an asynchronous call to a worker thread to make a context release from there. */
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncvoid VBoxExtReleaseContextAsync(struct wined3d_context *context);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#endif
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync/* API for creating & destroying windows */
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncHRESULT VBoxExtWndDestroy(HWND hWnd, HDC hDC);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncHRESULT VBoxExtWndCreate(DWORD width, DWORD height, HWND *phWnd, HDC *phDC);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync/* hashmap */
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef DECLCALLBACK(uint32_t) FNVBOXEXT_HASHMAP_HASH(void *pvKey);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef FNVBOXEXT_HASHMAP_HASH *PFNVBOXEXT_HASHMAP_HASH;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef DECLCALLBACK(bool) FNVBOXEXT_HASHMAP_EQUAL(void *pvKey1, void *pvKey2);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef FNVBOXEXT_HASHMAP_EQUAL *PFNVBOXEXT_HASHMAP_EQUAL;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef DECLCALLBACK(bool) FNVBOXEXT_HASHMAP_VISITOR(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef FNVBOXEXT_HASHMAP_VISITOR *PFNVBOXEXT_HASHMAP_VISITOR;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef struct VBOXEXT_HASHMAP_ENTRY
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync RTLISTNODE ListNode;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync void *pvKey;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint32_t u32Hash;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync} VBOXEXT_HASHMAP_ENTRY, *PVBOXEXT_HASHMAP_ENTRY;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef struct VBOXEXT_HASHMAP_BUCKET
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync RTLISTNODE EntryList;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync} VBOXEXT_HASHMAP_BUCKET, *PVBOXEXT_HASHMAP_BUCKET;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXEXT_HASHMAP_NUM_BUCKETS 29
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef struct VBOXEXT_HASHMAP
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PFNVBOXEXT_HASHMAP_HASH pfnHash;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PFNVBOXEXT_HASHMAP_EQUAL pfnEqual;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint32_t cEntries;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXEXT_HASHMAP_BUCKET aBuckets[VBOXEXT_HASHMAP_NUM_BUCKETS];
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync} VBOXEXT_HASHMAP, *PVBOXEXT_HASHMAP;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncvoid VBoxExtHashInit(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_HASH pfnHash, PFNVBOXEXT_HASHMAP_EQUAL pfnEqual);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncPVBOXEXT_HASHMAP_ENTRY VBoxExtHashPut(PVBOXEXT_HASHMAP pMap, void *pvKey, PVBOXEXT_HASHMAP_ENTRY pEntry);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncPVBOXEXT_HASHMAP_ENTRY VBoxExtHashGet(PVBOXEXT_HASHMAP pMap, void *pvKey);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncPVBOXEXT_HASHMAP_ENTRY VBoxExtHashRemove(PVBOXEXT_HASHMAP pMap, void *pvKey);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncvoid* VBoxExtHashRemoveEntry(PVBOXEXT_HASHMAP pMap, PVBOXEXT_HASHMAP_ENTRY pEntry);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncvoid VBoxExtHashVisit(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_VISITOR pfnVisitor, void *pvVisitor);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncvoid VBoxExtHashCleanup(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_VISITOR pfnVisitor, void *pvVisitor);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncDECLINLINE(uint32_t) VBoxExtHashSize(PVBOXEXT_HASHMAP pMap)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return pMap->cEntries;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncDECLINLINE(void*) VBoxExtHashEntryKey(PVBOXEXT_HASHMAP_ENTRY pEntry)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return pEntry->pvKey;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef DECLCALLBACK(void) FNVBOXEXT_HASHCACHE_CLEANUP_ENTRY(void *pvKey, struct VBOXEXT_HASHCACHE_ENTRY *pEntry);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef FNVBOXEXT_HASHCACHE_CLEANUP_ENTRY *PFNVBOXEXT_HASHCACHE_CLEANUP_ENTRY;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef struct VBOXEXT_HASHCACHE_ENTRY
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXEXT_HASHMAP_ENTRY MapEntry;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint32_t u32Usage;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync} VBOXEXT_HASHCACHE_ENTRY, *PVBOXEXT_HASHCACHE_ENTRY;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef struct VBOXEXT_HASHCACHE
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXEXT_HASHMAP Map;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint32_t cMaxElements;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PFNVBOXEXT_HASHCACHE_CLEANUP_ENTRY pfnCleanupEntry;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync} VBOXEXT_HASHCACHE, *PVBOXEXT_HASHCACHE;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXEXT_HASHCACHE_FROM_MAP(_pMap) RT_FROM_MEMBER((_pMap), VBOXEXT_HASHCACHE, Map)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXEXT_HASHCACHE_ENTRY_FROM_MAP(_pEntry) RT_FROM_MEMBER((_pEntry), VBOXEXT_HASHCACHE_ENTRY, MapEntry)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncDECLINLINE(void) VBoxExtCacheInit(PVBOXEXT_HASHCACHE pCache, uint32_t cMaxElements,
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PFNVBOXEXT_HASHMAP_HASH pfnHash,
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PFNVBOXEXT_HASHMAP_EQUAL pfnEqual,
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PFNVBOXEXT_HASHCACHE_CLEANUP_ENTRY pfnCleanupEntry)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashInit(&pCache->Map, pfnHash, pfnEqual);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync pCache->cMaxElements = cMaxElements;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync pCache->pfnCleanupEntry = pfnCleanupEntry;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncDECLINLINE(PVBOXEXT_HASHCACHE_ENTRY) VBoxExtCacheGet(PVBOXEXT_HASHCACHE pCache, void *pvKey)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXEXT_HASHMAP_ENTRY pEntry = VBoxExtHashRemove(&pCache->Map, pvKey);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return VBOXEXT_HASHCACHE_ENTRY_FROM_MAP(pEntry);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncDECLINLINE(void) VBoxExtCachePut(PVBOXEXT_HASHCACHE pCache, void *pvKey, PVBOXEXT_HASHCACHE_ENTRY pEntry)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXEXT_HASHMAP_ENTRY pOldEntry = VBoxExtHashPut(&pCache->Map, pvKey, &pEntry->MapEntry);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXEXT_HASHCACHE_ENTRY pOld;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync if (!pOldEntry)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync pOld = VBOXEXT_HASHCACHE_ENTRY_FROM_MAP(pOldEntry);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync if (pOld != pEntry)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync pCache->pfnCleanupEntry(pvKey, pOld);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncvoid VBoxExtCacheCleanup(PVBOXEXT_HASHCACHE pCache);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncDECLINLINE(void) VBoxExtCacheTerm(PVBOXEXT_HASHCACHE pCache)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtCacheCleanup(pCache);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#ifdef VBOX_WINE_WITH_PROFILE
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#include <iprt/time.h>
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncvoid vboxWDbgPrintF(char * szString, ...);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_GET_TIME_NANO() RTTimeNanoTS()
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_GET_TIME_MILLI() RTTimeMilliTS()
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync# define PRLOG(_m) do {\
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync vboxWDbgPrintF _m ; \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef struct VBOXWINEPROFILE_ELEMENT
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint64_t u64Time;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint32_t cu32Calls;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync} VBOXWINEPROFILE_ELEMENT, *PVBOXWINEPROFILE_ELEMENT;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef struct VBOXWINEPROFILE_HASHMAP_ELEMENT
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXEXT_HASHMAP_ENTRY MapEntry;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_ELEMENT Data;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync} VBOXWINEPROFILE_HASHMAP_ELEMENT, *PVBOXWINEPROFILE_HASHMAP_ELEMENT;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(_p) ((PVBOXWINEPROFILE_HASHMAP_ELEMENT)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXWINEPROFILE_HASHMAP_ELEMENT, MapEntry)))
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_ELEMENT_DUMP(_p, _pn) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PRLOG(("%s: t(%u);c(%u)\n", \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync (_pn), \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync (uint32_t)((_p)->u64Time / 1000000), \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync (_p)->cu32Calls \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync )); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_ELEMENT_RESET(_p) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync memset(_p, 0, sizeof (*(_p))); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_ELEMENT_STEP(_p, _t) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync (_p)->u64Time += (_t); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync ++(_p)->cu32Calls; \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_HASHMAP_ELEMENT_CREATE() ( (PVBOXWINEPROFILE_HASHMAP_ELEMENT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (VBOXWINEPROFILE_HASHMAP_ELEMENT)) )
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_HASHMAP_ELEMENT_TERM(_pe) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync HeapFree(GetProcessHeap(), 0, (_pe)); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncDECLINLINE(PVBOXWINEPROFILE_HASHMAP_ELEMENT) vboxWineProfileHashMapElementGet(PVBOXEXT_HASHMAP pMap, void *pvKey)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXEXT_HASHMAP_ENTRY pEntry = VBoxExtHashGet(pMap, pvKey);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync if (pEntry)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync {
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pEntry);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync }
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync else
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync {
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_CREATE();
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync Assert(pElement);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync if (pElement)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashPut(pMap, pvKey, &pElement->MapEntry);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return pElement;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync }
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_HASHMAP_ELEMENT_STEP(_pm, _pk, _t) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = vboxWineProfileHashMapElementGet(_pm, _pk); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_ELEMENT_STEP(&pElement->Data, _t); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncstatic DECLCALLBACK(bool) vboxWineProfileElementResetCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_ELEMENT_RESET(&pElement->Data);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return true;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncstatic DECLCALLBACK(bool) vboxWineProfileElementDumpCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync char *pName = (char*)pvVisitor;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PRLOG(("%s[%d]:", pName, (uint32_t)pvKey));
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_ELEMENT_DUMP(&pElement->Data, "");
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return true;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_HASHMAP_RESET(_pm) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashVisit((_pm), vboxWineProfileElementResetCb, NULL); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_HASHMAP_DUMP(_pm, _pn) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashVisit((_pm), vboxWineProfileElementDumpCb, (_pn)); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncstatic DECLCALLBACK(bool) vboxWineProfileElementCleanupCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_ELEMENT_TERM(pElement);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return true;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_HASHMAP_TERM(_pm) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashCleanup((_pm), vboxWineProfileElementCleanupCb, NULL); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashVisit((_pm), vboxWineProfileElementResetCb, NULL); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsynctypedef struct VBOXWINEPROFILE_DRAWPRIM
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint64_t u64LoadLocationTime;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint64_t u64CtxAcquireTime;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint64_t u64PostProcess;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXEXT_HASHMAP MapDrawPrimSlowVs;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXEXT_HASHMAP MapDrawPrimSlow;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXEXT_HASHMAP MapDrawPrimStrided;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXEXT_HASHMAP MapDrawPrimFast;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync uint32_t cu32Calls;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync} VBOXWINEPROFILE_DRAWPRIM, *PVBOXWINEPROFILE_DRAWPRIM;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_DRAWPRIM_RESET_NEXT(_p) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync (_p)->u64LoadLocationTime = 0; \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync (_p)->u64CtxAcquireTime = 0; \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync (_p)->u64PostProcess = 0; \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimSlowVs); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimSlow); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimStrided); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimFast); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncstatic DECLCALLBACK(uint32_t) vboxWineProfileDrawPrimHashMapHash(void *pvKey)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return (uint32_t)pvKey;
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsyncstatic DECLCALLBACK(bool) vboxWineProfileDrawPrimHashMapEqual(void *pvKey1, void *pvKey2)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync{
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync return ((uint32_t)pvKey1) == ((uint32_t)pvKey2);
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync}
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_DRAWPRIM_INIT(_p) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync memset((_p), 0, sizeof (*(_p))); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashInit(&(_p)->MapDrawPrimSlowVs, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashInit(&(_p)->MapDrawPrimSlow, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashInit(&(_p)->MapDrawPrimStrided, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBoxExtHashInit(&(_p)->MapDrawPrimFast, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#define VBOXWINEPROFILE_DRAWPRIM_TERM(_p) do { \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync memset((_p), 0, sizeof (*(_p))); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimSlowVs); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimSlow); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimStrided); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimFast); \
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync } while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#else
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync# define PRLOG(_m) do {} while (0)
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#endif
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync
058c0c53c37f5cb271aeb3c385c10766f84f4aefvboxsync#endif /* #ifndef ___VBOXEXT_H__*/