mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 14:57:20 +00:00
[c-host] dxgi: allow out of order frame mapping
This commit is contained in:
parent
438e9e0969
commit
5e201a32ca
@ -42,7 +42,8 @@ typedef struct Texture
|
|||||||
enum TextureState state;
|
enum TextureState state;
|
||||||
ID3D11Texture2D * tex;
|
ID3D11Texture2D * tex;
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
osEventHandle * evt;
|
osEventHandle * mapped;
|
||||||
|
osEventHandle * free;
|
||||||
}
|
}
|
||||||
Texture;
|
Texture;
|
||||||
|
|
||||||
@ -75,7 +76,6 @@ struct iface
|
|||||||
int texRIndex;
|
int texRIndex;
|
||||||
int texWIndex;
|
int texWIndex;
|
||||||
bool needsRelease;
|
bool needsRelease;
|
||||||
osEventHandle * frameEvent;
|
|
||||||
osEventHandle * pointerEvent;
|
osEventHandle * pointerEvent;
|
||||||
|
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
@ -132,7 +132,7 @@ static void dxgi_initOptions()
|
|||||||
.name = "maxTextures",
|
.name = "maxTextures",
|
||||||
.description = "The maximum number of frames to buffer before skipping",
|
.description = "The maximum number of frames to buffer before skipping",
|
||||||
.type = OPTION_TYPE_INT,
|
.type = OPTION_TYPE_INT,
|
||||||
.value.x_int = 1
|
.value.x_int = 3
|
||||||
},
|
},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
@ -150,19 +150,10 @@ static bool dxgi_create()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->frameEvent = os_createEvent(true);
|
|
||||||
if (!this->frameEvent)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("failed to create the frame event");
|
|
||||||
free(this);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->pointerEvent = os_createEvent(true);
|
this->pointerEvent = os_createEvent(true);
|
||||||
if (!this->pointerEvent)
|
if (!this->pointerEvent)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("failed to create the pointer event");
|
DEBUG_ERROR("failed to create the pointer event");
|
||||||
os_freeEvent(this->frameEvent);
|
|
||||||
free(this);
|
free(this);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -205,7 +196,6 @@ 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;
|
||||||
os_resetEvent(this->frameEvent);
|
|
||||||
|
|
||||||
status = CreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&this->factory);
|
status = CreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&this->factory);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
@ -462,15 +452,22 @@ static bool dxgi_init(void * pointerShape, const unsigned int pointerSize)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->texture[i].evt = os_createEvent(true);
|
this->texture[i].free = os_createEvent(true);
|
||||||
if (!this->texture[i].evt)
|
if (!this->texture[i].free)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to create the texture event");
|
DEBUG_ERROR("Failed to create the texture free event");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pre-signal the events to flag as unused
|
// pre-signal the free events to flag as unused
|
||||||
os_signalEvent(this->texture[i].evt);
|
os_signalEvent(this->texture[i].free);
|
||||||
|
|
||||||
|
this->texture[i].mapped = os_createEvent(false);
|
||||||
|
if (!this->texture[i].mapped)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to create the texture mapped event");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// map the texture simply to get the pitch and stride
|
// map the texture simply to get the pitch and stride
|
||||||
@ -496,7 +493,8 @@ fail:
|
|||||||
static void dxgi_stop()
|
static void dxgi_stop()
|
||||||
{
|
{
|
||||||
this->stop = true;
|
this->stop = true;
|
||||||
os_signalEvent(this->frameEvent );
|
|
||||||
|
os_signalEvent(this->texture[this->texRIndex].mapped);
|
||||||
os_signalEvent(this->pointerEvent);
|
os_signalEvent(this->pointerEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,11 +518,18 @@ static bool dxgi_deinit()
|
|||||||
this->texture[i].tex = NULL;
|
this->texture[i].tex = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->texture[i].evt)
|
if (this->texture[i].free)
|
||||||
{
|
{
|
||||||
os_signalEvent(this->texture[i].evt);
|
os_signalEvent(this->texture[i].free);
|
||||||
os_freeEvent(this->texture[i].evt);
|
os_freeEvent(this->texture[i].free);
|
||||||
this->texture[i].evt = NULL;
|
this->texture[i].free = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->texture[i].mapped)
|
||||||
|
{
|
||||||
|
os_signalEvent(this->texture[i].mapped);
|
||||||
|
os_freeEvent(this->texture[i].mapped);
|
||||||
|
this->texture[i].mapped = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,7 +587,6 @@ static void dxgi_free()
|
|||||||
if (this->initialized)
|
if (this->initialized)
|
||||||
dxgi_deinit();
|
dxgi_deinit();
|
||||||
|
|
||||||
os_freeEvent(this->frameEvent );
|
|
||||||
os_freeEvent(this->pointerEvent);
|
os_freeEvent(this->pointerEvent);
|
||||||
free(this->texture);
|
free(this->texture);
|
||||||
|
|
||||||
@ -609,9 +613,12 @@ static CaptureResult dxgi_capture()
|
|||||||
IDXGIResource * res;
|
IDXGIResource * res;
|
||||||
|
|
||||||
// if the read texture is pending a mapping
|
// if the read texture is pending a mapping
|
||||||
if (this->texture[this->texRIndex].state == TEXTURE_STATE_PENDING_MAP)
|
for(int i = 0; i < this->maxTextures; ++i)
|
||||||
{
|
{
|
||||||
Texture * tex = &this->texture[this->texRIndex];
|
if (this->texture[i].state != TEXTURE_STATE_PENDING_MAP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Texture * tex = &this->texture[i];
|
||||||
|
|
||||||
// try to map the resource, but don't wait for it
|
// try to map the resource, but don't wait for it
|
||||||
status = ID3D11DeviceContext_Map(this->deviceContext, (ID3D11Resource*)tex->tex, 0, D3D11_MAP_READ, 0x100000L, &tex->map);
|
status = ID3D11DeviceContext_Map(this->deviceContext, (ID3D11Resource*)tex->tex, 0, D3D11_MAP_READ, 0x100000L, &tex->map);
|
||||||
@ -627,7 +634,7 @@ static CaptureResult dxgi_capture()
|
|||||||
|
|
||||||
// successful map, set the state and signal that there is a frame available
|
// successful map, set the state and signal that there is a frame available
|
||||||
tex->state = TEXTURE_STATE_MAPPED;
|
tex->state = TEXTURE_STATE_MAPPED;
|
||||||
os_signalEvent(this->frameEvent);
|
os_signalEvent(tex->mapped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,7 +667,7 @@ static CaptureResult dxgi_capture()
|
|||||||
Texture * tex = &this->texture[this->texWIndex];
|
Texture * tex = &this->texture[this->texWIndex];
|
||||||
|
|
||||||
// check if the texture is free, if not skip the frame to keep up
|
// check if the texture is free, if not skip the frame to keep up
|
||||||
if (!os_waitEvent(tex->evt, 0))
|
if (!os_waitEvent(tex->free, 0))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
NOTE: This is only informational for when debugging, skipping frames is
|
NOTE: This is only informational for when debugging, skipping frames is
|
||||||
@ -766,16 +773,18 @@ static CaptureResult dxgi_getFrame(CaptureFrame * frame)
|
|||||||
assert(this);
|
assert(this);
|
||||||
assert(this->initialized);
|
assert(this->initialized);
|
||||||
|
|
||||||
if (!os_waitEvent(this->frameEvent, TIMEOUT_INFINITE))
|
Texture * tex = &this->texture[this->texRIndex];
|
||||||
|
if (!os_waitEvent(tex->mapped, TIMEOUT_INFINITE))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to wait on the frame event");
|
DEBUG_ERROR("Failed to wait on the texture map event");
|
||||||
return CAPTURE_RESULT_ERROR;
|
return CAPTURE_RESULT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->stop)
|
if (this->stop)
|
||||||
return CAPTURE_RESULT_REINIT;
|
return CAPTURE_RESULT_REINIT;
|
||||||
|
|
||||||
Texture * tex = &this->texture[this->texRIndex];
|
// only reset the event if we used the texture
|
||||||
|
os_resetEvent(tex->mapped);
|
||||||
|
|
||||||
frame->width = this->width;
|
frame->width = this->width;
|
||||||
frame->height = this->height;
|
frame->height = this->height;
|
||||||
@ -784,7 +793,7 @@ static CaptureResult dxgi_getFrame(CaptureFrame * frame)
|
|||||||
frame->format = this->format;
|
frame->format = this->format;
|
||||||
|
|
||||||
memcpy(frame->data, tex->map.pData, this->pitch * this->height);
|
memcpy(frame->data, tex->map.pData, this->pitch * this->height);
|
||||||
os_signalEvent(tex->evt);
|
os_signalEvent(tex->free);
|
||||||
|
|
||||||
if (++this->texRIndex == this->maxTextures)
|
if (++this->texRIndex == this->maxTextures)
|
||||||
this->texRIndex = 0;
|
this->texRIndex = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user