static int w32_init(struct MPGLContext *ctx, int flags) { if (!vo_w32_init(ctx->vo)) goto fail; struct w32_context *w32_ctx = ctx->priv; w32_ctx->flags = flags; vo_w32_run_on_thread(ctx->vo, create_ctx, ctx); if (!w32_ctx->context) goto fail; if (!ctx->gl->SwapInterval) MP_VERBOSE(ctx->vo, "WGL_EXT_swap_control missing."); w32_ctx->real_wglSwapInterval = ctx->gl->SwapInterval; ctx->gl->SwapInterval = w32_swap_interval; w32_ctx->current_swapinterval = -1; current_w32_context = w32_ctx; wglMakeCurrent(w32_ctx->hdc, w32_ctx->context); return 0; fail: w32_uninit(ctx); return -1; }
static int preinit(const char *arg) { D3DDISPLAYMODE disp_mode; D3DCAPS9 disp_caps; DWORD texture_caps; DWORD dev_caps; /* Set to zero all global variables. */ priv = calloc(1, sizeof(struct global_priv)); if (!priv) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Allocating private memory failed.\n"); goto err_out; } /* FIXME > Please use subopt-helper.h for this, see vo_gl.c:preinit for > an example of how to use it. */ priv->d3d9_dll = LoadLibraryA("d3d9.dll"); if (!priv->d3d9_dll) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Unable to dynamically load d3d9.dll\n"); goto err_out; } priv->pDirect3DCreate9 = (void *)GetProcAddress(priv->d3d9_dll, "Direct3DCreate9"); if (!priv->pDirect3DCreate9) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Unable to find entry point of Direct3DCreate9\n"); goto err_out; } priv->d3d_handle = priv->pDirect3DCreate9(D3D_SDK_VERSION); if (!priv->d3d_handle) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Initializing Direct3D failed.\n"); goto err_out; } if (FAILED(IDirect3D9_GetAdapterDisplayMode(priv->d3d_handle, D3DADAPTER_DEFAULT, &disp_mode))) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Reading display mode failed.\n"); goto err_out; } /* Store in priv->desktop_fmt the user desktop's colorspace. Usually XRGB. */ priv->desktop_fmt = disp_mode.Format; priv->cur_backbuf_width = disp_mode.Width; priv->cur_backbuf_height = disp_mode.Height; mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Setting backbuffer dimensions to (%dx%d).\n", disp_mode.Width, disp_mode.Height); if (FAILED(IDirect3D9_GetDeviceCaps(priv->d3d_handle, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &disp_caps))) { mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Reading display capabilities failed.\n"); goto err_out; } /* Store relevant information reguarding caps of device */ texture_caps = disp_caps.TextureCaps; dev_caps = disp_caps.DevCaps; priv->device_caps_power2_only = (texture_caps & D3DPTEXTURECAPS_POW2) && !(texture_caps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL); priv->device_caps_square_only = texture_caps & D3DPTEXTURECAPS_SQUAREONLY; priv->device_texture_sys = dev_caps & D3DDEVCAPS_TEXTURESYSTEMMEMORY; priv->max_texture_width = disp_caps.MaxTextureWidth; priv->max_texture_height = disp_caps.MaxTextureHeight; mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>device_caps_power2_only %d, device_caps_square_only %d\n" "<vo_direct3d>device_texture_sys %d\n" "<vo_direct3d>max_texture_width %d, max_texture_height %d\n", priv->device_caps_power2_only, priv->device_caps_square_only, priv->device_texture_sys, priv->max_texture_width, priv->max_texture_height); /* w32_common framework call. Configures window on the screen, gets * fullscreen dimensions and does other useful stuff. */ if (!vo_w32_init()) { mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Configuring onscreen window failed.\n"); goto err_out; } return 0; err_out: uninit(); return -1; }
static int angle_init(struct MPGLContext *ctx, int flags) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; if (!angle_load()) { MP_VERBOSE(vo, "Failed to load LIBEGL.DLL\n"); goto fail; } if (!vo_w32_init(vo)) goto fail; HDC dc = GetDC(vo_w32_hwnd(vo)); if (!dc) { MP_FATAL(vo, "Couldn't get DC\n"); goto fail; } PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); if (!eglGetPlatformDisplayEXT) { MP_FATAL(vo, "Missing EGL_EXT_platform_base\n"); goto fail; } EGLint d3d_types[] = {EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE}; EGLint d3d_dev_types[] = {EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE}; for (int i = 0; i < MP_ARRAY_SIZE(d3d_types); i++) { EGLint display_attributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, d3d_types[i], EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, d3d_dev_types[i], EGL_NONE, }; p->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, display_attributes); if (p->egl_display == EGL_NO_DISPLAY) continue; if (!eglInitialize(p->egl_display, NULL, NULL)) { p->egl_display = EGL_NO_DISPLAY; continue; } if (d3d_dev_types[i] == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE) show_sw_adapter_msg(ctx); break; } if (p->egl_display == EGL_NO_DISPLAY) { MP_FATAL(vo, "Couldn't get display\n"); goto fail; } const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS); if (exts) MP_DBG(ctx->vo, "EGL extensions: %s\n", exts); eglBindAPI(EGL_OPENGL_ES_API); if (eglGetError() != EGL_SUCCESS) { MP_FATAL(vo, "Couldn't bind GLES API\n"); goto fail; } EGLConfig config = select_fb_config_egl(ctx); if (!config) goto fail; int window_attribs_len = 0; EGLint *window_attribs = NULL; EGLint flip_val; if (eglGetConfigAttrib(p->egl_display, config, EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE, &flip_val)) { if (flip_val == EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) { MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_SURFACE_ORIENTATION_ANGLE); MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE); ctx->flip_v = true; MP_VERBOSE(vo, "Rendering flipped.\n"); } } // EGL_DIRECT_COMPOSITION_ANGLE enables the use of flip-mode present, which // avoids a copy of the video image and lowers vsync jitter, though the // extension is only present on Windows 8 and up. if (strstr(exts, "EGL_ANGLE_direct_composition")) { MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_DIRECT_COMPOSITION_ANGLE); MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_TRUE); MP_VERBOSE(vo, "Using DirectComposition.\n"); } MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_NONE); p->egl_surface = eglCreateWindowSurface(p->egl_display, config, vo_w32_hwnd(vo), window_attribs); talloc_free(window_attribs); if (p->egl_surface == EGL_NO_SURFACE) { MP_FATAL(ctx->vo, "Could not create EGL surface!\n"); goto fail; } if (!(!p->use_es2 && create_context_egl(ctx, config, 3)) && !create_context_egl(ctx, config, 2)) { MP_FATAL(ctx->vo, "Could not create EGL context!\n"); goto fail; } // Configure the underlying Direct3D device d3d_init(ctx); if (strstr(exts, "EGL_NV_post_sub_buffer")) { p->eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC)eglGetProcAddress("eglPostSubBufferNV"); } mpgl_load_functions(ctx->gl, get_proc_address, NULL, vo->log); return 0; fail: angle_uninit(ctx); return -1; }
static int angle_init(struct MPGLContext *ctx, int flags) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; if (!vo_w32_init(vo)) goto fail; HDC dc = GetDC(vo_w32_hwnd(vo)); if (!dc) { MP_FATAL(vo, "Couldn't get DC\n"); goto fail; } PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); if (!eglGetPlatformDisplayEXT) { MP_FATAL(vo, "Missing EGL_EXT_platform_base\n"); goto fail; } EGLint d3d_types[] = {EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE}; for (int i = 0; i < MP_ARRAY_SIZE(d3d_types); i++) { EGLint display_attributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, d3d_types[i], EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, EGL_NONE, }; p->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, display_attributes); if (p->egl_display != EGL_NO_DISPLAY) break; } if (p->egl_display == EGL_NO_DISPLAY) { MP_FATAL(vo, "Couldn't get display\n"); goto fail; } if (!eglInitialize(p->egl_display, NULL, NULL)) { MP_FATAL(vo, "Couldn't initialize EGL\n"); goto fail; } eglBindAPI(EGL_OPENGL_ES_API); if (eglGetError() != EGL_SUCCESS) { MP_FATAL(vo, "Couldn't bind GLES API\n"); goto fail; } EGLConfig config = select_fb_config_egl(ctx); if (!config) goto fail; p->egl_surface = eglCreateWindowSurface(p->egl_display, config, vo_w32_hwnd(vo), NULL); if (p->egl_surface == EGL_NO_SURFACE) { MP_FATAL(ctx->vo, "Could not create EGL surface!\n"); goto fail; } if (!create_context_egl(ctx, config, 3) && !create_context_egl(ctx, config, 2)) { MP_FATAL(ctx->vo, "Could not create EGL context!\n"); goto fail; } mpgl_load_functions(ctx->gl, get_proc_address, NULL, vo->log); return 0; fail: angle_uninit(ctx); return -1; }