void SWRenderDisplayWindowProvider::create(DisplayWindowSite *new_site, const DisplayWindowDescription &description) { site = new_site; flip_timer_set = false; refresh_rate = description.get_refresh_rate(); if (!refresh_rate) // Default the refresh rate to 100 if not defined refresh_rate = 100; swap_interval = description.get_swap_interval(); #ifdef WIN32 window.create(site, description); #elif !defined(__APPLE__) ::Display *disp = window.get_display(); int bpp = 24; XVisualInfo visual_info; int screen = DefaultScreen(disp); //RootWindow(disp, 0); if (XMatchVisualInfo(disp, screen, 24, TrueColor, &visual_info)) {bpp = 24;} else if (XMatchVisualInfo(disp, screen, 16, TrueColor, &visual_info)) {bpp = 16;} else if (XMatchVisualInfo(disp, screen, 15, TrueColor, &visual_info)) {bpp = 15;} else if (XMatchVisualInfo(disp, screen, 32, TrueColor, &visual_info)) {bpp = 32;} else if (XMatchVisualInfo(disp, screen, 8, PseudoColor, &visual_info)) {bpp = 8;} else if (XMatchVisualInfo(disp, screen, 8, GrayScale, &visual_info)) {bpp = 8;} else if (XMatchVisualInfo(disp, screen, 8, StaticGray, &visual_info)) {bpp = 8;} else if (XMatchVisualInfo(disp, screen, 1, StaticGray, &visual_info)) {bpp = 1;} else { throw Exception("Cannot match visual info"); } window.create(&visual_info, site, description); #endif gc = GraphicContext(new SWRenderGraphicContextProvider(this)); }
void D3DDisplayWindowProvider::create(DisplayWindowSite *new_site, const DisplayWindowDescription &description) { site = new_site; if (device) D3DShareList::device_destroyed(device); info_queue.clear(); debug.clear(); back_buffer_rtv.clear(); fake_front_buffer.clear(); back_buffer.clear(); swap_chain.clear(); device_context.clear(); device.clear(); window.create(site, description); use_fake_front_buffer = description.is_update_supported(); D3D_FEATURE_LEVEL request_levels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; DXGI_SWAP_CHAIN_DESC swap_chain_description; swap_chain_description.BufferCount = description.get_flipping_buffers(); swap_chain_description.BufferDesc.Width = 0; swap_chain_description.BufferDesc.Height = 0; swap_chain_description.BufferDesc.RefreshRate.Numerator = 60; swap_chain_description.BufferDesc.RefreshRate.Denominator = 1; swap_chain_description.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; swap_chain_description.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swap_chain_description.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swap_chain_description.SampleDesc.Count = 1; swap_chain_description.SampleDesc.Quality = 0; swap_chain_description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_description.OutputWindow = window.get_hwnd(); swap_chain_description.Windowed = TRUE; // Seems the documentation wants us to call IDXGISwapChain::SetFullscreenState afterwards swap_chain_description.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swap_chain_description.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; bool debug_mode = false; // To do: fetch this from DisplayWindowDescription using same method as clanGL (or maybe promote debug flag to clanDisplay?) UINT device_flags = 0; if (debug_mode) device_flags |= D3D11_CREATE_DEVICE_DEBUG; MutexSection mutex_lock(&d3d11_mutex); if (d3d11_dll == 0) { d3d11_dll = LoadLibrary(L"d3d11.dll"); if (d3d11_dll == 0) throw Exception("Unable to load d3d11.dll"); try { d3d11_createdeviceandswapchain = reinterpret_cast<FuncD3D11CreateDeviceAndSwapChain>(GetProcAddress(d3d11_dll, "D3D11CreateDeviceAndSwapChain")); if (d3d11_createdeviceandswapchain == 0) throw Exception("D3D11CreateDeviceAndSwapChain function not found!"); } catch (...) { CloseHandle(d3d11_dll); d3d11_dll = 0; d3d11_createdeviceandswapchain = 0; throw; } } HRESULT result = d3d11_createdeviceandswapchain( 0, D3D_DRIVER_TYPE_HARDWARE, 0, device_flags, request_levels, 3, D3D11_SDK_VERSION, &swap_chain_description, swap_chain.output_variable(), device.output_variable(), &feature_level, device_context.output_variable()); D3DTarget::throw_if_failed("D3D11CreateDeviceAndSwapChain failed", result); if (debug_mode) { result = device->QueryInterface(__uuidof(ID3D11Debug), (void**)debug.output_variable()); if (FAILED(result)) debug.clear(); // No debug info available. Should this throw an exception instead? result = device->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)info_queue.output_variable()); if (FAILED(result)) info_queue.clear(); // No debug messages available. } // Disable mouse lag (no, 3 frames rendered ahead is NOT a good default Microsoft): ComPtr<IDXGIDevice1> dxgi_device; result = swap_chain->GetDevice(__uuidof(IDXGIDevice1), (void**)dxgi_device.output_variable()); D3DTarget::throw_if_failed("Unable to retrieve IDXGIDevice1 from swap chain", result); dxgi_device->SetMaximumFrameLatency(1); create_swap_chain_buffers(); gc = GraphicContext(new D3DGraphicContextProvider(this, description)); if (description.is_fullscreen()) swap_chain->SetFullscreenState(TRUE, 0); D3DGraphicContextProvider *d3d_gc = static_cast<D3DGraphicContextProvider*>(gc.get_provider()); d3d_gc->standard_programs = StandardPrograms(gc); }
void OpenGLWindowProvider::create(DisplayWindowSite *new_site, const DisplayWindowDescription &desc) { window_handle = desc.get_handle(); if (window_handle.window == nullptr) throw Exception("Window handle must exist in the display description"); ANativeWindow *window = window_handle.window; const EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE }; EGLint format; EGLint numConfigs; EGLConfig config; display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0); /* Here, the application chooses the configuration it desires. In this * sample, we have a very simplified selection process, where we pick * the first EGLConfig that matches our criteria */ if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs)) throw Exception("eglChooseConfig failed"); if (numConfigs < 1) throw Exception("Found configs failed"); /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). * As soon as we picked a EGLConfig, we can safely reconfigure the * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); ANativeWindow_setBuffersGeometry(window, 0, 0, format); surface = eglCreateWindowSurface(display, config, window, NULL); if (surface == EGL_NO_SURFACE) throw Exception("eglCreateWindowSurface failed"); context = eglCreateContext(display, config, NULL, NULL); if (context == EGL_NO_CONTEXT) throw Exception("eglCreateWindowSurface failed"); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { throw Exception("Unable to eglMakeCurrent"); } bool use_gl3; int desc_version_major = opengl_desc.get_version_major(); int desc_version_minor = opengl_desc.get_version_minor(); // Do not attempt GL3, if not requested that version if (desc_version_major < 3) { use_gl3 = false; } else if (!opengl_desc.get_allow_lower_versions()) // Else, if we do not allow lower versions, only attempt GL3 { use_gl3 = true; } else { // Choose the target depending on the current opengl version int gl_version_major; int gl_version_minor; get_opengl_version(gl_version_major, gl_version_minor); if (gl_version_major < 3) { use_gl3 = false; } else { use_gl3 = true; } } if (use_gl3) { using_gl3 = true; gc = GraphicContext(new GL3GraphicContextProvider(this)); } else { using_gl3 = false; gc = GraphicContext(new GL1GraphicContextProvider(this)); } swap_interval = desc.get_swap_interval(); if (swap_interval != -1) eglSwapInterval(display, swap_interval); }
void OpenGLWindowProvider::create(DisplayWindowSite *new_site, const DisplayWindowDescription &desc) { site = new_site; fullscreen = desc.is_fullscreen(); win32_window.create(site, desc); if (!opengl_context) { HWND handle = win32_window.get_hwnd(); dwm_layered = false; if (desc.is_layered() && !DwmFunctions::is_composition_enabled()) { create_shadow_window(handle); } else { if (desc.is_layered()) dwm_layered = true; } desc.is_layered() ? double_buffered = false : double_buffered = true; // Only can use Layered windows that are single buffered with OpenGL (via shadow window) ( PFD_DOUBLEBUFFER_DONTCARE set in OpenGLCreationHelper::set_multisampling_pixel_format) device_context = GetDC(handle); HGLRC share_context = get_share_context(); OpenGLCreationHelper helper(handle, device_context); helper.set_multisampling_pixel_format(desc); int gl_major = opengl_desc.get_version_major(); int gl_minor = opengl_desc.get_version_minor(); if (opengl_desc.get_allow_lower_versions() == false) { opengl_context = helper.create_opengl3_context(share_context, gl_major, gl_minor, opengl_desc); if (!opengl_context) throw Exception(string_format("This application requires OpenGL %1.%2 or above. Try updating your drivers, or upgrade to a newer graphics card.", gl_major, gl_minor)); } else { static const char opengl_version_list[] = { // Clanlib supported version pairs 4, 5, 4, 4, 4, 3, 4, 2, 4, 1, 4, 0, 3, 3, 3, 2, 3, 1, 3, 0, 0, 0, // End of list }; const char *opengl_version_list_ptr = opengl_version_list; do { int major = *(opengl_version_list_ptr++); if (major == 0) break; int minor = *(opengl_version_list_ptr++); // Find the appropriate version in the list if (major > gl_major) continue; if (major == gl_major) { if (minor > gl_minor) continue; } opengl_context = helper.create_opengl3_context(share_context, major, minor, opengl_desc); } while (!opengl_context); if (!opengl_context) opengl_context = helper.create_opengl2_context(share_context); if (!opengl_context) throw Exception("This application requires OpenGL. Try updating your drivers, or upgrade to a newer graphics card."); } bool use_gl3; int desc_version_major = opengl_desc.get_version_major(); int desc_version_minor = opengl_desc.get_version_minor(); // Do not attempt GL3, if not requested that version if (desc_version_major < 3) { use_gl3 = false; } else if (!opengl_desc.get_allow_lower_versions()) // Else, if we do not allow lower versions, only attempt GL3 { use_gl3 = true; } else { // Choose the target depending on the current opengl version int gl_version_major; int gl_version_minor; get_opengl_version(gl_version_major, gl_version_minor); if (gl_version_major < 3) { use_gl3 = false; } else { use_gl3 = true; } } if (use_gl3) { using_gl3 = true; gc = GraphicContext(new GL3GraphicContextProvider(this)); } else { using_gl3 = false; gc = GraphicContext(new GL1GraphicContextProvider(this)); } } wglSwapIntervalEXT = (ptr_wglSwapIntervalEXT)OpenGL::get_proc_address("wglSwapIntervalEXT"); swap_interval = desc.get_swap_interval(); if (wglSwapIntervalEXT && swap_interval != -1) wglSwapIntervalEXT(swap_interval); }