Skip to content
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

Add more control over when and how to clear the framebuffer. #605

Merged
merged 1 commit into from Dec 12, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -15,7 +15,7 @@ use std::io::Read;
use std::fs::File;
use std::path::{Path, PathBuf};
use std::env;
use webrender_traits::{ApiMsg, RenderApi, PipelineId, LayerSize, DeviceUintSize};
use webrender_traits::{ApiMsg, RenderApi, PipelineId, LayerSize, DeviceUintSize, ColorF};
use webrender_traits::channel::PayloadHelperMethods;
use glutin::{Event, ElementState, VirtualKeyCode as Key};

@@ -119,6 +119,9 @@ fn main() {
renderer_kind: webrender_traits::RendererKind::Native,
debug: false,
enable_subpixel_aa: false,
clear_framebuffer: true,
clear_empty_tiles: false,
clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0),
};

let (mut renderer, sender) = webrender::renderer::Renderer::new(opts);
@@ -66,7 +66,6 @@ fn main() {
unsafe {
window.make_current().ok();
gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
gl::clear_color(0.3, 0.0, 0.0, 1.0);
}

println!("OpenGL version {}", gl::get_string(gl::VERSION));
@@ -86,6 +85,9 @@ fn main() {
precache_shaders: true,
renderer_kind: RendererKind::Native,
enable_subpixel_aa: false,
clear_framebuffer: true,
clear_empty_tiles: false,
clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0),
};

let (mut renderer, sender) = webrender::renderer::Renderer::new(opts);
@@ -219,14 +221,13 @@ fn main() {
builder.pop_stacking_context();

api.set_root_display_list(
root_background_color,
Some(root_background_color),
epoch,
LayoutSize::new(width as f32, height as f32),
builder);
api.set_root_pipeline(pipeline_id);

for event in window.wait_events() {
gl::clear(gl::COLOR_BUFFER_BIT);
renderer.update();

renderer.render(DeviceUintSize::new(width, height));
@@ -651,41 +651,28 @@ impl Frame {
};

if level == 0 {
// Add a large white rectangle as the root display item if there is no root stacking
// context background color. This is removed by the occlusion culling for most tiles,
// and means that it's no longer necessary to clear the framebuffer.
//
// TODO(nical) Should painting a white background be optional if there is no stacking
// context background color? On deferred GPUs we probably still want to clear the
// framebuffer and Gecko currently supports semi-transparent windows.
//
// If we do need this, does it make sense to keep Frame::clear_tiles?
let mut root_background_color = match context.scene.pipeline_map.get(&pipeline_id) {
Some(pipeline) => pipeline.background_color,
None => ColorF::new(1.0, 1.0, 1.0, 1.0),
};
if let Some(pipeline) = context.scene.pipeline_map.get(&pipeline_id) {
if let Some(bg_color) = pipeline.background_color {

// Adding a dummy layer for this rectangle in order to disable clipping.
let no_clip = ClipRegion::simple(&clip_region.main);
context.builder.push_layer(clip_region.main,
&no_clip,
transform,
pipeline_id,
scroll_layer_id,
&composition_operations);

//Note: we don't use the original clip region here,
// it's already processed by the layer we just pushed.
context.builder.add_solid_rectangle(&clip_region.main,
&no_clip,
&bg_color,
PrimitiveFlags::None);

if root_background_color.a == 0.0 {
root_background_color = ColorF::new(1.0, 1.0, 1.0, 1.0);
context.builder.pop_layer();
}
}

// Adding a dummy layer for this rectangle in order to disable clipping.
let no_clip = ClipRegion::simple(&clip_region.main);
context.builder.push_layer(clip_region.main,
&no_clip,
transform,
pipeline_id,
scroll_layer_id,
&composition_operations);

//Note: we don't use the original clip region here,
// it's already processed by the layer we just pushed.
context.builder.add_solid_rectangle(&clip_region.main,
&no_clip,
&root_background_color,
PrimitiveFlags::None);

context.builder.pop_layer();
}

// TODO(gw): Int with overflow etc
@@ -368,7 +368,7 @@ pub struct Renderer {

tile_clear_shader: LazilyCompiledShader,

max_clear_tiles: usize,
max_empty_tiles: usize,
max_prim_instances: usize,
max_cache_instances: usize,
max_clip_instances: usize,
@@ -377,6 +377,9 @@ pub struct Renderer {
notifier: Arc<Mutex<Option<Box<RenderNotifier>>>>,

enable_profiler: bool,
clear_framebuffer: bool,
clear_empty_tiles: bool,
clear_color: ColorF,
debug: DebugRenderer,
backend_profile_counters: BackendProfileCounters,
profile_counters: RendererProfileCounters,
@@ -593,7 +596,7 @@ impl Renderer {
&mut device,
options.precache_shaders);

let max_clear_tiles = get_ubo_max_len::<ClearTile>(max_ubo_size);
let max_empty_tiles = get_ubo_max_len::<ClearTile>(max_ubo_size);
let tile_clear_shader = LazilyCompiledShader::new(ShaderKind::Clear,
"ps_clear",
max_ubo_vectors,
@@ -739,7 +742,7 @@ impl Renderer {
ps_cache_image: ps_cache_image,
ps_blend: ps_blend,
ps_composite: ps_composite,
max_clear_tiles: max_clear_tiles,
max_empty_tiles: max_empty_tiles,
max_prim_instances: max_prim_instances,
max_cache_instances: max_cache_instances,
max_clip_instances: max_clip_instances,
@@ -750,6 +753,9 @@ impl Renderer {
profile_counters: RendererProfileCounters::new(),
profiler: Profiler::new(),
enable_profiler: options.enable_profiler,
clear_framebuffer: options.clear_framebuffer,
clear_empty_tiles: options.clear_empty_tiles,
clear_color: options.clear_color,
last_time: 0,
render_targets: Vec::new(),
gpu_profile: GpuProfiler::new(),
@@ -1097,7 +1103,7 @@ impl Renderer {
ORTHO_FAR_PLANE)
),
None => (
[1.0, 1.0, 1.0, 1.0],
self.clear_color.to_array(),
Matrix4D::ortho(0.0,
target_size.width,
target_size.height,
@@ -1107,7 +1113,6 @@ impl Renderer {
),
};

// todo(gw): remove me!
if should_clear {
self.device.clear_color(color);
}
@@ -1487,7 +1492,7 @@ impl Renderer {
ORTHO_FAR_PLANE);

if frame.passes.is_empty() {
self.device.clear_color([1.0, 1.0, 1.0, 1.0]);
self.device.clear_color(self.clear_color.to_array());
} else {
// Add new render targets to the pool if required.
let needed_targets = frame.passes.len() - 1; // framebuffer doesn't need a target!
@@ -1533,7 +1538,7 @@ impl Renderer {

for (pass_index, pass) in frame.passes.iter().enumerate() {
let (do_clear, size, target_id) = if pass.is_framebuffer {
(needs_clear,
(self.clear_framebuffer || needs_clear,
DeviceSize::new(framebuffer_size.width as f32, framebuffer_size.height as f32),
None)
} else {
@@ -1558,12 +1563,12 @@ impl Renderer {

let _gm = self.gpu_profile.add_marker(GPU_TAG_CLEAR_TILES);

// Clear tiles with no items
if !frame.clear_tiles.is_empty() {
// Tiles with no items
if self.clear_empty_tiles && !frame.empty_tiles.is_empty() {
self.device.set_blend(false);
let shader = self.tile_clear_shader.get(&mut self.device);
let max_prim_items = self.max_clear_tiles;
self.draw_ubo_batch(&frame.clear_tiles,
let max_prim_items = self.max_empty_tiles;
self.draw_ubo_batch(&frame.empty_tiles,
shader,
1,
&BatchTextures::no_texture(),
@@ -1630,4 +1635,8 @@ pub struct RendererOptions {
pub precache_shaders: bool,
pub renderer_kind: RendererKind,
pub enable_subpixel_aa: bool,
// TODO: this option ignores the clear color (always opaque white).
pub clear_empty_tiles: bool,
pub clear_framebuffer: bool,
pub clear_color: ColorF,
}
@@ -29,7 +29,7 @@ pub struct ScenePipeline {
pub pipeline_id: PipelineId,
pub epoch: Epoch,
pub viewport_size: LayerSize,
pub background_color: ColorF,
pub background_color: Option<ColorF>,
}

/// A complete representation of the layout bundling visible pipelines together.
@@ -60,7 +60,7 @@ impl Scene {
pipeline_id: PipelineId,
epoch: Epoch,
built_display_list: BuiltDisplayList,
background_color: ColorF,
background_color: Option<ColorF>,
viewport_size: LayerSize,
auxiliary_lists: AuxiliaryLists) {
self.pipeline_auxiliary_lists.insert(pipeline_id, auxiliary_lists);
@@ -1680,7 +1680,7 @@ pub struct Frame {
pub debug_rects: Vec<DebugRect>,
pub cache_size: DeviceSize,
pub passes: Vec<RenderPass>,
pub clear_tiles: Vec<ClearTile>,
pub empty_tiles: Vec<ClearTile>,
pub profile_counters: FrameProfileCounters,

pub layer_texture_data: Vec<PackedStackingContext>,
@@ -2803,7 +2803,7 @@ impl FrameBuilder {
&mut profile_counters,
device_pixel_ratio);

let mut clear_tiles = Vec::new();
let mut empty_tiles = Vec::new();
let mut compiled_screen_tiles = Vec::new();
let mut max_passes_needed = 0;

@@ -2852,7 +2852,7 @@ impl FrameBuilder {
compiled_screen_tiles.push(compiled_screen_tile);
}
None => {
clear_tiles.push(ClearTile {
empty_tiles.push(ClearTile {
rect: rect,
});
}
@@ -2918,7 +2918,7 @@ impl FrameBuilder {
debug_rects: debug_rects,
profile_counters: profile_counters,
passes: passes,
clear_tiles: clear_tiles,
empty_tiles: empty_tiles,
cache_size: DeviceSize::new(RENDERABLE_CACHE_SIZE as f32,
RENDERABLE_CACHE_SIZE as f32),
layer_texture_data: self.packed_layers.clone(),
@@ -155,7 +155,7 @@ impl RenderApi {
///
/// [notifier]: trait.RenderNotifier.html#tymethod.new_frame_ready
pub fn set_root_display_list(&self,
background_color: ColorF,
background_color: Option<ColorF>,
epoch: Epoch,
viewport_size: LayoutSize,
builder: DisplayListBuilder) {
@@ -94,6 +94,10 @@ impl ColorF {
a: self.a,
}
}

pub fn to_array(&self) -> [f32; 4] {
[self.r, self.g, self.b, self.a]
}
}

impl ComplexClipRegion {
@@ -38,7 +38,7 @@ pub enum ApiMsg {
///
/// After receiving this message, WebRender will read the display list, followed by the
/// auxiliary lists, from the payload channel.
SetRootDisplayList(ColorF,
SetRootDisplayList(Option<ColorF>,
Epoch,
PipelineId,
LayoutSize,
@@ -64,7 +64,7 @@ impl JsonFrameWriter {
}

pub fn begin_write_root_display_list(&mut self,
_: &ColorF,
_: &Option<ColorF>,
_: &Epoch,
_: &PipelineId,
_: &LayoutSize,
@@ -166,6 +166,9 @@ impl Wrench {
debug: debug,
precache_shaders: false,
renderer_kind: RendererKind::Native,
clear_framebuffer: true,
clear_empty_tiles: false,
clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0),
};

let (renderer, sender) = webrender::renderer::Renderer::new(opts);
@@ -320,7 +323,7 @@ impl Wrench {
pub fn send_lists(&mut self, frame_number: u32, display_list: DisplayListBuilder) {
self.frame_start_sender.push(time::SteadyTime::now());

let root_background_color = ColorF::new(0.3, 0.0, 0.0, 1.0);
let root_background_color = Some(ColorF::new(0.3, 0.0, 0.0, 1.0));
self.api.set_root_display_list(root_background_color,
Epoch(frame_number),
self.window_size_f32(),
@@ -215,7 +215,7 @@ impl YamlFrameWriter {
}

pub fn begin_write_root_display_list(&mut self,
_: &ColorF,
_: &Option<ColorF>,
_: &Epoch,
_: &PipelineId,
_: &LayoutSize,
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.