mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 13:37:22 +00:00
[c-host] dxgi: futher event improvements
This commit is contained in:
parent
9c5f9906fa
commit
c82a5e0523
@ -46,7 +46,6 @@ typedef struct Texture
|
|||||||
enum TextureState state;
|
enum TextureState state;
|
||||||
ID3D11Texture2D * tex;
|
ID3D11Texture2D * tex;
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
osEventHandle * readyEvent;
|
|
||||||
}
|
}
|
||||||
Texture;
|
Texture;
|
||||||
|
|
||||||
@ -80,10 +79,12 @@ struct iface
|
|||||||
IDXGIOutputDuplication * dup;
|
IDXGIOutputDuplication * dup;
|
||||||
int maxTextures;
|
int maxTextures;
|
||||||
Texture * texture;
|
Texture * texture;
|
||||||
volatile int texRIndex;
|
int texRIndex;
|
||||||
int texWIndex;
|
int texWIndex;
|
||||||
|
volatile int texReady;
|
||||||
bool needsRelease;
|
bool needsRelease;
|
||||||
osEventHandle * pointerEvent;
|
osEventHandle * pointerEvent;
|
||||||
|
osEventHandle * frameEvent;
|
||||||
|
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
@ -172,27 +173,20 @@ static bool dxgi_create()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->frameEvent = os_createEvent(true, 17); // 60Hz = 16.7ms
|
||||||
|
if (!this->frameEvent)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("failed to create the frame event");
|
||||||
|
free(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
this->maxTextures = option_get_int("dxgi", "maxTextures");
|
this->maxTextures = option_get_int("dxgi", "maxTextures");
|
||||||
if (this->maxTextures <= 0)
|
if (this->maxTextures <= 0)
|
||||||
this->maxTextures = 1;
|
this->maxTextures = 1;
|
||||||
|
|
||||||
this->texture = calloc(sizeof(struct Texture), this->maxTextures);
|
|
||||||
for(int i = 0; i < this->maxTextures; ++i)
|
|
||||||
{
|
|
||||||
this->texture[i].readyEvent = os_createEvent(false, 30);
|
|
||||||
if (!this->texture[i].readyEvent)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("failed to create the texture event");
|
|
||||||
|
|
||||||
for(int x = 0; x < i; ++x)
|
|
||||||
os_freeEvent(this->texture[x].readyEvent);
|
|
||||||
|
|
||||||
free(this->texture);
|
|
||||||
free(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->useAcquireLock = option_get_bool("dxgi", "useAcquireLock");
|
this->useAcquireLock = option_get_bool("dxgi", "useAcquireLock");
|
||||||
|
this->texture = calloc(sizeof(struct Texture), this->maxTextures);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,6 +220,7 @@ static bool dxgi_init(void * pointerShape, const unsigned int pointerSize)
|
|||||||
this->stop = false;
|
this->stop = false;
|
||||||
this->texRIndex = 0;
|
this->texRIndex = 0;
|
||||||
this->texWIndex = 0;
|
this->texWIndex = 0;
|
||||||
|
this->texReady = 0;
|
||||||
|
|
||||||
status = CreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&this->factory);
|
status = CreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&this->factory);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
@ -682,11 +677,12 @@ static CaptureResult dxgi_capture()
|
|||||||
|
|
||||||
ID3D11Texture2D_Release(src);
|
ID3D11Texture2D_Release(src);
|
||||||
|
|
||||||
// set the state and signal
|
// set the state, and signal
|
||||||
tex->state = TEXTURE_STATE_PENDING_MAP;
|
tex->state = TEXTURE_STATE_PENDING_MAP;
|
||||||
os_signalEvent(tex->readyEvent);
|
INTERLOCKED_INC(&this->texReady);
|
||||||
|
os_signalEvent(this->frameEvent);
|
||||||
|
|
||||||
// advance our write pointer
|
// advance the write index
|
||||||
if (++this->texWIndex == this->maxTextures)
|
if (++this->texWIndex == this->maxTextures)
|
||||||
this->texWIndex = 0;
|
this->texWIndex = 0;
|
||||||
|
|
||||||
@ -760,10 +756,18 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
|
|||||||
assert(this);
|
assert(this);
|
||||||
assert(this->initialized);
|
assert(this->initialized);
|
||||||
|
|
||||||
Texture * tex = &this->texture[INTERLOCKED_GET(&this->texRIndex)];
|
// NOTE: the event may be signaled when there are no frames available
|
||||||
if (!os_waitEvent(tex->readyEvent, 1000))
|
if(this->texReady == 0)
|
||||||
|
{
|
||||||
|
if (!os_waitEvent(this->frameEvent, 1000))
|
||||||
return CAPTURE_RESULT_TIMEOUT;
|
return CAPTURE_RESULT_TIMEOUT;
|
||||||
|
|
||||||
|
if (this->texReady == 0)
|
||||||
|
return CAPTURE_RESULT_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture * tex = &this->texture[this->texRIndex];
|
||||||
|
|
||||||
// try to map the resource, but don't wait for it
|
// try to map the resource, but don't wait for it
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
LOCKED({status = ID3D11DeviceContext_Map(this->deviceContext, (ID3D11Resource*)tex->tex, 0, D3D11_MAP_READ, 0x100000L, &tex->map);});
|
LOCKED({status = ID3D11DeviceContext_Map(this->deviceContext, (ID3D11Resource*)tex->tex, 0, D3D11_MAP_READ, 0x100000L, &tex->map);});
|
||||||
@ -784,7 +788,7 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
|
|||||||
frame->stride = this->stride;
|
frame->stride = this->stride;
|
||||||
frame->format = this->format;
|
frame->format = this->format;
|
||||||
|
|
||||||
os_resetEvent(tex->readyEvent);
|
INTERLOCKED_DEC(&this->texReady);
|
||||||
return CAPTURE_RESULT_OK;
|
return CAPTURE_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,14 +797,14 @@ static CaptureResult dxgi_getFrame(FrameBuffer frame)
|
|||||||
assert(this);
|
assert(this);
|
||||||
assert(this->initialized);
|
assert(this->initialized);
|
||||||
|
|
||||||
Texture * tex = &this->texture[INTERLOCKED_GET(&this->texRIndex)];
|
Texture * tex = &this->texture[this->texRIndex];
|
||||||
|
|
||||||
framebuffer_write(frame, tex->map.pData, this->pitch * this->height);
|
framebuffer_write(frame, tex->map.pData, this->pitch * this->height);
|
||||||
LOCKED({ID3D11DeviceContext_Unmap(this->deviceContext, (ID3D11Resource*)tex->tex, 0);});
|
LOCKED({ID3D11DeviceContext_Unmap(this->deviceContext, (ID3D11Resource*)tex->tex, 0);});
|
||||||
tex->state = TEXTURE_STATE_UNUSED;
|
tex->state = TEXTURE_STATE_UNUSED;
|
||||||
|
|
||||||
INTERLOCKED_INC(&this->texRIndex);
|
if (++this->texRIndex == this->maxTextures)
|
||||||
INTERLOCKED_CE (&this->texRIndex, this->maxTextures, 0);
|
this->texRIndex = 0;
|
||||||
|
|
||||||
return CAPTURE_RESULT_OK;
|
return CAPTURE_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "interface/platform.h"
|
#include "interface/platform.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
|
#include "common/locking.h"
|
||||||
#include "windows/debug.h"
|
#include "windows/debug.h"
|
||||||
#include "ivshmem.h"
|
#include "ivshmem.h"
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ struct osThreadHandle
|
|||||||
|
|
||||||
struct osEventHandle
|
struct osEventHandle
|
||||||
{
|
{
|
||||||
|
volatile int lock;
|
||||||
bool reset;
|
bool reset;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
bool wrapped;
|
bool wrapped;
|
||||||
@ -510,10 +512,13 @@ osEventHandle * os_createEvent(bool autoReset, unsigned int msSpinTime)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event->lock = 0;
|
||||||
event->reset = autoReset;
|
event->reset = autoReset;
|
||||||
|
event->handle = CreateEvent(NULL, autoReset ? FALSE : TRUE, FALSE, NULL);
|
||||||
event->wrapped = false;
|
event->wrapped = false;
|
||||||
event->msSpinTime = msSpinTime;
|
event->msSpinTime = msSpinTime;
|
||||||
event->handle = CreateEvent(NULL, autoReset ? FALSE : TRUE, FALSE, NULL);
|
event->signaled = false;
|
||||||
|
|
||||||
if (!event->handle)
|
if (!event->handle)
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to create the event", GetLastError());
|
DEBUG_WINERROR("Failed to create the event", GetLastError());
|
||||||
@ -533,10 +538,12 @@ osEventHandle * os_wrapEvent(HANDLE handle)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event->lock = 0;
|
||||||
event->reset = false;
|
event->reset = false;
|
||||||
event->handle = event;
|
event->handle = event;
|
||||||
event->wrapped = true;
|
event->wrapped = true;
|
||||||
event->msSpinTime = 0;
|
event->msSpinTime = 0;
|
||||||
|
event->signaled = false;
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,10 +558,19 @@ bool os_waitEvent(osEventHandle * event, unsigned int timeout)
|
|||||||
if (!event->wrapped)
|
if (!event->wrapped)
|
||||||
{
|
{
|
||||||
if (event->signaled)
|
if (event->signaled)
|
||||||
|
{
|
||||||
|
if (event->reset)
|
||||||
|
event->signaled = false;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (timeout == 0)
|
if (timeout == 0)
|
||||||
return event->signaled;
|
{
|
||||||
|
bool ret = event->signaled;
|
||||||
|
if (event->reset)
|
||||||
|
event->signaled = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (event->msSpinTime)
|
if (event->msSpinTime)
|
||||||
{
|
{
|
||||||
@ -581,9 +597,13 @@ bool os_waitEvent(osEventHandle * event, unsigned int timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event->signaled)
|
if (event->signaled)
|
||||||
|
{
|
||||||
|
if (event->reset)
|
||||||
|
event->signaled = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const DWORD to = (timeout == TIMEOUT_INFINITE) ? INFINITE : (DWORD)timeout;
|
const DWORD to = (timeout == TIMEOUT_INFINITE) ? INFINITE : (DWORD)timeout;
|
||||||
while(true)
|
while(true)
|
||||||
|
Loading…
Reference in New Issue
Block a user