示例#1
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;
}
示例#2
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;
}
示例#3
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);
}
示例#4
0
BOOL APIENTRY
DrvSwapBuffers(
   HDC hdc )
{
   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_release(fb);
      return TRUE;
   }

   stw_flush_current_locked(fb);

   return stw_st_swap_framebuffer_locked(hdc, fb->stfb);
}
示例#5
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);
   }
}
示例#6
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;
}
示例#7
0
/**
 * Called via DrvCreateContext(), DrvCreateLayerContext() and
 * wglCreateContextAttribsARB() to actually create a rendering context.
 * \param handle  the desired DHGLRC handle to use for the context, or zero
 *                if a new handle should be allocated.
 * \return the handle for the new context or zero if there was a problem.
 */
DHGLRC
stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
                           int majorVersion, int minorVersion,
                           int contextFlags, int profileMask,
                           DHGLRC handle)
{
    int iPixelFormat;
    struct stw_framebuffer *fb;
    const struct stw_pixelformat_info *pfi;
    struct st_context_attribs attribs;
    struct stw_context *ctx = NULL;
    struct stw_context *shareCtx = NULL;
    enum st_context_error ctx_err = 0;

    if (!stw_dev)
        return 0;

    if (iLayerPlane != 0)
        return 0;

    iPixelFormat = GetPixelFormat(hdc);
    if(!iPixelFormat)
        return 0;

    /*
     * GDI only knows about displayable pixel formats, so determine the pixel
     * format from the framebuffer.
     *
     * TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
     */
    fb = stw_framebuffer_from_hdc( hdc );
    if (fb) {
        assert(iPixelFormat == fb->iDisplayablePixelFormat);
        iPixelFormat = fb->iPixelFormat;
        stw_framebuffer_release(fb);
    }

    pfi = stw_pixelformat_get_info( iPixelFormat );

    if (hShareContext != 0) {
        pipe_mutex_lock( stw_dev->ctx_mutex );
        shareCtx = stw_lookup_context_locked( hShareContext );
        pipe_mutex_unlock( stw_dev->ctx_mutex );
    }

    ctx = CALLOC_STRUCT( stw_context );
    if (ctx == NULL)
        goto no_ctx;

    ctx->hdc = hdc;
    ctx->iPixelFormat = iPixelFormat;

    memset(&attribs, 0, sizeof(attribs));
    attribs.visual = pfi->stvis;
    attribs.major = majorVersion;
    attribs.minor = minorVersion;
    if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
        attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
    if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
        attribs.flags |= ST_CONTEXT_FLAG_DEBUG;

    switch (profileMask) {
    case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
        /* There are no profiles before OpenGL 3.2.  The
         * WGL_ARB_create_context_profile spec says:
         *
         *     "If the requested OpenGL version is less than 3.2,
         *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
         *     of the context is determined solely by the requested version."
         */
        if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
            attribs.profile = ST_PROFILE_OPENGL_CORE;
            break;
        }
    /* fall-through */
    case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
        /*
         * The spec also says:
         *
         *     "If version 3.1 is requested, the context returned may implement
         *     any of the following versions:
         *
         *       * Version 3.1. The GL_ARB_compatibility extension may or may not
         *         be implemented, as determined by the implementation.
         *       * The core profile of version 3.2 or greater."
         *
         * and because Mesa doesn't support GL_ARB_compatibility, the only chance to
         * honour a 3.1 context is through core profile.
         */
        if (majorVersion == 3 && minorVersion == 1) {
            attribs.profile = ST_PROFILE_OPENGL_CORE;
        } else {
            attribs.profile = ST_PROFILE_DEFAULT;
        }
        break;
    case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
        if (majorVersion >= 2) {
            attribs.profile = ST_PROFILE_OPENGL_ES2;
        } else {
            attribs.profile = ST_PROFILE_OPENGL_ES1;
        }
        break;
    default:
        assert(0);
        goto no_st_ctx;
    }

    ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
              stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
    if (ctx->st == NULL)
        goto no_st_ctx;

    ctx->st->st_manager_private = (void *) ctx;

    if (ctx->st->cso_context) {
        ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
    }

    pipe_mutex_lock( stw_dev->ctx_mutex );
    if (handle) {
        /* We're replacing the context data for this handle. See the
         * wglCreateContextAttribsARB() function.
         */
        struct stw_context *old_ctx =
            stw_lookup_context_locked((unsigned) handle);
        if (old_ctx) {
            /* free the old context data associated with this handle */
            if (old_ctx->hud) {
                hud_destroy(old_ctx->hud);
            }
            ctx->st->destroy(old_ctx->st);
            FREE(old_ctx);
        }

        /* replace table entry */
        handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
    }
    else {
        /* create new table entry */
        handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
    }

    ctx->dhglrc = handle;

    pipe_mutex_unlock( stw_dev->ctx_mutex );
    if (!ctx->dhglrc)
        goto no_hglrc;

    return ctx->dhglrc;

no_hglrc:
    if (ctx->hud) {
        hud_destroy(ctx->hud);
    }
    ctx->st->destroy(ctx->st);
no_st_ctx:
    FREE(ctx);
no_ctx:
    return 0;
}
示例#8
0
DHGLRC
stw_create_context_attribs(
   HDC hdc,
   INT iLayerPlane,
   DHGLRC hShareContext,
   int majorVersion, int minorVersion,
   int contextFlags, int profileMask)
{
   int iPixelFormat;
   struct stw_framebuffer *fb;
   const struct stw_pixelformat_info *pfi;
   struct st_context_attribs attribs;
   struct stw_context *ctx = NULL;
   struct stw_context *shareCtx = NULL;
   enum st_context_error ctx_err = 0;

   if (!stw_dev)
      return 0;

   if (iLayerPlane != 0)
      return 0;

   iPixelFormat = GetPixelFormat(hdc);
   if(!iPixelFormat)
      return 0;

   /*
    * GDI only knows about displayable pixel formats, so determine the pixel format
    * from the framebuffer.
    *
    * TODO: Remove the GetPixelFormat() above, and stop relying on GDI.
    */
   fb = stw_framebuffer_from_hdc( hdc );
   if (fb) {
      assert(iPixelFormat == fb->iDisplayablePixelFormat);
      iPixelFormat = fb->iPixelFormat;
      stw_framebuffer_release(fb);
   }

   pfi = stw_pixelformat_get_info( iPixelFormat );

   if (hShareContext != 0) {
      pipe_mutex_lock( stw_dev->ctx_mutex );
      shareCtx = stw_lookup_context_locked( hShareContext );
      pipe_mutex_unlock( stw_dev->ctx_mutex );
   }

   ctx = CALLOC_STRUCT( stw_context );
   if (ctx == NULL)
      goto no_ctx;

   ctx->hdc = hdc;
   ctx->iPixelFormat = iPixelFormat;

   memset(&attribs, 0, sizeof(attribs));
   attribs.visual = pfi->stvis;
   attribs.major = majorVersion;
   attribs.minor = minorVersion;
   if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
   if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
      attribs.flags |= ST_CONTEXT_FLAG_DEBUG;

   /* There are no profiles before OpenGL 3.2.  The
    * WGL_ARB_create_context_profile spec says:
    *
    *     "If the requested OpenGL version is less than 3.2,
    *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality of the
    *     context is determined solely by the requested version."
    *
    * The spec also says:
    *
    *     "The default value for WGL_CONTEXT_PROFILE_MASK_ARB is
    *     WGL_CONTEXT_CORE_PROFILE_BIT_ARB."
    */
   attribs.profile = ST_PROFILE_DEFAULT;
   if ((majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2))
       && ((profileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) == 0))
      attribs.profile = ST_PROFILE_OPENGL_CORE;

   ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
         stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
   if (ctx->st == NULL)
      goto no_st_ctx;

   ctx->st->st_manager_private = (void *) ctx;

   pipe_mutex_lock( stw_dev->ctx_mutex );
   ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
   pipe_mutex_unlock( stw_dev->ctx_mutex );
   if (!ctx->dhglrc)
      goto no_hglrc;

   return ctx->dhglrc;

no_hglrc:
   ctx->st->destroy(ctx->st);
no_st_ctx:
   FREE(ctx);
no_ctx:
   return 0;
}