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; }
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; }
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); }
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); }
/** * 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); } }
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; }
/** * 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; }
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; }