mirror of
				https://github.com/gnif/LookingGlass.git
				synced 2025-10-31 12:42:02 +00:00 
			
		
		
		
	[c-host] dxgi: futher event improvements
This commit is contained in:
		| @@ -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,9 +756,17 @@ 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)) | ||||
|     return CAPTURE_RESULT_TIMEOUT; | ||||
|   // 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; | ||||
| @@ -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,7 +597,11 @@ bool os_waitEvent(osEventHandle * event, unsigned int timeout) | ||||
|       } | ||||
|  | ||||
|       if (event->signaled) | ||||
|       { | ||||
|         if (event->reset) | ||||
|           event->signaled = false; | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Geoffrey McRae
					Geoffrey McRae