示例#1
0
/**
 * Queue a composition.
 *
 * The stw_framebuffer object must have its mutex locked.  The mutex will
 * be unlocked here before returning.
 */
BOOL
stw_framebuffer_present_locked(HDC hdc,
                               struct stw_framebuffer *fb,
                               struct pipe_resource *res)
{
   if (stw_dev->callbacks.wglCbPresentBuffers &&
      stw_dev->stw_winsys->compose) {
      GLCBPRESENTBUFFERSDATA data;

      memset(&data, 0, sizeof data);
      data.magic1 = 2;
      data.magic2 = 0;
      data.AdapterLuid = stw_dev->AdapterLuid;
      data.rect = fb->client_rect;
      data.pPrivateData = (void *)res;

      stw_notify_current_locked(fb);
      stw_framebuffer_unlock(fb);

      return stw_dev->callbacks.wglCbPresentBuffers(hdc, &data);
   }
   else {
      struct pipe_screen *screen = stw_dev->screen;

      stw_dev->stw_winsys->present( screen, res, hdc );

      stw_framebuffer_update(fb);
      stw_notify_current_locked(fb);
      stw_framebuffer_unlock(fb);

      return TRUE;
   }
}
示例#2
0
BOOL APIENTRY
DrvSetPixelFormat(HDC hdc, LONG iPixelFormat)
{
   uint count;
   uint index;
   struct stw_framebuffer *fb;

   if (!stw_dev)
      return FALSE;

   index = (uint) iPixelFormat - 1;
   count = stw_pixelformat_get_count();
   if (index >= count)
      return FALSE;

   fb = stw_framebuffer_from_hdc_locked(hdc);
   if (fb) {
      /*
       * SetPixelFormat must be called only once.  However ignore
       * pbuffers, for which the framebuffer object is created first.
       */
      boolean bPbuffer = fb->bPbuffer;

      stw_framebuffer_unlock( fb );

      return bPbuffer;
   }

   fb = stw_framebuffer_create(hdc, iPixelFormat);
   if (!fb) {
      return FALSE;
   }

   stw_framebuffer_unlock( fb );

   /* Some applications mistakenly use the undocumented wglSetPixelFormat
    * function instead of SetPixelFormat, so we call SetPixelFormat here to
    * avoid opengl32.dll's wglCreateContext to fail */
   if (GetPixelFormat(hdc) == 0) {
      BOOL bRet = SetPixelFormat(hdc, iPixelFormat, NULL);
      if (!bRet) {
	  debug_printf("SetPixelFormat failed\n");
      }
   }

   return TRUE;
}
示例#3
0
BOOL APIENTRY
DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
{
   struct stw_framebuffer *fb;
   struct pipe_screen *screen;
   struct pipe_resource *res;

   if (!stw_dev)
      return FALSE;

   fb = stw_framebuffer_from_hdc( hdc );
   if (fb == NULL)
      return FALSE;

   screen = stw_dev->screen;

   res = (struct pipe_resource *)data->pPrivateData;

   if (data->hSharedSurface != fb->hSharedSurface) {
      if (fb->shared_surface) {
         stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface);
         fb->shared_surface = NULL;
      }

      fb->hSharedSurface = data->hSharedSurface;

      if (data->hSharedSurface &&
         stw_dev->stw_winsys->shared_surface_open) {
         fb->shared_surface =
            stw_dev->stw_winsys->shared_surface_open(screen,
                                                     fb->hSharedSurface);
      }
   }

   if (!fb->minimized) {
      if (fb->shared_surface) {
         stw_dev->stw_winsys->compose(screen,
                                      res,
                                      fb->shared_surface,
                                      &fb->client_rect,
                                      data->PresentHistoryToken);
      }
      else {
         stw_dev->stw_winsys->present( screen, res, hdc );
      }
   }

   stw_framebuffer_update(fb);
   stw_notify_current_locked(fb);

   stw_framebuffer_unlock(fb);

   return TRUE;
}
示例#4
0
/**
 * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
 * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
 */
LRESULT CALLBACK
stw_call_window_proc(int nCode, WPARAM wParam, LPARAM lParam)
{
   struct stw_tls_data *tls_data;
   PCWPSTRUCT pParams = (PCWPSTRUCT)lParam;
   struct stw_framebuffer *fb;

   tls_data = stw_tls_get_data();
   if (!tls_data)
      return 0;

   if (nCode < 0 || !stw_dev)
       return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);

   /* We check that the stw_dev object is initialized before we try to do
    * anything with it.  Otherwise, in multi-threaded programs there's a
    * chance of executing this code before the stw_dev object is fully
    * initialized.
    */
   if (stw_dev && stw_dev->initialized) {
      if (pParams->message == WM_WINDOWPOSCHANGED) {
         /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according
          * to http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
          * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it
          * can be masked out by the application.
          */
         LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam;
         if ((lpWindowPos->flags & SWP_SHOWWINDOW) ||
             !(lpWindowPos->flags & SWP_NOMOVE) ||
             !(lpWindowPos->flags & SWP_NOSIZE)) {
            fb = stw_framebuffer_from_hwnd( pParams->hwnd );
            if (fb) {
               /* Size in WINDOWPOS includes the window frame, so get the size
                * of the client area via GetClientRect.
                */
               stw_framebuffer_get_size(fb);
               stw_framebuffer_unlock(fb);
            }
         }
      }
      else if (pParams->message == WM_DESTROY) {
         stw_lock_framebuffers(stw_dev);
         fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
         if (fb)
            stw_framebuffer_release_locked(fb);
         stw_unlock_framebuffers(stw_dev);
      }
   }

   return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
}
示例#5
0
int
stw_pixelformat_get(HDC hdc)
{
   int iPixelFormat = 0;
   struct stw_framebuffer *fb;

   fb = stw_framebuffer_from_hdc(hdc);
   if (fb) {
      iPixelFormat = fb->iPixelFormat;
      stw_framebuffer_unlock(fb);
   }

   return iPixelFormat;
}
示例#6
0
/**
 * Decrement the reference count on the given stw_framebuffer object.
 * If the reference count hits zero, destroy the object.
 *
 * Note: Both stw_dev::fb_mutex and stw_framebuffer::mutex must already be
 * locked.  After this function completes, the fb's mutex will be unlocked.
 */
void
stw_framebuffer_release_locked(struct stw_framebuffer *fb)
{
   struct stw_framebuffer **link;

   assert(fb);
   assert(stw_own_mutex(&fb->mutex));
   assert(stw_own_mutex(&stw_dev->fb_mutex));

   /* check the reference count */
   fb->refcnt--;
   if (fb->refcnt) {
      stw_framebuffer_unlock(fb);
      return;
   }

   /* remove this stw_framebuffer from the device's linked list */
   link = &stw_dev->fb_head;
   while (*link != fb)
      link = &(*link)->next;
   assert(*link);
   *link = fb->next;
   fb->next = NULL;

   if (fb->shared_surface)
      stw_dev->stw_winsys->shared_surface_close(stw_dev->screen,
                                                fb->shared_surface);

   stw_st_destroy_framebuffer_locked(fb->stfb);

   stw_framebuffer_unlock(fb);

   DeleteCriticalSection(&fb->mutex);

   FREE( fb );
}
示例#7
0
BOOL APIENTRY
DrvSwapBuffers(HDC hdc)
{
   struct stw_context *ctx;
   struct stw_framebuffer *fb;

   if (!stw_dev)
      return FALSE;

   fb = stw_framebuffer_from_hdc( hdc );
   if (fb == NULL)
      return FALSE;

   if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) {
      stw_framebuffer_unlock(fb);
      return TRUE;
   }

   ctx = stw_current_context();
   if (ctx) {
      if (ctx->hud) {
         /* Display the HUD */
         struct pipe_resource *back =
            stw_get_framebuffer_resource(fb->stfb, ST_ATTACHMENT_BACK_LEFT);
         if (back) {
            hud_draw(ctx->hud, back);
         }
      }

      if (ctx->current_framebuffer == fb) {
         /* flush current context */
         ctx->st->flush(ctx->st, ST_FLUSH_END_OF_FRAME, NULL);
      }
   }

   if (stw_dev->swap_interval != 0) {
      wait_swap_interval(fb);
   }

   return stw_st_swap_framebuffer_locked(hdc, fb->stfb);
}