Exemplo n.º 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;
   }
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
/**
 * XXX: Dispatch pipe_screen::flush_front_buffer to our 
 * stw_winsys::flush_front_buffer.
 */
static void 
stw_flush_frontbuffer(struct pipe_screen *screen,
                     struct pipe_surface *surface,
                     void *context_private )
{
   const struct stw_winsys *stw_winsys = stw_dev->stw_winsys;
   HDC hdc = (HDC)context_private;
   struct stw_framebuffer *fb;
   
   fb = stw_framebuffer_from_hdc( hdc );
   /* fb can be NULL if window was destroyed already */
   if (fb) {
#if DEBUG
      {
         struct pipe_surface *surface2;
   
         if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_FRONT_LEFT, &surface2 ))
            assert(0);
         else
            assert(surface2 == surface);
      }
#endif

#ifdef DEBUG
      if(stw_dev->trace_running) {
         screen = trace_screen(screen)->screen;
         surface = trace_surface(surface)->surface;
      }
#endif
   }
   
   stw_winsys->flush_frontbuffer(screen, surface, hdc);
   
   if(fb) {
      stw_framebuffer_update(fb);
      stw_framebuffer_release(fb);
   }
}
Exemplo n.º 4
0
BOOL
stw_make_current(
    HDC hdc,
    DHGLRC dhglrc )
{
    struct stw_context *curctx = NULL;
    struct stw_context *ctx = NULL;
    struct stw_framebuffer *fb = NULL;
    BOOL ret = FALSE;

    if (!stw_dev)
        return FALSE;

    curctx = stw_current_context();
    if (curctx != NULL) {
        if (curctx->dhglrc == dhglrc) {
            if (curctx->hdc == hdc) {
                /* Return if already current. */
                return TRUE;
            }
        } else {
            curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL);
        }
    }

    if (dhglrc) {
        pipe_mutex_lock( stw_dev->ctx_mutex );
        ctx = stw_lookup_context_locked( dhglrc );
        pipe_mutex_unlock( stw_dev->ctx_mutex );
        if (!ctx) {
            goto fail;
        }

        fb = stw_framebuffer_from_hdc( hdc );
        if (fb) {
            stw_framebuffer_update(fb);
        }
        else {
            /* Applications should call SetPixelFormat before creating a context,
             * but not all do, and the opengl32 runtime seems to use a default pixel
             * format in some cases, so we must create a framebuffer for those here
             */
            int iPixelFormat = GetPixelFormat(hdc);
            if (iPixelFormat)
                fb = stw_framebuffer_create( hdc, iPixelFormat );
            if (!fb)
                goto fail;
        }

        if (fb->iPixelFormat != ctx->iPixelFormat) {
            SetLastError(ERROR_INVALID_PIXEL_FORMAT);
            goto fail;
        }

        /* Bind the new framebuffer */
        ctx->hdc = hdc;

        ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
                                           fb->stfb, fb->stfb);
        stw_framebuffer_reference(&ctx->current_framebuffer, fb);
    } else {
        ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
    }

fail:

    if (fb) {
        stw_framebuffer_release(fb);
    }

    /* On failure, make the thread's current rendering context not current
     * before returning */
    if (!ret) {
        stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
        ctx = NULL;
    }

    /* Unreference the previous framebuffer if any. It must be done after
     * make_current, as it can be referenced inside.
     */
    if (curctx && curctx != ctx) {
        stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
    }

    return ret;
}