Skip to content

Make device::gl_device crate fully self-contained #597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/device/gl_device/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

use std::slice;

use {attrib, back, draw, target, tex, shade, state};
use {attrib, draw, target, tex, shade, state};
use {AttributeSlot, IndexType, InstanceCount, PrimitiveType, TextureSlot, UniformBlockIndex, UniformBufferSlot, VertexCount};
use super::{ArrayBuffer, Buffer, FrameBuffer, Program, Surface, Texture};
use super::{ArrayBuffer, Buffer, FrameBuffer, Program, Surface, Texture, GlResources};

/// Serialized device command.
#[derive(Copy, Debug)]
Expand All @@ -33,7 +33,7 @@ pub enum Command {
BindTargetTexture(target::Access, target::Target, Texture, target::Level, Option<target::Layer>),
BindUniformBlock(Program, UniformBufferSlot, UniformBlockIndex, Buffer),
BindUniform(shade::Location, shade::UniformValue),
BindTexture(TextureSlot, tex::TextureKind, Texture, Option<::SamplerHandle<back::GlResources>>),
BindTexture(TextureSlot, tex::TextureKind, Texture, Option<::SamplerHandle<GlResources>>),
SetDrawColorBuffers(usize),
SetPrimitiveState(state::Primitive),
SetViewport(target::Rect),
Expand Down Expand Up @@ -119,7 +119,7 @@ impl draw::CommandBuffer for CommandBuffer {
self.buf.push(Command::BindUniform(loc, value));
}
fn bind_texture(&mut self, slot: ::TextureSlot, kind: ::tex::TextureKind,
tex: Texture, sampler: Option<::SamplerHandle<back::GlResources>>) {
tex: Texture, sampler: Option<::SamplerHandle<GlResources>>) {
self.buf.push(Command::BindTexture(slot, kind, tex, sampler));
}

Expand Down
10 changes: 10 additions & 0 deletions src/device/gl_device/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ pub type Surface = gl::types::GLuint;
pub type Sampler = gl::types::GLuint;
pub type Texture = gl::types::GLuint;

/// A helper method to test `#[vertex_format]` without GL context
//#[cfg(test)]
pub fn make_dummy_buffer<T>() -> BufferHandle<GlResources, T> {
let info = ::BufferInfo {
usage: BufferUsage::Static,
size: 0,
};
BufferHandle::from_raw(::Handle(0, info))
}

#[derive(Copy, Clone, PartialEq, Debug)]
pub enum GlResources {}

Expand Down
13 changes: 0 additions & 13 deletions src/device/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ extern crate log;
extern crate bitflags;
extern crate libc;

// TODO: Remove these exports once `gl_device` becomes a separate crate.
pub use self::gl_device as back;

use std::fmt;
use std::mem;
use std::ops::{Deref, DerefMut};
Expand Down Expand Up @@ -248,16 +245,6 @@ pub type TextureHandle<R: Resources> = Handle<<R as Resources>::Texture, tex::Te
/// Sampler Handle
pub type SamplerHandle<R: Resources> = Handle<<R as Resources>::Sampler, tex::SamplerInfo>;

/// A helper method to test `#[vertex_format]` without GL context
//#[cfg(test)]
pub fn make_fake_buffer<T>() -> BufferHandle<back::GlResources, T> {
let info = BufferInfo {
usage: BufferUsage::Static,
size: 0,
};
BufferHandle::from_raw(Handle(0, info))
}

/// Treat a given slice as `&[u8]` for the given function call
pub fn as_byte_slice<T>(slice: &[T]) -> &[u8] {
let len = mem::size_of::<T>() * slice.len();
Expand Down
2 changes: 1 addition & 1 deletion src/gfx/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub struct Graphics<D: device::Device> {
/// Graphics device.
pub device: D,
/// Renderer front-end.
pub renderer: Renderer<D>,
pub renderer: Renderer<D::CommandBuffer>,
/// Hidden batch context.
context: batch::Context<D::Resources>,
}
Expand Down
4 changes: 2 additions & 2 deletions src/render/device_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<'a> ShaderSource<'a> {
/// Backend extension trait for convenience methods
pub trait DeviceExt: device::Device {
/// Create a new renderer
fn create_renderer(&mut self) -> ::Renderer<Self>;
fn create_renderer(&mut self) -> ::Renderer<Self::CommandBuffer>;
/// Create a new mesh from the given vertex data.
/// Convenience function around `create_buffer` and `Mesh::from_format`.
fn create_mesh<T>(&mut self, data: &[T]) -> Mesh<Self::Resources> where
Expand All @@ -75,7 +75,7 @@ pub trait DeviceExt: device::Device {
}

impl<D: device::Device> DeviceExt for D {
fn create_renderer(&mut self) -> ::Renderer<D> {
fn create_renderer(&mut self) -> ::Renderer<D::CommandBuffer> {
::Renderer {
command_buffer: device::draw::CommandBuffer::new(),
data_buffer: device::draw::DataBuffer::new(),
Expand Down
60 changes: 30 additions & 30 deletions src/render/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,18 @@ pub enum DrawError<E> {
}

/// Renderer front-end
pub struct Renderer<D: Device> {
command_buffer: D::CommandBuffer,
pub struct Renderer<C: CommandBuffer> {
command_buffer: C,
data_buffer: device::draw::DataBuffer,
common_array_buffer: Result<device::ArrayBufferHandle<D::Resources>, ()>,
draw_frame_buffer: device::FrameBufferHandle<D::Resources>,
read_frame_buffer: device::FrameBufferHandle<D::Resources>,
default_frame_buffer: device::FrameBufferHandle<D::Resources>,
render_state: RenderState<D::Resources>,
parameters: ParamStorage<D::Resources>,
common_array_buffer: Result<device::ArrayBufferHandle<C::Resources>, ()>,
draw_frame_buffer: device::FrameBufferHandle<C::Resources>,
read_frame_buffer: device::FrameBufferHandle<C::Resources>,
default_frame_buffer: device::FrameBufferHandle<C::Resources>,
render_state: RenderState<C::Resources>,
parameters: ParamStorage<C::Resources>,
}

impl<D: Device> Renderer<D> {
impl<C: CommandBuffer> Renderer<C> {
/// Reset all commands for the command buffer re-usal.
pub fn reset(&mut self) {
self.command_buffer.clear();
Expand All @@ -162,12 +162,12 @@ impl<D: Device> Renderer<D> {
}

/// Get command and data buffers to be submitted to the device.
pub fn as_buffer(&self) -> (&D::CommandBuffer, &device::draw::DataBuffer) {
pub fn as_buffer(&self) -> (&C, &device::draw::DataBuffer) {
(&self.command_buffer, &self.data_buffer)
}

/// Clone the renderer shared data but ignore the commands.
pub fn clone_empty(&self) -> Renderer<D> {
pub fn clone_empty(&self) -> Renderer<C> {
Renderer {
command_buffer: CommandBuffer::new(),
data_buffer: device::draw::DataBuffer::new(),
Expand All @@ -181,29 +181,29 @@ impl<D: Device> Renderer<D> {
}

/// Clear the `Frame` as the `ClearData` specifies.
pub fn clear(&mut self, data: ClearData, mask: Mask, frame: &target::Frame<D::Resources>) {
pub fn clear(&mut self, data: ClearData, mask: Mask, frame: &target::Frame<C::Resources>) {
self.bind_frame(frame);
self.command_buffer.call_clear(data, mask);
}

/// Draw a `batch` into the specified `frame`
pub fn draw<B: Batch<Resources = D::Resources>>(&mut self, batch: &B, frame: &target::Frame<D::Resources>)
pub fn draw<B: Batch<Resources = C::Resources>>(&mut self, batch: &B, frame: &target::Frame<C::Resources>)
-> Result<(), DrawError<B::Error>> {
self.draw_all(batch, None, frame)
}

/// Draw a `batch` multiple times using instancing
pub fn draw_instanced<B: Batch<Resources = D::Resources>>(&mut self, batch: &B,
pub fn draw_instanced<B: Batch<Resources = C::Resources>>(&mut self, batch: &B,
count: device::InstanceCount,
base: device::VertexCount,
frame: &target::Frame<D::Resources>)
frame: &target::Frame<C::Resources>)
-> Result<(), DrawError<B::Error>> {
self.draw_all(batch, Some((count, base)), frame)
}

/// Draw a 'batch' with all known parameters specified, internal use only.
fn draw_all<B: Batch<Resources = D::Resources>>(&mut self, batch: &B, instances: Option<Instancing>,
frame: &target::Frame<D::Resources>) -> Result<(), DrawError<B::Error>> {
fn draw_all<B: Batch<Resources = C::Resources>>(&mut self, batch: &B, instances: Option<Instancing>,
frame: &target::Frame<C::Resources>) -> Result<(), DrawError<B::Error>> {
let (mesh, attrib_iter, slice, state) = match batch.get_data() {
Ok(data) => data,
Err(e) => return Err(DrawError::InvalidBatch(e)),
Expand All @@ -224,8 +224,8 @@ impl<D: Device> Renderer<D> {
}

/// Blit one frame onto another
pub fn blit(&mut self, source: &target::Frame<D::Resources>, source_rect: Rect,
destination: &target::Frame<D::Resources>, dest_rect: Rect,
pub fn blit(&mut self, source: &target::Frame<C::Resources>, source_rect: Rect,
destination: &target::Frame<C::Resources>, dest_rect: Rect,
mirror: Mirror, mask: Mask) {
// verify as much as possible here
if mask.intersects(device::target::COLOR) {
Expand All @@ -247,7 +247,7 @@ impl<D: Device> Renderer<D> {
}

/// Update a buffer with data from a vector.
pub fn update_buffer_vec<T: Copy>(&mut self, buf: device::BufferHandle<D::Resources, T>,
pub fn update_buffer_vec<T: Copy>(&mut self, buf: device::BufferHandle<C::Resources, T>,
data: &[T], offset_elements: usize) {
let esize = mem::size_of::<T>();
let offset_bytes = esize * offset_elements;
Expand All @@ -258,21 +258,21 @@ impl<D: Device> Renderer<D> {

/// Update a buffer with data from a single type.
pub fn update_buffer_struct<U, T: Copy>(&mut self,
buf: device::BufferHandle<D::Resources, U>, data: &T) {
buf: device::BufferHandle<C::Resources, U>, data: &T) {
debug_assert!(mem::size_of::<T>() <= buf.get_info().size);
let pointer = self.data_buffer.add_struct(data);
self.command_buffer.update_buffer(buf.get_name(), pointer, 0);
}

/// Update the contents of a texture.
pub fn update_texture<T: Copy>(&mut self, tex: device::TextureHandle<D::Resources>,
pub fn update_texture<T: Copy>(&mut self, tex: device::TextureHandle<C::Resources>,
img: device::tex::ImageInfo, data: &[T]) {
debug_assert!(tex.get_info().contains(&img));
let pointer = self.data_buffer.add_vec(data);
self.command_buffer.update_texture(tex.get_info().kind, tex.get_name(), img, pointer);
}

fn bind_frame(&mut self, frame: &target::Frame<D::Resources>) {
fn bind_frame(&mut self, frame: &target::Frame<C::Resources>) {
if self.render_state.frame.width != frame.width ||
self.render_state.frame.height != frame.height {
self.command_buffer.set_viewport(Rect {
Expand Down Expand Up @@ -330,7 +330,7 @@ impl<D: Device> Renderer<D> {
}
}

fn bind_read_frame(&mut self, frame: &target::Frame<D::Resources>) {
fn bind_read_frame(&mut self, frame: &target::Frame<C::Resources>) {
self.command_buffer.bind_frame_buffer(Access::Read, self.read_frame_buffer.get_name());
// color
if frame.colors.is_empty() {
Expand Down Expand Up @@ -367,8 +367,8 @@ impl<D: Device> Renderer<D> {
self.render_state.draw = *state;
}

fn bind_program<'a, B: Batch<Resources = D::Resources>>(&mut self, batch: &'a B)
-> Result<&'a device::ProgramHandle<D::Resources>, B::Error> {
fn bind_program<'a, B: Batch<Resources = C::Resources>>(&mut self, batch: &'a B)
-> Result<&'a device::ProgramHandle<C::Resources>, B::Error> {
let program = match batch.fill_params(self.parameters.get_mut()) {
Ok(p) => p,
Err(e) => return Err(e),
Expand All @@ -382,7 +382,7 @@ impl<D: Device> Renderer<D> {
Ok(program)
}

fn upload_parameters(&mut self, program: &device::ProgramHandle<D::Resources>) {
fn upload_parameters(&mut self, program: &device::ProgramHandle<C::Resources>) {
let info = program.get_info();
if self.parameters.uniforms.len() != info.uniforms.len() ||
self.parameters.blocks.len() != info.blocks.len() ||
Expand Down Expand Up @@ -422,7 +422,7 @@ impl<D: Device> Renderer<D> {
}

fn bind_mesh<I: Iterator<Item = mesh::AttributeIndex>>(&mut self,
mesh: &mesh::Mesh<D::Resources>, attrib_iter: I, info: &ProgramInfo) {
mesh: &mesh::Mesh<C::Resources>, attrib_iter: I, info: &ProgramInfo) {
if !self.render_state.is_array_buffer_set {
// It's Ok if the array buffer is not supported. We can just ignore it.
self.common_array_buffer.map(|ab|
Expand All @@ -448,14 +448,14 @@ impl<D: Device> Renderer<D> {
}
}

fn bind_index<T>(&mut self, buf: device::BufferHandle<D::Resources, T>) {
fn bind_index<T>(&mut self, buf: device::BufferHandle<C::Resources, T>) {
if self.render_state.index != Some(buf.raw()) {
self.command_buffer.bind_index(buf.get_name());
self.render_state.index = Some(buf.raw());
}
}

fn draw_slice(&mut self, slice: &mesh::Slice<D::Resources>,
fn draw_slice(&mut self, slice: &mesh::Slice<C::Resources>,
instances: Option<(device::InstanceCount, device::VertexCount)>) {
let mesh::Slice { start, end, prim_type, kind } = slice.clone();
match kind {
Expand Down
4 changes: 2 additions & 2 deletions tests/vertex_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ fn test_vertex_format() {
use secret_lib::gfx;
use secret_lib::device;

let buf_vert = device::make_fake_buffer();
let buf_inst = device::make_fake_buffer();
let buf_vert = device::gl_device::make_dummy_buffer();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like these tests to be device-agnostic. We'll clean it up later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

let buf_inst = device::gl_device::make_dummy_buffer();
let mesh = gfx::Mesh::from_format_instanced::<MyVertex, MyInstance>(buf_vert, 0, buf_inst);
let stride_vert = 34 as Stride;
let stride_inst = 8 as Stride;
Expand Down