mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1473284 - Update webrender to commit 0e9563688e575cd662570f54bc9d6f849040dbf8. r=Gankro
MozReview-Commit-ID: 8iH1bGPKpsd --HG-- rename : gfx/webrender/src/query.rs => gfx/webrender/src/device/query_gl.rs extra : rebase_source : ee7fcddee44b360cfee098656df7f144cacf270e
This commit is contained in:
parent
b44f14fe70
commit
624ee847f6
@ -85,6 +85,8 @@ PictureTask fetch_picture_task(int address) {
|
||||
return task;
|
||||
}
|
||||
|
||||
#define CLIP_TASK_EMPTY 0x7FFF
|
||||
|
||||
struct ClipArea {
|
||||
RenderTaskCommonData common_data;
|
||||
vec2 screen_origin;
|
||||
@ -94,11 +96,10 @@ struct ClipArea {
|
||||
ClipArea fetch_clip_area(int index) {
|
||||
ClipArea area;
|
||||
|
||||
if (index == 0x7FFF) { //special sentinel task index
|
||||
area.common_data = RenderTaskCommonData(
|
||||
RectWithSize(vec2(0.0), vec2(0.0)),
|
||||
0.0
|
||||
);
|
||||
if (index >= CLIP_TASK_EMPTY) {
|
||||
RectWithSize rect = RectWithSize(vec2(0.0), vec2(0.0));
|
||||
|
||||
area.common_data = RenderTaskCommonData(rect, 0.0);
|
||||
area.screen_origin = vec2(0.0);
|
||||
area.local_space = false;
|
||||
} else {
|
||||
|
@ -3,5 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
mod gl;
|
||||
pub mod query_gl;
|
||||
|
||||
pub use self::gl::*;
|
||||
pub use self::query_gl as query;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, ClipAndScrollInfo};
|
||||
use api::{ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect, DeviceIntSize};
|
||||
use api::{DevicePixelScale, DeviceUintRect, DisplayItemRef, Epoch, ExtendMode, ExternalScrollId};
|
||||
use api::{DevicePixelScale, DeviceUintRect, DisplayItemRef, ExtendMode, ExternalScrollId};
|
||||
use api::{FilterOp, FontInstanceKey, GlyphInstance, GlyphOptions, GlyphRasterSpace, GradientStop};
|
||||
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayoutPoint};
|
||||
use api::{LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
|
||||
@ -150,9 +150,6 @@ pub struct DisplayListFlattener<'a> {
|
||||
/// The map of all font instances.
|
||||
font_instances: FontInstanceMap,
|
||||
|
||||
/// Used to track the latest flattened epoch for each pipeline.
|
||||
pipeline_epochs: Vec<(PipelineId, Epoch)>,
|
||||
|
||||
/// A set of pipelines that the caller has requested be made available as
|
||||
/// output textures.
|
||||
output_pipelines: &'a FastHashSet<PipelineId>,
|
||||
@ -207,8 +204,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
let root_pipeline_id = scene.root_pipeline_id.unwrap();
|
||||
let root_pipeline = scene.pipelines.get(&root_pipeline_id).unwrap();
|
||||
|
||||
let root_epoch = scene.pipeline_epochs[&root_pipeline_id];
|
||||
|
||||
let background_color = root_pipeline
|
||||
.background_color
|
||||
.and_then(|color| if color.a > 0.0 { Some(color) } else { None });
|
||||
@ -218,7 +213,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
clip_scroll_tree,
|
||||
font_instances,
|
||||
config: *frame_builder_config,
|
||||
pipeline_epochs: Vec::new(),
|
||||
output_pipelines,
|
||||
id_to_index_mapper: ClipIdToIndexMapper::default(),
|
||||
hit_testing_runs: recycle_vec(old_builder.hit_testing_runs),
|
||||
@ -243,8 +237,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
debug_assert!(flattener.picture_stack.is_empty());
|
||||
|
||||
new_scene.root_pipeline_id = Some(root_pipeline_id);
|
||||
new_scene.pipeline_epochs.insert(root_pipeline_id, root_epoch);
|
||||
new_scene.pipeline_epochs.extend(flattener.pipeline_epochs.drain(..));
|
||||
new_scene.pipeline_epochs = scene.pipeline_epochs.clone();
|
||||
new_scene.pipelines = scene.pipelines.clone();
|
||||
|
||||
FrameBuilder::with_display_list_flattener(
|
||||
@ -529,9 +522,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
),
|
||||
);
|
||||
|
||||
let epoch = self.scene.pipeline_epochs[&iframe_pipeline_id];
|
||||
self.pipeline_epochs.push((iframe_pipeline_id, epoch));
|
||||
|
||||
let bounds = item.rect();
|
||||
let origin = *reference_frame_relative_offset + bounds.origin.to_vector();
|
||||
self.push_reference_frame(
|
||||
@ -1892,7 +1882,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
rendering: image_rendering,
|
||||
tile: None,
|
||||
},
|
||||
current_epoch: Epoch::invalid(),
|
||||
alpha_type,
|
||||
stretch_size,
|
||||
tile_spacing,
|
||||
|
@ -89,7 +89,6 @@ mod picture;
|
||||
mod prim_store;
|
||||
mod print_tree;
|
||||
mod profiler;
|
||||
mod query;
|
||||
mod record;
|
||||
mod render_backend;
|
||||
mod render_task;
|
||||
|
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{AlphaType, BorderRadius, BoxShadowClipMode, BuiltDisplayList, ClipMode, ColorF};
|
||||
use api::{DeviceIntRect, DeviceIntSize, DevicePixelScale, Epoch, ExtendMode};
|
||||
use api::{DeviceIntRect, DeviceIntSize, DevicePixelScale, ExtendMode};
|
||||
use api::{FilterOp, GlyphInstance, GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag, TileOffset};
|
||||
use api::{GlyphRasterSpace, LayoutPoint, LayoutRect, LayoutSize, LayoutToWorldTransform, LayoutVector2D};
|
||||
use api::{PipelineId, PremultipliedColorF, PropertyBinding, Shadow, YuvColorSpace, YuvFormat, DeviceIntSideOffsets};
|
||||
@ -284,7 +284,6 @@ pub enum BrushKind {
|
||||
},
|
||||
Image {
|
||||
request: ImageRequest,
|
||||
current_epoch: Epoch,
|
||||
alpha_type: AlphaType,
|
||||
stretch_size: LayoutSize,
|
||||
tile_spacing: LayoutSize,
|
||||
@ -1577,7 +1576,6 @@ impl PrimitiveStore {
|
||||
sub_rect,
|
||||
stretch_size,
|
||||
ref mut tile_spacing,
|
||||
ref mut current_epoch,
|
||||
ref mut source,
|
||||
ref mut opacity_binding,
|
||||
ref mut visible_tiles,
|
||||
@ -1590,7 +1588,6 @@ impl PrimitiveStore {
|
||||
|
||||
// Set if we need to request the source image from the cache this frame.
|
||||
if let Some(image_properties) = image_properties {
|
||||
*current_epoch = image_properties.epoch;
|
||||
is_tiled = image_properties.tiling.is_some();
|
||||
|
||||
// If the opacity changed, invalidate the GPU cache so that
|
||||
@ -2276,7 +2273,8 @@ impl PrimitiveStore {
|
||||
prim_screen_rect.intersection(&prim_run_context.clip_chain.combined_outer_screen_rect);
|
||||
let clip_chain = prim_run_context.clip_chain.nodes.clone();
|
||||
if cfg!(debug_assertions) && Some(prim_index) == self.chase_id {
|
||||
println!("\tbase combined outer rect {:?}", combined_outer_rect);
|
||||
println!("\tbase screen {:?}, combined clip chain {:?}",
|
||||
prim_screen_rect, prim_run_context.clip_chain.combined_outer_screen_rect);
|
||||
}
|
||||
|
||||
let prim_coordinate_system_id = prim_run_context.scroll_node.coordinate_system_id;
|
||||
@ -2695,6 +2693,20 @@ impl PrimitiveStore {
|
||||
inv_parent.pre_mul(&scroll_node.world_content_transform)
|
||||
});
|
||||
|
||||
if run.is_chasing(self.chase_id) {
|
||||
println!("\teffective clip chain from {:?} {}",
|
||||
scroll_node.coordinate_system_id,
|
||||
if pic_context.apply_local_clip_rect { "(applied)" } else { "" },
|
||||
);
|
||||
let iter = ClipChainNodeIter { current: clip_chain.nodes.clone() };
|
||||
for node in iter {
|
||||
println!("\t\t{:?} {:?}",
|
||||
node.work_item.coordinate_system_id,
|
||||
node.local_clip_rect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let clip_chain_rect = if pic_context.apply_local_clip_rect {
|
||||
get_local_clip_rect_for_nodes(scroll_node, clip_chain)
|
||||
} else {
|
||||
|
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::ColorF;
|
||||
use query::{GpuTimer, NamedTag};
|
||||
use device::query::{GpuTimer, NamedTag};
|
||||
use std::collections::vec_deque::VecDeque;
|
||||
use std::f32;
|
||||
use time::precise_time_ns;
|
||||
@ -13,7 +13,7 @@ cfg_if! {
|
||||
use api::ColorU;
|
||||
use debug_render::DebugRenderer;
|
||||
use euclid::{Point2D, Rect, Size2D, vec2};
|
||||
use query::GpuSampler;
|
||||
use device::query::GpuSampler;
|
||||
use internal_types::FastHashMap;
|
||||
use renderer::MAX_VERTEX_TEXTURE_WIDTH;
|
||||
use std::mem;
|
||||
|
@ -39,7 +39,7 @@ use internal_types::{RenderTargetInfo, SavedTargetIndex};
|
||||
use prim_store::DeferredResolve;
|
||||
use profiler::{BackendProfileCounters, FrameProfileCounters,
|
||||
GpuProfileTag, RendererProfileCounters, RendererProfileTimers};
|
||||
use query::GpuProfiler;
|
||||
use device::query::GpuProfiler;
|
||||
use rayon::{ThreadPool, ThreadPoolBuilder};
|
||||
use record::ApiRecordingReceiver;
|
||||
use render_backend::RenderBackend;
|
||||
@ -83,7 +83,7 @@ cfg_if! {
|
||||
use api::ColorU;
|
||||
use debug_render::DebugRenderer;
|
||||
use profiler::{Profiler, ChangeIndicator};
|
||||
use query::GpuTimer;
|
||||
use device::query::GpuTimer;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
use api::{AddFont, BlobImageResources, ResourceUpdate};
|
||||
use api::{BlobImageDescriptor, BlobImageError, BlobImageRenderer, BlobImageRequest};
|
||||
use api::{ClearCache, ColorF, DevicePoint, DeviceUintPoint, DeviceUintRect, DeviceUintSize};
|
||||
use api::{Epoch, FontInstanceKey, FontKey, FontTemplate, GlyphIndex};
|
||||
use api::{FontInstanceKey, FontKey, FontTemplate, GlyphIndex};
|
||||
use api::{ExternalImageData, ExternalImageType};
|
||||
use api::{FontInstanceOptions, FontInstancePlatformOptions, FontVariation};
|
||||
use api::{GlyphDimensions, IdNamespace};
|
||||
@ -32,7 +32,8 @@ use render_backend::FrameId;
|
||||
use render_task::{RenderTaskCache, RenderTaskCacheKey, RenderTaskId};
|
||||
use render_task::{RenderTaskCacheEntry, RenderTaskCacheEntryHandle, RenderTaskTree};
|
||||
use std::collections::hash_map::Entry::{self, Occupied, Vacant};
|
||||
use std::cmp;
|
||||
use std::collections::hash_map::ValuesMut;
|
||||
use std::{cmp, mem};
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
#[cfg(any(feature = "capture", feature = "replay"))]
|
||||
@ -85,7 +86,6 @@ pub struct ImageProperties {
|
||||
pub descriptor: ImageDescriptor,
|
||||
pub external_image: Option<ExternalImageData>,
|
||||
pub tiling: Option<TileSize>,
|
||||
pub epoch: Epoch,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
@ -99,9 +99,7 @@ enum State {
|
||||
struct ImageResource {
|
||||
data: ImageData,
|
||||
descriptor: ImageDescriptor,
|
||||
epoch: Epoch,
|
||||
tiling: Option<TileSize>,
|
||||
dirty_rect: Option<DeviceUintRect>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -137,7 +135,7 @@ impl ImageTemplates {
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
struct CachedImageInfo {
|
||||
texture_cache_handle: TextureCacheHandle,
|
||||
epoch: Epoch,
|
||||
dirty_rect: Option<DeviceUintRect>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
@ -168,6 +166,24 @@ pub fn intersect_for_tile(
|
||||
})
|
||||
}
|
||||
|
||||
fn merge_dirty_rect(
|
||||
prev_dirty_rect: &Option<DeviceUintRect>,
|
||||
dirty_rect: &Option<DeviceUintRect>,
|
||||
descriptor: &ImageDescriptor,
|
||||
) -> Option<DeviceUintRect> {
|
||||
// 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.
|
||||
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>
|
||||
where
|
||||
@ -190,15 +206,27 @@ where
|
||||
self.resources.insert(key, value);
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: &K) {
|
||||
self.resources.remove(key);
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, key: &K) -> &mut V {
|
||||
self.resources.get_mut(key)
|
||||
.expect("Didn't find a cached resource with that ID!")
|
||||
}
|
||||
|
||||
pub fn try_get_mut(&mut self, key: &K) -> Option<&mut V> {
|
||||
self.resources.get_mut(key)
|
||||
}
|
||||
|
||||
pub fn entry(&mut self, key: K) -> Entry<K, V> {
|
||||
self.resources.entry(key)
|
||||
}
|
||||
|
||||
pub fn values_mut(&mut self) -> ValuesMut<K, V> {
|
||||
self.resources.values_mut()
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.resources.clear();
|
||||
}
|
||||
@ -225,6 +253,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
struct CachedImageKey {
|
||||
pub rendering: ImageRendering,
|
||||
pub tile: Option<TileOffset>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
@ -243,6 +278,10 @@ impl ImageRequest {
|
||||
tile: Some(offset),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_untiled_auto(&self) -> bool {
|
||||
self.tile.is_none() && self.rendering == ImageRendering::Auto
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<BlobImageRequest> for ImageRequest {
|
||||
@ -254,6 +293,15 @@ impl Into<BlobImageRequest> for ImageRequest {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<CachedImageKey> for ImageRequest {
|
||||
fn into(self) -> CachedImageKey {
|
||||
CachedImageKey {
|
||||
rendering: self.rendering,
|
||||
tile: self.tile,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Clone, Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -261,7 +309,15 @@ pub enum ImageCacheError {
|
||||
OverLimitSize,
|
||||
}
|
||||
|
||||
type ImageCache = ResourceClassCache<ImageRequest, Result<CachedImageInfo, ImageCacheError>, ()>;
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
enum ImageResult {
|
||||
UntiledAuto(CachedImageInfo),
|
||||
Multi(ResourceClassCache<CachedImageKey, CachedImageInfo, ()>),
|
||||
Err(ImageCacheError),
|
||||
}
|
||||
|
||||
type ImageCache = ResourceClassCache<ImageKey, ImageResult, ()>;
|
||||
pub type FontInstanceMap = Arc<RwLock<FastHashMap<FontInstanceKey, FontInstance>>>;
|
||||
|
||||
#[derive(Default)]
|
||||
@ -510,14 +566,11 @@ impl ResourceCache {
|
||||
tiling,
|
||||
);
|
||||
}
|
||||
let dirty_rect = Some(descriptor.full_rect());
|
||||
|
||||
let resource = ImageResource {
|
||||
descriptor,
|
||||
data,
|
||||
epoch: Epoch(0),
|
||||
tiling,
|
||||
dirty_rect,
|
||||
};
|
||||
|
||||
self.resources.image_templates.insert(image_key, resource);
|
||||
@ -548,24 +601,31 @@ impl ResourceCache {
|
||||
.update(image_key, Arc::clone(blob), dirty_rect);
|
||||
}
|
||||
|
||||
// Each cache entry stores its own copy of the image's dirty rect. This allows them to be
|
||||
// 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);
|
||||
}
|
||||
Some(&mut ImageResult::Multi(ref mut entries)) => {
|
||||
for entry in entries.values_mut() {
|
||||
entry.dirty_rect = merge_dirty_rect(&entry.dirty_rect, &dirty_rect, &descriptor);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
*image = ImageResource {
|
||||
descriptor,
|
||||
data,
|
||||
epoch: Epoch(image.epoch.0 + 1),
|
||||
tiling,
|
||||
dirty_rect: match (dirty_rect, image.dirty_rect) {
|
||||
(Some(rect), Some(prev_rect)) => Some(rect.union(&prev_rect)),
|
||||
(Some(rect), None) => Some(rect),
|
||||
(None, _) => None,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn delete_image_template(&mut self, image_key: ImageKey) {
|
||||
let value = self.resources.image_templates.remove(image_key);
|
||||
|
||||
self.cached_images
|
||||
.clear_keys(|request| request.key == image_key);
|
||||
self.cached_images.remove(&image_key);
|
||||
|
||||
match value {
|
||||
Some(image) => if image.data.is_blob() {
|
||||
@ -606,41 +666,76 @@ impl ResourceCache {
|
||||
// The image or tiling size is too big for hardware texture size.
|
||||
warn!("Dropping image, image:(w:{},h:{}, tile:{}) is too big for hardware!",
|
||||
template.descriptor.size.width, template.descriptor.size.height, template.tiling.unwrap_or(0));
|
||||
self.cached_images.insert(request, Err(ImageCacheError::OverLimitSize));
|
||||
self.cached_images.insert(request.key, ImageResult::Err(ImageCacheError::OverLimitSize));
|
||||
return;
|
||||
}
|
||||
|
||||
// If this image exists in the texture cache, *and* the epoch
|
||||
// in the cache matches that of the template, then it is
|
||||
// valid to use as-is.
|
||||
let (entry, needs_update) = match self.cached_images.entry(request) {
|
||||
Occupied(entry) => {
|
||||
let info = entry.into_mut();
|
||||
let needs_update = info.as_mut().unwrap().epoch != template.epoch;
|
||||
info.as_mut().unwrap().epoch = template.epoch;
|
||||
(info, needs_update)
|
||||
}
|
||||
Vacant(entry) => (
|
||||
entry.insert(Ok(
|
||||
CachedImageInfo {
|
||||
epoch: template.epoch,
|
||||
texture_cache_handle: TextureCacheHandle::new(),
|
||||
let storage = match self.cached_images.entry(request.key) {
|
||||
Occupied(e) => {
|
||||
// We might have an existing untiled entry, and need to insert
|
||||
// a second entry. In such cases we need to move the old entry
|
||||
// out first, replacing it with a dummy entry, and then creating
|
||||
// the tiled/multi-entry variant.
|
||||
let entry = e.into_mut();
|
||||
if !request.is_untiled_auto() {
|
||||
let untiled_entry = match entry {
|
||||
&mut ImageResult::UntiledAuto(ref mut entry) => {
|
||||
Some(mem::replace(entry, CachedImageInfo {
|
||||
texture_cache_handle: TextureCacheHandle::new(),
|
||||
dirty_rect: None,
|
||||
}))
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
|
||||
if let Some(untiled_entry) = untiled_entry {
|
||||
let mut entries = ResourceClassCache::new();
|
||||
let untiled_key = CachedImageKey {
|
||||
rendering: ImageRendering::Auto,
|
||||
tile: None,
|
||||
};
|
||||
entries.insert(untiled_key, untiled_entry);
|
||||
*entry = ImageResult::Multi(entries);
|
||||
}
|
||||
)),
|
||||
true,
|
||||
),
|
||||
}
|
||||
entry
|
||||
}
|
||||
Vacant(entry) => {
|
||||
entry.insert(if request.is_untiled_auto() {
|
||||
ImageResult::UntiledAuto(CachedImageInfo {
|
||||
texture_cache_handle: TextureCacheHandle::new(),
|
||||
dirty_rect: Some(template.descriptor.full_rect()),
|
||||
})
|
||||
} else {
|
||||
ImageResult::Multi(ResourceClassCache::new())
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
// If this image exists in the texture cache, *and* the dirty rect
|
||||
// in the cache is empty, then it is valid to use as-is.
|
||||
let entry = match *storage {
|
||||
ImageResult::UntiledAuto(ref mut entry) => entry,
|
||||
ImageResult::Multi(ref mut entries) => {
|
||||
entries.entry(request.into())
|
||||
.or_insert(CachedImageInfo {
|
||||
texture_cache_handle: TextureCacheHandle::new(),
|
||||
dirty_rect: Some(template.descriptor.full_rect()),
|
||||
})
|
||||
},
|
||||
ImageResult::Err(_) => panic!("Errors should already have been handled"),
|
||||
};
|
||||
|
||||
let needs_upload = self.texture_cache
|
||||
.request(&entry.as_ref().unwrap().texture_cache_handle, gpu_cache);
|
||||
.request(&entry.texture_cache_handle, gpu_cache);
|
||||
|
||||
let dirty_rect = if needs_upload {
|
||||
// the texture cache entry has been evicted, treat it as all dirty
|
||||
Some(template.descriptor.full_rect())
|
||||
} else if needs_update {
|
||||
template.dirty_rect
|
||||
} else {
|
||||
None
|
||||
} else if entry.dirty_rect.is_none() {
|
||||
return
|
||||
} else {
|
||||
entry.dirty_rect
|
||||
};
|
||||
|
||||
if !self.pending_image_requests.insert(request) {
|
||||
@ -666,6 +761,7 @@ impl ResourceCache {
|
||||
if let Some(dirty) = dirty_rect {
|
||||
if intersect_for_tile(dirty, actual_size, tile_size, tile_offset).is_none() {
|
||||
// don't bother requesting unchanged tiles
|
||||
entry.dirty_rect = None;
|
||||
self.pending_image_requests.remove(&request);
|
||||
return
|
||||
}
|
||||
@ -849,11 +945,15 @@ impl ResourceCache {
|
||||
|
||||
// TODO(Jerry): add a debug option to visualize the corresponding area for
|
||||
// the Err() case of CacheItem.
|
||||
match *self.cached_images.get(&request) {
|
||||
Ok(ref image_info) => {
|
||||
match *self.cached_images.get(&request.key) {
|
||||
ImageResult::UntiledAuto(ref image_info) => {
|
||||
Ok(self.texture_cache.get(&image_info.texture_cache_handle))
|
||||
}
|
||||
Err(_) => {
|
||||
ImageResult::Multi(ref entries) => {
|
||||
let image_info = entries.get(&request.into());
|
||||
Ok(self.texture_cache.get(&image_info.texture_cache_handle))
|
||||
}
|
||||
ImageResult::Err(_) => {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
@ -888,7 +988,6 @@ impl ResourceCache {
|
||||
descriptor: image_template.descriptor,
|
||||
external_image,
|
||||
tiling: image_template.tiling,
|
||||
epoch: image_template.epoch,
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -934,8 +1033,6 @@ impl ResourceCache {
|
||||
}
|
||||
|
||||
fn update_texture_cache(&mut self, gpu_cache: &mut GpuCache) {
|
||||
let mut keys_to_clear_dirty_rect = FastHashSet::default();
|
||||
|
||||
for request in self.pending_image_requests.drain() {
|
||||
let image_template = self.resources.image_templates.get_mut(request.key).unwrap();
|
||||
debug_assert!(image_template.data.uses_texture_cache());
|
||||
@ -974,7 +1071,11 @@ impl ResourceCache {
|
||||
}
|
||||
};
|
||||
|
||||
let entry = self.cached_images.get_mut(&request).as_mut().unwrap();
|
||||
let entry = match *self.cached_images.get_mut(&request.key) {
|
||||
ImageResult::UntiledAuto(ref mut entry) => entry,
|
||||
ImageResult::Multi(ref mut entries) => entries.get_mut(&request.into()),
|
||||
ImageResult::Err(_) => panic!("Update requested for invalid entry")
|
||||
};
|
||||
let mut descriptor = image_template.descriptor.clone();
|
||||
let local_dirty_rect;
|
||||
|
||||
@ -982,12 +1083,10 @@ impl ResourceCache {
|
||||
let tile_size = image_template.tiling.unwrap();
|
||||
let clipped_tile_size = compute_tile_size(&descriptor, tile_size, tile);
|
||||
|
||||
local_dirty_rect = if let Some(ref rect) = image_template.dirty_rect {
|
||||
keys_to_clear_dirty_rect.insert(request.key.clone());
|
||||
|
||||
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);
|
||||
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
|
||||
@ -1010,7 +1109,7 @@ impl ResourceCache {
|
||||
|
||||
descriptor.size = clipped_tile_size;
|
||||
} else {
|
||||
local_dirty_rect = image_template.dirty_rect.take();
|
||||
local_dirty_rect = entry.dirty_rect.take();
|
||||
}
|
||||
|
||||
let filter = match request.rendering {
|
||||
@ -1052,11 +1151,6 @@ impl ResourceCache {
|
||||
UvRectKind::Rect,
|
||||
);
|
||||
}
|
||||
|
||||
for key in keys_to_clear_dirty_rect.drain() {
|
||||
let image_template = self.resources.image_templates.get_mut(key).unwrap();
|
||||
image_template.dirty_rect.take();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end_frame(&mut self) {
|
||||
@ -1088,7 +1182,7 @@ impl ResourceCache {
|
||||
.images
|
||||
.retain(|key, _| key.0 != namespace);
|
||||
self.cached_images
|
||||
.clear_keys(|request| request.key.0 == namespace);
|
||||
.clear_keys(|key| key.0 == namespace);
|
||||
|
||||
self.resources.font_instances
|
||||
.write()
|
||||
@ -1151,7 +1245,6 @@ enum PlainFontTemplate {
|
||||
struct PlainImageTemplate {
|
||||
data: String,
|
||||
descriptor: ImageDescriptor,
|
||||
epoch: Epoch,
|
||||
tiling: Option<TileSize>,
|
||||
}
|
||||
|
||||
@ -1350,7 +1443,6 @@ impl ResourceCache {
|
||||
},
|
||||
descriptor: template.descriptor.clone(),
|
||||
tiling: template.tiling,
|
||||
epoch: template.epoch,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
@ -1475,8 +1567,6 @@ impl ResourceCache {
|
||||
data,
|
||||
descriptor: template.descriptor,
|
||||
tiling: template.tiling,
|
||||
epoch: template.epoch,
|
||||
dirty_rect: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
34a498f7e46c385a189299e7369e204e1cb2060c
|
||||
0e9563688e575cd662570f54bc9d6f849040dbf8
|
||||
|
@ -55,7 +55,7 @@ fn render_blob(
|
||||
};
|
||||
|
||||
let mut dirty_rect = dirty_rect.unwrap_or(DeviceUintRect::new(
|
||||
DeviceUintPoint::origin(),
|
||||
descriptor.offset.to_u32(),
|
||||
descriptor.size,
|
||||
));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user