Ejemplo n.º 1
0
BOOL APIENTRY
DrvReleaseContext(
    DHGLRC dhglrc )
{
    struct stw_context *ctx;

    if (!stw_dev)
        return FALSE;

    pipe_mutex_lock( stw_dev->ctx_mutex );
    ctx = stw_lookup_context_locked( dhglrc );
    pipe_mutex_unlock( stw_dev->ctx_mutex );

    if (!ctx)
        return FALSE;

    /* The expectation is that ctx is the same context which is
     * current for this thread.  We should check that and return False
     * if not the case.
     */
    if (ctx != stw_current_context())
        return FALSE;

    if (stw_make_current( NULL, 0 ) == FALSE)
        return FALSE;

    return TRUE;
}
Ejemplo n.º 2
0
BOOL APIENTRY
DrvDeleteContext(
    DHGLRC dhglrc )
{
    struct stw_context *ctx ;
    BOOL ret = FALSE;

    if (!stw_dev)
        return FALSE;

    pipe_mutex_lock( stw_dev->ctx_mutex );
    ctx = stw_lookup_context_locked(dhglrc);
    handle_table_remove(stw_dev->ctx_table, dhglrc);
    pipe_mutex_unlock( stw_dev->ctx_mutex );

    if (ctx) {
        struct stw_context *curctx = stw_current_context();

        /* Unbind current if deleting current context. */
        if (curctx == ctx)
            stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);

        if (ctx->hud) {
            hud_destroy(ctx->hud);
        }

        ctx->st->destroy(ctx->st);
        FREE(ctx);

        ret = TRUE;
    }

    return ret;
}
Ejemplo n.º 3
0
/**
 * Flush the current context if it is bound to the framebuffer.
 */
void
stw_flush_current_locked( struct stw_framebuffer *fb )
{
    struct stw_context *ctx = stw_current_context();

    if (ctx && ctx->current_framebuffer == fb) {
        ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
    }
}
Ejemplo n.º 4
0
HDC
stw_get_current_dc( void )
{
    struct stw_context *ctx;

    ctx = stw_current_context();
    if(!ctx)
        return NULL;

    return ctx->hdc;
}
Ejemplo n.º 5
0
DHGLRC
stw_get_current_context( void )
{
    struct stw_context *ctx;

    ctx = stw_current_context();
    if(!ctx)
        return 0;

    return ctx->dhglrc;
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
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;
}
BOOL WINAPI
wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
{
   HDC prevDrawable = stw_get_current_dc();
   HDC prevReadable = stw_get_current_read_dc();
   HDC dc;
   struct stw_context *curctx = stw_current_context();
   struct stw_framebuffer *fb;
   GLenum texFormat, srcBuffer, target;
   boolean retVal;
   int pixelFormatSave;

   /*
    * Implementation notes:
    * Ideally, we'd implement this function with the
    * st_context_iface::teximage() function which replaces a specific
    * texture image with a different resource (the pbuffer).
    * The main problem however, is the pbuffer image is upside down relative
    * to the texture image.
    * Window system drawing surfaces (windows & pbuffers) are "top to bottom"
    * while OpenGL texture images are "bottom to top".  One possible solution
    * to this is to invert rendering to pbuffers (as we do for renderbuffers)
    * but that could lead to other issues (and would require extensive
    * testing).
    *
    * The simple alternative is to use a copy-based approach which copies the
    * pbuffer image into the texture via glCopyTex[Sub]Image.  That's what
    * we do here.
    */

   if (!curctx) {
      debug_printf("No rendering context in wglBindTexImageARB()\n");
      SetLastError(ERROR_INVALID_OPERATION);
      return FALSE;
   }

   fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
   if (!fb) {
      debug_printf("Invalid pbuffer handle in wglBindTexImageARB()\n");
      SetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }

   srcBuffer = translate_ibuffer(iBuffer);
   if (srcBuffer == GL_NONE) {
      debug_printf("Invalid buffer 0x%x in wglBindTexImageARB()\n", iBuffer);
      SetLastError(ERROR_INVALID_DATA);
      return FALSE;
   }

   target = translate_target(fb->textureTarget);
   if (target == GL_NONE) {
      debug_printf("no texture target in wglBindTexImageARB()\n");
      return FALSE;
   }

   texFormat = translate_texture_format(fb->textureFormat);
   if (texFormat == GL_NONE) {
      debug_printf("no texture format in wglBindTexImageARB()\n");
      return FALSE;
   }

   /*
    * Bind the pbuffer surface so we can read/copy from it.
    *
    * Before we can call stw_make_current() we have to temporarily
    * change the pbuffer's pixel format to match the context to avoid
    * an error condition.  After the stw_make_current() we restore the
    * buffer's pixel format.
    */
   pixelFormatSave = fb->iPixelFormat;
   fb->iPixelFormat = curctx->iPixelFormat;
   dc = wglGetPbufferDCARB(hPbuffer);
   retVal = stw_make_current(dc, dc, curctx->dhglrc);
   fb->iPixelFormat = pixelFormatSave;
   if (!retVal) {
      debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n");
      wglReleasePbufferDCARB(hPbuffer, dc);
      return FALSE;
   }

   st_copy_framebuffer_to_texture(srcBuffer, fb->width, fb->height,
                                  target, fb->textureLevel,
                                  fb->textureFace, texFormat);

   /* rebind previous drawing surface */
   retVal = stw_make_current(prevDrawable, prevReadable, curctx->dhglrc);
   if (!retVal) {
      debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n");
   }

   wglReleasePbufferDCARB(hPbuffer, dc);

   return retVal;
}