Add errors throughout
This commit is contained in:
parent
78c03a9594
commit
5453afa7a1
|
@ -8,6 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use error::GlError;
|
||||
use euclid::{Point2D, Rect, Size2D};
|
||||
use gl::types::{GLenum, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
||||
use gl;
|
||||
|
@ -34,6 +35,8 @@ impl AtlasBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns an error if there is no space left for the glyph in the atlas.
|
||||
///
|
||||
/// FIXME(pcwalton): Support the same glyph drawn at multiple point sizes.
|
||||
pub fn pack_glyph(&mut self,
|
||||
outline_builder: &OutlineBuilder,
|
||||
|
@ -74,7 +77,7 @@ impl AtlasBuilder {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn create_atlas(&mut self, outline_builder: &OutlineBuilder) -> Result<Atlas, ()> {
|
||||
pub fn create_atlas(&mut self, outline_builder: &OutlineBuilder) -> Result<Atlas, GlError> {
|
||||
self.image_metadata.sort_by(|a, b| a.glyph_index.cmp(&b.glyph_index));
|
||||
|
||||
let (mut current_range, mut counts, mut start_indices) = (None, vec![], vec![]);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
use compute_shader::buffer::Protection;
|
||||
use compute_shader::device::Device;
|
||||
use compute_shader::image::{ExternalImage, Format, Image};
|
||||
use error::InitError;
|
||||
use euclid::size::Size2D;
|
||||
use gl::types::{GLint, GLuint};
|
||||
use gl;
|
||||
|
@ -21,15 +22,16 @@ pub struct CoverageBuffer {
|
|||
}
|
||||
|
||||
impl CoverageBuffer {
|
||||
pub fn new(device: &Device, size: &Size2D<u32>) -> Result<CoverageBuffer, ()> {
|
||||
pub fn new(device: &Device, size: &Size2D<u32>) -> Result<CoverageBuffer, InitError> {
|
||||
let image = try!(device.create_image(Format::R32F, Protection::ReadWrite, size)
|
||||
.map_err(drop));
|
||||
.map_err(InitError::ComputeError));
|
||||
|
||||
let mut framebuffer = 0;
|
||||
unsafe {
|
||||
let mut gl_texture = 0;
|
||||
gl::GenTextures(1, &mut gl_texture);
|
||||
try!(image.bind_to(&ExternalImage::GlTexture(gl_texture)).map_err(drop));
|
||||
try!(image.bind_to(&ExternalImage::GlTexture(gl_texture))
|
||||
.map_err(InitError::ComputeError));
|
||||
|
||||
gl::BindTexture(gl::TEXTURE_RECTANGLE, gl_texture);
|
||||
gl::TexParameteri(gl::TEXTURE_RECTANGLE, gl::TEXTURE_MIN_FILTER, gl::LINEAR as GLint);
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2017 The Servo Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Errors.
|
||||
|
||||
use compute_shader;
|
||||
use gl::types::GLenum;
|
||||
|
||||
/// An OpenGL error with the given code.
|
||||
///
|
||||
/// You cannot depend on these being reliably returned. Pathfinder does not call `glGetError()`
|
||||
/// unless necessary, to avoid driver stalls.
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub struct GlError(pub GLenum);
|
||||
|
||||
/// An initialization error. This could be an OpenGL error or a shader compilation/link error.
|
||||
#[derive(Debug)]
|
||||
pub enum InitError {
|
||||
GlError(GlError),
|
||||
CompileFailed(&'static str, String),
|
||||
LinkFailed(String),
|
||||
ComputeError(compute_shader::error::Error),
|
||||
/// One of the rasterization options had an invalid syntax.
|
||||
InvalidSetting,
|
||||
}
|
||||
|
||||
/// A rasterization error. This could be an OpenGL error or a compute error.
|
||||
#[derive(Debug)]
|
||||
pub enum RasterError {
|
||||
GlError(GlError),
|
||||
ComputeError(compute_shader::error::Error),
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ extern crate test;
|
|||
pub mod atlas;
|
||||
pub mod charmap;
|
||||
pub mod coverage;
|
||||
pub mod error;
|
||||
pub mod glyph_range;
|
||||
pub mod otf;
|
||||
pub mod outline;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use error::GlError;
|
||||
use euclid::{Point2D, Rect, Size2D};
|
||||
use gl::types::{GLsizeiptr, GLuint};
|
||||
use gl;
|
||||
|
@ -95,7 +96,7 @@ impl OutlineBuilder {
|
|||
self.descriptors[glyph_index as usize].glyph_id
|
||||
}
|
||||
|
||||
pub fn create_buffers(&self) -> Result<OutlineBuffers, ()> {
|
||||
pub fn create_buffers(&self) -> Result<OutlineBuffers, GlError> {
|
||||
// TODO(pcwalton): Try using `glMapBuffer` here. Requires precomputing contour types and
|
||||
// counts.
|
||||
unsafe {
|
||||
|
|
|
@ -16,6 +16,7 @@ use compute_shader::profile_event::ProfileEvent;
|
|||
use compute_shader::program::Program;
|
||||
use compute_shader::queue::{Queue, Uniform};
|
||||
use coverage::CoverageBuffer;
|
||||
use error::{InitError, RasterError};
|
||||
use euclid::rect::Rect;
|
||||
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint, GLvoid};
|
||||
use gl;
|
||||
|
@ -58,7 +59,7 @@ pub struct DrawAtlasProfilingEvents {
|
|||
|
||||
impl Rasterizer {
|
||||
pub fn new(instance: &Instance, device: Device, queue: Queue, options: RasterizerOptions)
|
||||
-> Result<Rasterizer, ()> {
|
||||
-> Result<Rasterizer, InitError> {
|
||||
let (draw_program, draw_position_attribute, draw_glyph_index_attribute);
|
||||
let (draw_glyph_descriptors_uniform, draw_image_descriptors_uniform);
|
||||
let draw_atlas_size_uniform;
|
||||
|
@ -96,9 +97,8 @@ impl Rasterizer {
|
|||
|
||||
try!(check_gl_object_status(draw_program,
|
||||
gl::LINK_STATUS,
|
||||
"Program",
|
||||
gl::GetProgramiv,
|
||||
gl::GetProgramInfoLog));
|
||||
gl::GetProgramInfoLog).map_err(InitError::LinkFailed));
|
||||
|
||||
gl::GenVertexArrays(1, &mut draw_vertex_array);
|
||||
|
||||
|
@ -124,7 +124,9 @@ impl Rasterizer {
|
|||
ShadingLanguage::Cl => ACCUM_CL_SHADER,
|
||||
ShadingLanguage::Glsl => ACCUM_COMPUTE_SHADER,
|
||||
};
|
||||
let accum_program = device.create_program(accum_source).unwrap();
|
||||
|
||||
let accum_program = try!(device.create_program(accum_source)
|
||||
.map_err(InitError::ComputeError));
|
||||
|
||||
Ok(Rasterizer {
|
||||
device: device,
|
||||
|
@ -148,7 +150,7 @@ impl Rasterizer {
|
|||
atlas: &Atlas,
|
||||
outline_buffers: &OutlineBuffers,
|
||||
coverage_buffer: &CoverageBuffer)
|
||||
-> Result<DrawAtlasProfilingEvents, ()> {
|
||||
-> Result<DrawAtlasProfilingEvents, RasterError> {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, coverage_buffer.framebuffer());
|
||||
gl::Viewport(0, 0, rect.size.width as GLint, rect.size.height as GLint);
|
||||
|
@ -230,7 +232,7 @@ impl Rasterizer {
|
|||
let accum_event = try!(self.queue.submit_compute(&self.accum_program,
|
||||
&[atlas.shelf_columns],
|
||||
&accum_uniforms,
|
||||
&[]).map_err(drop));
|
||||
&[]).map_err(RasterError::ComputeError));
|
||||
|
||||
Ok(DrawAtlasProfilingEvents {
|
||||
draw: self.draw_query,
|
||||
|
@ -239,26 +241,27 @@ impl Rasterizer {
|
|||
}
|
||||
}
|
||||
|
||||
fn compile_gl_shader(shader_type: GLuint, description: &str, source: &str) -> Result<GLuint, ()> {
|
||||
fn compile_gl_shader(shader_type: GLuint, description: &'static str, source: &str)
|
||||
-> Result<GLuint, InitError> {
|
||||
unsafe {
|
||||
let shader = gl::CreateShader(shader_type);
|
||||
gl::ShaderSource(shader, 1, &(source.as_ptr() as *const GLchar), &(source.len() as GLint));
|
||||
gl::CompileShader(shader);
|
||||
try!(check_gl_object_status(shader,
|
||||
match check_gl_object_status(shader,
|
||||
gl::COMPILE_STATUS,
|
||||
description,
|
||||
gl::GetShaderiv,
|
||||
gl::GetShaderInfoLog));
|
||||
Ok(shader)
|
||||
gl::GetShaderInfoLog) {
|
||||
Ok(_) => Ok(shader),
|
||||
Err(info_log) => Err(InitError::CompileFailed(description, info_log)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_gl_object_status(object: GLuint,
|
||||
parameter: GLenum,
|
||||
description: &str,
|
||||
get_status: unsafe fn(GLuint, GLenum, *mut GLint),
|
||||
get_log: unsafe fn(GLuint, GLsizei, *mut GLsizei, *mut GLchar))
|
||||
-> Result<(), ()> {
|
||||
-> Result<(), String> {
|
||||
unsafe {
|
||||
let mut status = 0;
|
||||
get_status(object, parameter, &mut status);
|
||||
|
@ -271,10 +274,11 @@ fn check_gl_object_status(object: GLuint,
|
|||
|
||||
let mut info_log = vec![0; info_log_length as usize];
|
||||
get_log(object, info_log_length, ptr::null_mut(), info_log.as_mut_ptr() as *mut GLchar);
|
||||
if let Ok(string) = String::from_utf8(info_log) {
|
||||
println!("{} error:\n{}", description, string);
|
||||
|
||||
match String::from_utf8(info_log) {
|
||||
Ok(string) => Err(string),
|
||||
Err(_) => Err("(not UTF-8)".to_owned()),
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,7 +296,7 @@ impl Default for RasterizerOptions {
|
|||
}
|
||||
|
||||
impl RasterizerOptions {
|
||||
pub fn from_env() -> Result<RasterizerOptions, ()> {
|
||||
pub fn from_env() -> Result<RasterizerOptions, InitError> {
|
||||
let force_geometry_shader = match env::var("PATHFINDER_FORCE_GEOMETRY_SHADER") {
|
||||
Ok(ref string) if string.eq_ignore_ascii_case("on") ||
|
||||
string.eq_ignore_ascii_case("yes") ||
|
||||
|
@ -301,7 +305,7 @@ impl RasterizerOptions {
|
|||
string.eq_ignore_ascii_case("no") ||
|
||||
string.eq_ignore_ascii_case("0") => false,
|
||||
Err(_) => false,
|
||||
Ok(_) => return Err(()),
|
||||
Ok(_) => return Err(InitError::InvalidSetting),
|
||||
};
|
||||
|
||||
Ok(RasterizerOptions {
|
||||
|
|
|
@ -31,6 +31,9 @@ impl RectPacker {
|
|||
}
|
||||
}
|
||||
|
||||
/// Packs a rectangle of the given size.
|
||||
///
|
||||
/// Returns the top-left position of the rectangle or an error if there is no space left.
|
||||
pub fn pack(&mut self, size: &Size2D<u32>) -> Result<Point2D<u32>, ()> {
|
||||
// Add a one-pixel border to prevent bleed.
|
||||
let alloc_size = *size + Size2D::new(2, 2);
|
||||
|
|
Loading…
Reference in New Issue