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

Revert "Store tile dirty rects in tile space." #3284

Merged
merged 1 commit into from Nov 7, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -196,21 +196,21 @@ pub fn intersect_for_tile(

fn merge_dirty_rect(
prev_dirty_rect: &Option<DeviceUintRect>,
dirty_rect: &DeviceUintRect,
dst_size: &DeviceUintSize,
dirty_rect: &Option<DeviceUintRect>,
descriptor: &ImageDescriptor,
) -> Option<DeviceUintRect> {
// It is important to never assume a dirty rect equal to None implies a full reupload here,
// although we are able to do so elsewhere. We store the image or tile's full rect instead
// It is important to never assume an empty dirty rect implies a full reupload here,
// although we are able to do so elsewhere. We store the descriptor's full rect instead
// There are update sequences which could cause us to forget the correct dirty regions
// regions if we cleared the dirty rect when we received None, e.g.:
// 1) Update with no dirty rect. We want to reupload everything.
// 2) Update with dirty rect B. We still want to reupload everything, not just B.
// 3) Perform the upload some time later.
let full_rect = DeviceUintRect::from(*dst_size);
match *prev_dirty_rect {
Some(ref prev_rect) => dirty_rect.union(&prev_rect),
None => *dirty_rect,
}.intersection(&full_rect)
match (dirty_rect, prev_dirty_rect) {
(&Some(ref rect), &Some(ref prev_rect)) => Some(rect.union(&prev_rect)),
(&Some(ref rect), &None) => Some(*rect),
(&None, _) => Some(descriptor.full_rect()),
}
}

impl<K, V, U> ResourceClassCache<K, V, U>
@@ -754,9 +754,6 @@ impl ResourceCache {
data: ImageData,
dirty_rect: Option<DeviceUintRect>,
) {
let dirty_rect = dirty_rect.unwrap_or_else(|| {
descriptor.full_rect()
});
let max_texture_size = self.max_texture_size();
let image = match self.resources.image_templates.get_mut(image_key) {
Some(res) => res,
@@ -772,25 +769,24 @@ impl ResourceCache {
// updated independently.
match self.cached_images.try_get_mut(&image_key) {
Some(&mut ImageResult::UntiledAuto(ref mut entry)) => {
entry.dirty_rect = merge_dirty_rect(&entry.dirty_rect, &dirty_rect, &descriptor.size);
entry.dirty_rect = merge_dirty_rect(&entry.dirty_rect, &dirty_rect, &descriptor);
}
Some(&mut ImageResult::Multi(ref mut entries)) => {
let tile_size = tiling.unwrap();
for (key, entry) in entries.iter_mut() {
let (local_dirty_rect, local_size) = match key.tile {
Some(tile) => {
let tile_offset = DeviceUintPoint::new(tile.x as u32, tile.y as u32) * tile_size as u32;
let mut tile_dirty_rect = dirty_rect;
tile_dirty_rect.origin -= tile_offset.to_vector();
(tile_dirty_rect, compute_tile_size(&descriptor, tile_size, tile))
let merged_rect = merge_dirty_rect(&entry.dirty_rect, &dirty_rect, &descriptor);

entry.dirty_rect = match (key.tile, merged_rect) {
(Some(tile), Some(rect)) => {
let tile_size = image.tiling.unwrap();
let clipped_tile_size = compute_tile_size(&descriptor, tile_size, tile);

rect.intersection(&DeviceUintRect::new(
DeviceUintPoint::new(tile.x as u32, tile.y as u32) * tile_size as u32,
clipped_tile_size,
))
}
None => (dirty_rect, descriptor.size),
_ => merged_rect,
};
entry.dirty_rect = merge_dirty_rect(
&entry.dirty_rect,
&local_dirty_rect,
&local_size
);
}
}
_ => {}
@@ -1528,12 +1524,23 @@ impl ResourceCache {
};

let mut descriptor = image_template.descriptor.clone();
let mut dirty_rect = entry.dirty_rect.take();
let mut local_dirty_rect;

if let Some(tile) = request.tile {
let tile_size = image_template.tiling.unwrap();
let clipped_tile_size = compute_tile_size(&descriptor, tile_size, tile);

local_dirty_rect = if let Some(rect) = entry.dirty_rect.take() {
// We should either have a dirty rect, or we are re-uploading where the dirty
// rect is ignored anyway.
let intersection = intersect_for_tile(rect, clipped_tile_size, tile_size, tile);
debug_assert!(intersection.is_some() ||
self.texture_cache.needs_upload(&entry.texture_cache_handle));
intersection
} else {
None
};

// The tiled image could be stored on the CPU as one large image or be
// already broken up into tiles. This affects the way we compute the stride
// and offset.
@@ -1548,13 +1555,15 @@ impl ResourceCache {
}

descriptor.size = clipped_tile_size;
} else {
local_dirty_rect = entry.dirty_rect.take();
}

// If we are uploading the dirty region of a blob image we might have several
// rects to upload so we use each of these rasterized rects rather than the
// overall dirty rect of the image.
if blob_rasterized_rect.is_some() {
dirty_rect = blob_rasterized_rect;
local_dirty_rect = blob_rasterized_rect;
}

let filter = match request.rendering {
@@ -1597,7 +1606,7 @@ impl ResourceCache {
filter,
Some(image_data),
[0.0; 3],
dirty_rect,
local_dirty_rect,
gpu_cache,
None,
UvRectKind::Rect,
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.