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

Support resizing an image in the texture cache. #925

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Support resizing an image in the texture cache.

  • Loading branch information
nical committed Feb 24, 2017
commit afc63da7c94539713849cd690084de80019e07b4
@@ -110,6 +110,13 @@ fn main() {
None,
);

let (desc, data) = generate_xy_gradient_image(100, 100);
let resized_img = api.generate_image_key();
api.add_image(
resized_img, desc, ImageData::new(data),
None,
);

let pipeline_id = PipelineId(0, 0);
let mut builder = webrender_traits::DisplayListBuilder::new(pipeline_id);

@@ -131,12 +138,12 @@ fn main() {
webrender_traits::MixBlendMode::Normal,
Vec::new());
builder.push_image(
LayoutRect::new(LayoutPoint::new(0.0, 0.0), LayoutSize::new(100.0, 100.0)),
LayoutRect::new(LayoutPoint::new(0.0, 0.0), LayoutSize::new(1000.0, 1000.0)),
ClipRegion::simple(&bounds),
LayoutSize::new(100.0, 100.0),
LayoutSize::new(1000.0, 1000.0),
LayoutSize::new(0.0, 0.0),
ImageRendering::Auto,
vector_img,
resized_img,
);

let sub_clip = {
@@ -267,13 +274,24 @@ fn main() {
api.set_root_pipeline(pipeline_id);
api.generate_frame(None);

let mut x = 0.0;

for event in window.wait_events() {

renderer.update();

renderer.render(DeviceUintSize::new(width, height));

window.swap_buffers().ok();

x += 0.1f32;
let sz = (x.sin() * 40.0 + 200.0) as u32;
//let sz = 100;
let (desc, data) = generate_xy_gradient_image(sz, sz);
api.update_image(resized_img, desc, data);

api.generate_frame(None);

match event {
glutin::Event::Closed |
glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) |
@@ -334,3 +352,21 @@ impl BlobImageRenderer for FakeBlobImageRenderer {
self.images.remove(&key).unwrap_or(Err(BlobImageError::InvalidKey))
}
}

fn generate_xy_gradient_image(w: u32, h: u32) -> (ImageDescriptor, Vec<u8>) {
let mut pixels = Vec::with_capacity((w * h * 4) as usize);
for y in 0..h {
for x in 0..w {
let grid = if x % 100 < 3 || y % 100 < 3 { 0.9 } else { 1.0 };
pixels.push((y as f32 / h as f32 * 255.0 * grid) as u8);
pixels.push(0);
pixels.push((x as f32 / w as f32 * 255.0 * grid) as u8);
pixels.push(255);
}
}

return (
ImageDescriptor::new(w, h, ImageFormat::RGBA8, true),
pixels
);
}
@@ -641,13 +641,19 @@ impl ResourceCache {
// external handle doesn't need to update the texture_cache.
}
ImageData::Raw(..) | ImageData::ExternalBuffer(..) | ImageData::Blob(..) => {
let filter = match request.rendering {
ImageRendering::Pixelated => TextureFilter::Nearest,
ImageRendering::Auto | ImageRendering::CrispEdges => TextureFilter::Linear,
};

match self.cached_images.entry(request.clone(), self.current_frame_id) {
Occupied(entry) => {
let image_id = entry.get().texture_cache_id;

if entry.get().epoch != image_template.epoch {
self.texture_cache.update(image_id,
image_template.descriptor,
filter,
image_data);

// Update the cached epoch
@@ -660,11 +666,6 @@ impl ResourceCache {
Vacant(entry) => {
let image_id = self.texture_cache.new_item_id();

let filter = match request.rendering {
ImageRendering::Pixelated => TextureFilter::Nearest,
ImageRendering::Auto | ImageRendering::CrispEdges => TextureFilter::Linear,
};

if let Some(tile) = request.tile {
let tile_size = image_template.tiling.unwrap() as u32;
let image_descriptor = image_template.descriptor.clone();
@@ -709,12 +709,34 @@ impl TextureCache {
pub fn update(&mut self,
image_id: TextureCacheItemId,
descriptor: ImageDescriptor,
filter: TextureFilter,
data: ImageData) {
let existing_item = self.items.get(image_id);
let existing_item = self.items.get(image_id).clone();

// TODO(gw): Handle updates to size/format!
debug_assert_eq!(existing_item.allocated_rect.size.width, descriptor.width);
debug_assert_eq!(existing_item.allocated_rect.size.height, descriptor.height);
println!(" -- update {:?}", image_id);

if existing_item.allocated_rect.size.width != descriptor.width ||
existing_item.allocated_rect.size.height != descriptor.height {
match self.arena.texture_page_for_id(existing_item.texture_id) {
Some(texture_page) => texture_page.free(&existing_item.allocated_rect),
None => {
// This is a standalone texture allocation. Just push it back onto the free
// list.
self.pending_updates.push(TextureUpdate {
id: existing_item.texture_id,
op: TextureUpdateOp::Free,
});
self.cache_id_list.free(existing_item.texture_id);
}
}

self.allocate(image_id,
descriptor.width,
descriptor.height,
descriptor.format,
filter);
return;
}

let op = match data {
ImageData::ExternalHandle(..) | ImageData::ExternalBuffer(..)=> {
@@ -753,6 +775,8 @@ impl TextureCache {
panic!("must rasterize the vector image before adding to the cache");
}

println!(" -- insert {:?}", image_id);

let width = descriptor.width;
let height = descriptor.height;
let format = descriptor.format;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.