Create framebuffers for every texture page
This commit is contained in:
parent
a3736859ba
commit
e50039f4c2
|
@ -115,7 +115,7 @@ where
|
||||||
dest_blend_framebuffer: D::Framebuffer,
|
dest_blend_framebuffer: D::Framebuffer,
|
||||||
intermediate_dest_framebuffer: D::Framebuffer,
|
intermediate_dest_framebuffer: D::Framebuffer,
|
||||||
texture_pages: Vec<TexturePage<D>>,
|
texture_pages: Vec<TexturePage<D>>,
|
||||||
render_targets: Vec<RenderTargetInfo<D>>,
|
render_targets: Vec<RenderTargetInfo>,
|
||||||
render_target_stack: Vec<RenderTargetId>,
|
render_target_stack: Vec<RenderTargetId>,
|
||||||
|
|
||||||
// This is a dummy texture consisting solely of a single `rgba(0, 0, 0, 255)` texel. It serves
|
// This is a dummy texture consisting solely of a single `rgba(0, 0, 0, 255)` texel. It serves
|
||||||
|
@ -573,43 +573,37 @@ where
|
||||||
fn add_texture_data(&mut self, texture_data: &TextureData) {
|
fn add_texture_data(&mut self, texture_data: &TextureData) {
|
||||||
// Clear out old paint textures.
|
// Clear out old paint textures.
|
||||||
for old_texture_page in self.texture_pages.drain(..) {
|
for old_texture_page in self.texture_pages.drain(..) {
|
||||||
match old_texture_page {
|
let old_texture = self.device.destroy_framebuffer(old_texture_page.framebuffer);
|
||||||
TexturePage::Texture(texture) => self.texture_cache.release_texture(texture),
|
self.texture_cache.release_texture(old_texture);
|
||||||
TexturePage::RenderTarget(_) => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear out old render targets.
|
// Clear out old render targets.
|
||||||
for render_target in self.render_targets.drain(..) {
|
self.render_targets.clear();
|
||||||
let texture = self.device.destroy_framebuffer(render_target.framebuffer);
|
|
||||||
self.texture_cache.release_texture(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build up new paint textures and render targets.
|
// Build up new paint textures and render targets.
|
||||||
for texture_page_data in &texture_data.pages {
|
for texture_page_data in &texture_data.pages {
|
||||||
let texture_size = texture_page_data.size;
|
let texture_size = texture_page_data.size;
|
||||||
let texture_page = self.texture_cache.create_texture(&mut self.device,
|
let texture = self.texture_cache.create_texture(&mut self.device,
|
||||||
TextureFormat::RGBA8,
|
TextureFormat::RGBA8,
|
||||||
texture_size);
|
texture_size);
|
||||||
|
let texture_page_id = TexturePageId(self.texture_pages.len() as u32);
|
||||||
|
let must_preserve_contents;
|
||||||
match texture_page_data.contents {
|
match texture_page_data.contents {
|
||||||
TexturePageContents::RenderTarget(render_target_id) => {
|
TexturePageContents::RenderTarget(render_target_id) => {
|
||||||
let framebuffer = self.device.create_framebuffer(texture_page);
|
debug_assert_eq!(render_target_id.0, self.render_targets.len() as u32);
|
||||||
self.render_targets.push(RenderTargetInfo {
|
self.render_targets.push(RenderTargetInfo { texture_page: texture_page_id });
|
||||||
framebuffer,
|
must_preserve_contents = false;
|
||||||
must_preserve_contents: false
|
|
||||||
});
|
|
||||||
|
|
||||||
self.texture_pages.push(TexturePage::RenderTarget(render_target_id));
|
|
||||||
}
|
}
|
||||||
TexturePageContents::Texels(ref texels) => {
|
TexturePageContents::Texels(ref texels) => {
|
||||||
let texels = color::color_slice_to_u8_slice(texels);
|
let texels = color::color_slice_to_u8_slice(texels);
|
||||||
self.device.upload_to_texture(&texture_page,
|
self.device.upload_to_texture(&texture,
|
||||||
RectI::new(Vector2I::default(), texture_size),
|
RectI::new(Vector2I::default(), texture_size),
|
||||||
TextureDataRef::U8(texels));
|
TextureDataRef::U8(texels));
|
||||||
|
must_preserve_contents = true;
|
||||||
self.texture_pages.push(TexturePage::Texture(texture_page));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let framebuffer = self.device.create_framebuffer(texture);
|
||||||
|
self.texture_pages.push(TexturePage { framebuffer, must_preserve_contents });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1148,7 +1142,8 @@ where
|
||||||
pub fn draw_render_target(&self) -> RenderTarget<D> {
|
pub fn draw_render_target(&self) -> RenderTarget<D> {
|
||||||
match self.render_target_stack.last() {
|
match self.render_target_stack.last() {
|
||||||
Some(&render_target_id) => {
|
Some(&render_target_id) => {
|
||||||
let framebuffer = &self.render_targets[render_target_id.0 as usize].framebuffer;
|
let texture_page_id = self.render_target_texture_page_id(render_target_id);
|
||||||
|
let framebuffer = self.texture_page_framebuffer(texture_page_id);
|
||||||
RenderTarget::Framebuffer(framebuffer)
|
RenderTarget::Framebuffer(framebuffer)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -1258,9 +1253,9 @@ where
|
||||||
render_target_id: RenderTargetId,
|
render_target_id: RenderTargetId,
|
||||||
direction: BlurDirection,
|
direction: BlurDirection,
|
||||||
sigma: f32) {
|
sigma: f32) {
|
||||||
let source_framebuffer = &self.render_targets[render_target_id.0 as usize].framebuffer;
|
let src_texture_page = self.render_target_texture_page_id(render_target_id);
|
||||||
let source_texture = self.device.framebuffer_texture(source_framebuffer);
|
let src_texture = self.texture_page(src_texture_page);
|
||||||
let source_texture_size = self.device.texture_size(source_texture);
|
let src_texture_size = self.device.texture_size(src_texture);
|
||||||
|
|
||||||
let sigma_inv = 1.0 / sigma;
|
let sigma_inv = 1.0 / sigma;
|
||||||
let gauss_coeff_x = SQRT_2_PI_INV * sigma_inv;
|
let gauss_coeff_x = SQRT_2_PI_INV * sigma_inv;
|
||||||
|
@ -1271,7 +1266,7 @@ where
|
||||||
BlurDirection::X => Vector2F::new(1.0, 0.0),
|
BlurDirection::X => Vector2F::new(1.0, 0.0),
|
||||||
BlurDirection::Y => Vector2F::new(0.0, 1.0),
|
BlurDirection::Y => Vector2F::new(0.0, 1.0),
|
||||||
};
|
};
|
||||||
let src_offset_scale = src_offset / source_texture_size.to_f32();
|
let src_offset_scale = src_offset / src_texture_size.to_f32();
|
||||||
|
|
||||||
let uniforms = vec![
|
let uniforms = vec![
|
||||||
(&self.tile_filter_blur_program.src_offset_scale_uniform,
|
(&self.tile_filter_blur_program.src_offset_scale_uniform,
|
||||||
|
@ -1304,8 +1299,8 @@ where
|
||||||
blend_state: Option<BlendState>) {
|
blend_state: Option<BlendState>) {
|
||||||
let clear_color = self.clear_color_for_draw_operation();
|
let clear_color = self.clear_color_for_draw_operation();
|
||||||
let main_viewport = self.main_viewport();
|
let main_viewport = self.main_viewport();
|
||||||
let src_framebuffer = &self.render_targets[render_target_id.0 as usize].framebuffer;
|
let src_texture_page = self.render_target_texture_page_id(render_target_id);
|
||||||
let src_texture = self.device.framebuffer_texture(src_framebuffer);
|
let src_texture = self.texture_page(src_texture_page);
|
||||||
let src_texture_size = self.device.texture_size(src_texture);
|
let src_texture_size = self.device.texture_size(src_texture);
|
||||||
|
|
||||||
uniforms.extend_from_slice(&[
|
uniforms.extend_from_slice(&[
|
||||||
|
@ -1372,8 +1367,9 @@ where
|
||||||
|
|
||||||
fn clear_color_for_draw_operation(&self) -> Option<ColorF> {
|
fn clear_color_for_draw_operation(&self) -> Option<ColorF> {
|
||||||
let must_preserve_contents = match self.render_target_stack.last() {
|
let must_preserve_contents = match self.render_target_stack.last() {
|
||||||
Some(render_target_id) => {
|
Some(&render_target_id) => {
|
||||||
self.render_targets[render_target_id.0 as usize].must_preserve_contents
|
let texture_page = self.render_target_texture_page_id(render_target_id);
|
||||||
|
self.texture_pages[texture_page.0 as usize].must_preserve_contents
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.framebuffer_flags
|
self.framebuffer_flags
|
||||||
|
@ -1392,8 +1388,9 @@ where
|
||||||
|
|
||||||
fn preserve_draw_framebuffer(&mut self) {
|
fn preserve_draw_framebuffer(&mut self) {
|
||||||
match self.render_target_stack.last() {
|
match self.render_target_stack.last() {
|
||||||
Some(render_target_id) => {
|
Some(&render_target_id) => {
|
||||||
self.render_targets[render_target_id.0 as usize].must_preserve_contents = true;
|
let texture_page = self.render_target_texture_page_id(render_target_id);
|
||||||
|
self.texture_pages[texture_page.0 as usize].must_preserve_contents = true;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.framebuffer_flags
|
self.framebuffer_flags
|
||||||
|
@ -1404,9 +1401,9 @@ where
|
||||||
|
|
||||||
pub fn draw_viewport(&self) -> RectI {
|
pub fn draw_viewport(&self) -> RectI {
|
||||||
match self.render_target_stack.last() {
|
match self.render_target_stack.last() {
|
||||||
Some(render_target_id) => {
|
Some(&render_target_id) => {
|
||||||
let framebuffer = &self.render_targets[render_target_id.0 as usize].framebuffer;
|
let texture_page = self.render_target_texture_page_id(render_target_id);
|
||||||
let texture = self.device.framebuffer_texture(framebuffer);
|
let texture = self.texture_page(texture_page);
|
||||||
RectI::new(Vector2I::default(), self.device.texture_size(texture))
|
RectI::new(Vector2I::default(), self.device.texture_size(texture))
|
||||||
}
|
}
|
||||||
None => self.main_viewport(),
|
None => self.main_viewport(),
|
||||||
|
@ -1430,14 +1427,16 @@ where
|
||||||
Vector2I::new(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT))
|
Vector2I::new(MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_target_texture_page_id(&self, render_target_id: RenderTargetId) -> TexturePageId {
|
||||||
|
self.render_targets[render_target_id.0 as usize].texture_page
|
||||||
|
}
|
||||||
|
|
||||||
|
fn texture_page_framebuffer(&self, id: TexturePageId) -> &D::Framebuffer {
|
||||||
|
&self.texture_pages[id.0 as usize].framebuffer
|
||||||
|
}
|
||||||
|
|
||||||
fn texture_page(&self, id: TexturePageId) -> &D::Texture {
|
fn texture_page(&self, id: TexturePageId) -> &D::Texture {
|
||||||
match self.texture_pages[id.0 as usize] {
|
self.device.framebuffer_texture(&self.texture_page_framebuffer(id))
|
||||||
TexturePage::Texture(ref texture) => texture,
|
|
||||||
TexturePage::RenderTarget(render_target_id) => {
|
|
||||||
let framebuffer = &self.render_targets[render_target_id.0 as usize].framebuffer;
|
|
||||||
self.device.framebuffer_texture(framebuffer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocate_timer_query(&mut self) -> D::TimerQuery {
|
fn allocate_timer_query(&mut self) -> D::TimerQuery {
|
||||||
|
@ -1568,16 +1567,15 @@ impl<D> TextureCache<D> where D: Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TexturePage<D> where D: Device {
|
struct TexturePage<D> where D: Device {
|
||||||
Texture(D::Texture),
|
|
||||||
RenderTarget(RenderTargetId),
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RenderTargetInfo<D> where D: Device {
|
|
||||||
framebuffer: D::Framebuffer,
|
framebuffer: D::Framebuffer,
|
||||||
must_preserve_contents: bool,
|
must_preserve_contents: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RenderTargetInfo {
|
||||||
|
texture_page: TexturePageId,
|
||||||
|
}
|
||||||
|
|
||||||
trait ToBlendState {
|
trait ToBlendState {
|
||||||
fn to_blend_state(self) -> Option<BlendState>;
|
fn to_blend_state(self) -> Option<BlendState>;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue