use super::error::*;
use super::opengl::*;
use super::offscreen_trait::*;
use gl;
use flo_render_gl_offscreen::cgl;
use core_foundation::base::*;
use core_foundation::string::*;
use core_foundation::bundle::*;
use std::str;
use std::ptr;
struct CglOffscreenRenderContext {
_pixel_format: cgl::CGLPixelFormatObj,
context: cgl::CGLContextObj
}
fn get_proc_address(addr: &str) -> *const libc::c_void {
let symbol_name: CFString = str::FromStr::from_str(addr).unwrap();
let framework_name: CFString = str::FromStr::from_str("com.apple.opengl").unwrap();
let framework = unsafe {
CFBundleGetBundleWithIdentifier(framework_name.as_concrete_TypeRef())
};
let symbol = unsafe {
CFBundleGetFunctionPointerForName(framework, symbol_name.as_concrete_TypeRef())
};
symbol as *const _
}
fn to_render_error(error: cgl::CGLError) -> Result<(), RenderInitError> {
match error {
cgl::kCGLNoError => Ok(()),
_ => Err(RenderInitError::CannotStartGraphicsDriver)
}
}
pub fn initialize_offscreen_rendering() -> Result<impl OffscreenRenderContext, RenderInitError> {
unsafe {
let pixel_attributes = vec![
cgl::kCGLPFAAccelerated,
cgl::kCGLPFAOpenGLProfile, 0x3200,
cgl::kCGLPFAColorSize, 24,
cgl::kCGLPFADepthSize, 16,
0
];
let mut pixel_format = ptr::null_mut();
let mut num_pixel_formats = 0;
let pixel_format_error = cgl::CGLChoosePixelFormat(pixel_attributes.as_ptr(), &mut pixel_format, &mut num_pixel_formats);
to_render_error(pixel_format_error)?;
if pixel_format.is_null() {
Err(RenderInitError::DisplayNotAvailable)?
}
let mut context = ptr::null_mut();
let context_error = cgl::CGLCreateContext(pixel_format, ptr::null_mut(), &mut context);
to_render_error(context_error)?;
if context.is_null() {
Err(RenderInitError::CouldNotCreateContext)?
}
let set_context_error = cgl::CGLSetCurrentContext(context);
if set_context_error != 0 {
Err(RenderInitError::ContextDidNotStart)?
}
gl::load_with(|name| get_proc_address(name));
let error = gl::GetError();
if error != gl::NO_ERROR { println!("gl::GetError {:x}", error); Err(RenderInitError::ContextDidNotStart)? }
assert!(error == gl::NO_ERROR);
Ok(CglOffscreenRenderContext {
_pixel_format: pixel_format,
context: context
})
}
}
impl OffscreenRenderContext for CglOffscreenRenderContext {
type RenderTarget = OpenGlOffscreenRenderer;
fn create_render_target(&mut self, width: usize, height: usize) -> Self::RenderTarget {
unsafe {
let set_context_error = cgl::CGLSetCurrentContext(self.context);
if set_context_error != 0 { panic!("CGLSetCurrentContext {:x}", set_context_error); }
OpenGlOffscreenRenderer::new(width, height)
}
}
}