mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 05:27:20 +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;
|
||||
ID3D11Texture2D * tex;
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
osEventHandle * readyEvent;
|
||||
}
|
||||
Texture;
|
||||
|
||||
@ -80,10 +79,12 @@ struct iface
|
||||
IDXGIOutputDuplication * dup;
|
||||
int maxTextures;
|
||||
Texture * texture;
|
||||
volatile int texRIndex;
|
||||
int texRIndex;
|
||||
int texWIndex;
|
||||
volatile int texReady;
|
||||
bool needsRelease;
|
||||
osEventHandle * pointerEvent;
|
||||
osEventHandle * frameEvent;
|
||||
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
@ -172,27 +173,20 @@ static bool dxgi_create()
|
||||
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");
|
||||
if (this->maxTextures <= 0)
|
||||
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->texture = calloc(sizeof(struct Texture), this->maxTextures);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -226,6 +220,7 @@ static bool dxgi_init(void * pointerShape, const unsigned int pointerSize)
|
||||
this->stop = false;
|
||||
this->texRIndex = 0;
|
||||
this->texWIndex = 0;
|
||||
this->texReady = 0;
|
||||
|
||||
status = CreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&this->factory);
|
||||
if (FAILED(status))
|
||||
@ -682,11 +677,12 @@ static CaptureResult dxgi_capture()
|
||||
|
||||
ID3D11Texture2D_Release(src);
|
||||
|
||||
// set the state and signal
|
||||
// set the state, and signal
|
||||
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)
|
||||
this->texWIndex = 0;
|
||||
|
||||
@ -760,10 +756,18 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
|
||||
assert(this);
|
||||
assert(this->initialized);
|
||||
|
||||
Texture * tex = &this->texture[INTERLOCKED_GET(&this->texRIndex)];
|
||||
if (!os_waitEvent(tex->readyEvent, 1000))
|
||||
// NOTE: the event may be signaled when there are no frames available
|
||||
if(this->texReady == 0)
|
||||
{
|
||||
if (!os_waitEvent(this->frameEvent, 1000))
|
||||
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
|
||||
HRESULT status;
|
||||
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->format = this->format;
|
||||
|
||||
os_resetEvent(tex->readyEvent);
|
||||
INTERLOCKED_DEC(&this->texReady);
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
|
||||
@ -793,14 +797,14 @@ static CaptureResult dxgi_getFrame(FrameBuffer frame)
|
||||
assert(this);
|
||||
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);
|
||||
LOCKED({ID3D11DeviceContext_Unmap(this->deviceContext, (ID3D11Resource*)tex->tex, 0);});
|
||||
tex->state = TEXTURE_STATE_UNUSED;
|
||||
|
||||
INTERLOCKED_INC(&this->texRIndex);
|
||||
INTERLOCKED_CE (&this->texRIndex, this->maxTextures, 0);
|
||||
if (++this->texRIndex == this->maxTextures)
|
||||
this->texRIndex = 0;
|
||||
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "interface/platform.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/option.h"
|
||||
#include "common/locking.h"
|
||||
#include "windows/debug.h"
|
||||
#include "ivshmem.h"
|
||||
|
||||
@ -72,6 +73,7 @@ struct osThreadHandle
|
||||
|
||||
struct osEventHandle
|
||||
{
|
||||
volatile int lock;
|
||||
bool reset;
|
||||
HANDLE handle;
|
||||
bool wrapped;
|
||||
@ -510,10 +512,13 @@ osEventHandle * os_createEvent(bool autoReset, unsigned int msSpinTime)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
event->lock = 0;
|
||||
event->reset = autoReset;
|
||||
event->handle = CreateEvent(NULL, autoReset ? FALSE : TRUE, FALSE, NULL);
|
||||
event->wrapped = false;
|
||||
event->msSpinTime = msSpinTime;
|
||||
event->handle = CreateEvent(NULL, autoReset ? FALSE : TRUE, FALSE, NULL);
|
||||
event->signaled = false;
|
||||
|
||||
if (!event->handle)
|
||||
{
|
||||
DEBUG_WINERROR("Failed to create the event", GetLastError());
|
||||
@ -533,10 +538,12 @@ osEventHandle * os_wrapEvent(HANDLE handle)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
event->lock = 0;
|
||||
event->reset = false;
|
||||
event->handle = event;
|
||||
event->wrapped = true;
|
||||
event->msSpinTime = 0;
|
||||
event->signaled = false;
|
||||
return event;
|
||||
}
|
||||
|
||||
@ -551,10 +558,19 @@ bool os_waitEvent(osEventHandle * event, unsigned int timeout)
|
||||
if (!event->wrapped)
|
||||
{
|
||||
if (event->signaled)
|
||||
{
|
||||
if (event->reset)
|
||||
event->signaled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
return event->signaled;
|
||||
{
|
||||
bool ret = event->signaled;
|
||||
if (event->reset)
|
||||
event->signaled = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (event->msSpinTime)
|
||||
{
|
||||
@ -581,9 +597,13 @@ bool os_waitEvent(osEventHandle * event, unsigned int timeout)
|
||||
}
|
||||
|
||||
if (event->signaled)
|
||||
{
|
||||
if (event->reset)
|
||||
event->signaled = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DWORD to = (timeout == TIMEOUT_INFINITE) ? INFINITE : (DWORD)timeout;
|
||||
while(true)
|
||||
|
Loading…
Reference in New Issue
Block a user