Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Mullvad Browser
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
The Tor Project
Applications
Mullvad Browser
Commits
0640ea80
Commit
0640ea80
authored
6 years ago
by
Jeff Muizelaar
Browse files
Options
Downloads
Patches
Plain Diff
Bug 1493473. Update webrender to 4e7d0ed1b08f5402a6971230864a7e497b2453ec
parent
0ab721da
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
gfx/webrender/src/resource_cache.rs
+129
-176
129 additions, 176 deletions
gfx/webrender/src/resource_cache.rs
gfx/webrender_bindings/revision.txt
+1
-1
1 addition, 1 deletion
gfx/webrender_bindings/revision.txt
with
130 additions
and
177 deletions
gfx/webrender/src/resource_cache.rs
+
129
−
176
View file @
0640ea80
...
...
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use
api
::{
AddFont
,
BlobImageResources
,
AsyncBlobImageRasterizer
,
ResourceUpdate
};
use
api
::{
BlobImageDescriptor
,
BlobImageHandler
,
BlobImageRequest
,
RasterizedBlobImage
};
use
api
::{
BlobImageDescriptor
,
BlobImageHandler
,
BlobImageRequest
};
use
api
::{
ClearCache
,
ColorF
,
DevicePoint
,
DeviceUintPoint
,
DeviceUintRect
,
DeviceUintSize
};
use
api
::{
FontInstanceKey
,
FontKey
,
FontTemplate
,
GlyphIndex
};
use
api
::{
ExternalImageData
,
ExternalImageType
,
BlobImageResult
,
BlobImageParams
};
...
...
@@ -33,7 +33,6 @@ use profiler::{ResourceProfileCounters, TextureCacheProfileCounters};
use
render_backend
::
FrameId
;
use
render_task
::{
RenderTaskCache
,
RenderTaskCacheKey
,
RenderTaskId
};
use
render_task
::{
RenderTaskCacheEntry
,
RenderTaskCacheEntryHandle
,
RenderTaskTree
};
use
smallvec
::
SmallVec
;
use
std
::
collections
::
hash_map
::
Entry
::{
self
,
Occupied
,
Vacant
};
use
std
::
collections
::
hash_map
::
IterMut
;
use
std
::{
cmp
,
mem
};
...
...
@@ -101,9 +100,8 @@ enum State {
}
/// Post scene building state.
enum
RasterizedBlob
{
Tiled
(
FastHashMap
<
TileOffset
,
RasterizedBlobImage
>
),
NonTiled
(
Vec
<
RasterizedBlobImage
>
),
struct
RasterizedBlobImage
{
data
:
FastHashMap
<
Option
<
TileOffset
>
,
BlobImageResult
>
,
}
/// Pre scene building state.
...
...
@@ -407,7 +405,7 @@ pub struct ResourceCache {
pending_image_requests
:
FastHashSet
<
ImageRequest
>
,
blob_image_handler
:
Option
<
Box
<
BlobImageHandler
>>
,
rasterized_blob_images
:
FastHashMap
<
ImageKey
,
RasterizedBlob
>
,
rasterized_blob_images
:
FastHashMap
<
ImageKey
,
RasterizedBlob
Image
>
,
blob_image_templates
:
FastHashMap
<
ImageKey
,
BlobImageTemplate
>
,
// If while building a frame we encounter blobs that we didn't already
...
...
@@ -606,40 +604,10 @@ impl ResourceCache {
pub
fn
add_rasterized_blob_images
(
&
mut
self
,
images
:
Vec
<
(
BlobImageRequest
,
BlobImageResult
)
>
)
{
for
(
request
,
result
)
in
images
{
let
data
=
match
result
{
Ok
(
data
)
=>
data
,
Err
(
..
)
=>
{
warn!
(
"Failed to rasterize a blob image"
);
continue
;
}
};
// First make sure we have an entry for this key (using a placeholder
// if need be).
let
image
=
self
.rasterized_blob_images
.entry
(
request
.key
)
.or_insert_with
(
||
{
RasterizedBlob
::
Tiled
(
FastHashMap
::
default
()
)
}
||
{
RasterizedBlob
Image
{
data
:
FastHashMap
::
default
()
}
}
);
if
let
Some
(
tile
)
=
request
.tile
{
if
let
RasterizedBlob
::
NonTiled
(
..
)
=
*
image
{
*
image
=
RasterizedBlob
::
Tiled
(
FastHashMap
::
default
());
}
if
let
RasterizedBlob
::
Tiled
(
ref
mut
tiles
)
=
*
image
{
tiles
.insert
(
tile
,
data
);
}
}
else
{
if
let
RasterizedBlob
::
NonTiled
(
ref
mut
queue
)
=
*
image
{
// If our new rasterized rect overwrites items in the queue, discard them.
queue
.retain
(|
img
|
{
!
data
.rasterized_rect
.contains_rect
(
&
img
.rasterized_rect
)
});
queue
.push
(
data
);
}
else
{
*
image
=
RasterizedBlob
::
NonTiled
(
vec!
[
data
]);
}
}
image
.data
.insert
(
request
.tile
,
result
);
}
}
...
...
@@ -977,10 +945,9 @@ impl ResourceCache {
if
template
.data
.is_blob
()
{
let
request
:
BlobImageRequest
=
request
.into
();
let
missing
=
match
(
self
.rasterized_blob_images
.get
(
&
request
.key
),
request
.tile
)
{
(
Some
(
RasterizedBlob
::
Tiled
(
tiles
)),
Some
(
tile
))
=>
!
tiles
.contains_key
(
&
tile
),
(
Some
(
RasterizedBlob
::
NonTiled
(
..
)),
None
)
=>
false
,
_
=>
true
,
let
missing
=
match
self
.rasterized_blob_images
.get
(
&
request
.key
)
{
Some
(
img
)
=>
!
img
.data
.contains_key
(
&
request
.tile
),
None
=>
true
,
};
// For some reason the blob image is missing. We'll fall back to
...
...
@@ -1115,32 +1082,13 @@ impl ResourceCache {
);
});
}
else
{
let
mut
needs_upload
=
match
self
.cached_images
.try_get
(
&
key
)
{
let
needs_upload
=
match
self
.cached_images
.try_get
(
&
key
)
{
Some
(
&
ImageResult
::
UntiledAuto
(
ref
entry
))
=>
{
self
.texture_cache
.needs_upload
(
&
entry
.texture_cache_handle
)
}
_
=>
true
,
};
// If the queue of ratserized updates is growing it probably means that
// the texture is not getting uploaded because the display item is off-screen.
// In that case we are better off
// - Either not kicking rasterization for that image (avoid wasted cpu work
// but will jank next time the item is visible because of lazy rasterization.
// - Clobber the update queue by pushing an update with a larger dirty rect
// to prevent it from accumulating.
//
// We do the latter here but it's not ideal and might want to revisit and do
// the former instead.
match
self
.rasterized_blob_images
.get
(
&
key
)
{
Some
(
RasterizedBlob
::
NonTiled
(
ref
queue
))
=>
{
if
queue
.len
()
>
2
{
needs_upload
=
true
;
}
}
_
=>
{},
};
let
dirty_rect
=
if
needs_upload
{
// The texture cache entry has been evicted, treat it as all dirty.
None
...
...
@@ -1186,19 +1134,28 @@ impl ResourceCache {
Some
(
size
)
=>
size
,
None
=>
{
return
;
}
};
let
tiles
=
match
self
.rasterized_blob_images
.get_mut
(
&
key
)
{
Some
(
RasterizedBlob
::
Tiled
(
tiles
))
=>
tiles
,
_
=>
{
return
;
}
let
image
=
match
self
.rasterized_blob_images
.get_mut
(
&
key
)
{
Some
(
image
)
=>
image
,
None
=>
{
//println!("Missing rasterized blob (key={:?})!", key);
return
;
}
};
let
tile_range
=
compute_tile_range
(
&
area
,
&
template
.descriptor.size
,
tile_size
,
);
tiles
.retain
(|
tile
,
_
|
{
tile_range
.contains
(
tile
)
});
image
.data
.retain
(|
tile
,
_
|
{
match
*
tile
{
Some
(
offset
)
=>
tile_range
.contains
(
&
offset
),
// This would be a bug. If we get here the blob should be tiled.
None
=>
{
error!
(
"Blob image template and image data tiling don't match."
);
false
}
}
});
}
pub
fn
request_glyphs
(
...
...
@@ -1463,34 +1420,28 @@ impl ResourceCache {
let
image_template
=
self
.resources.image_templates
.get_mut
(
request
.key
)
.unwrap
();
debug_assert!
(
image_template
.data
.uses_texture_cache
());
let
mut
updates
:
SmallVec
<
[(
ImageData
,
Option
<
DeviceUintRect
>
);
1
]
>
=
SmallVec
::
new
();
match
image_template
.data
{
let
mut
blob_rasterized_rect
=
None
;
let
image_data
=
match
image_template
.data
{
ImageData
::
Raw
(
..
)
|
ImageData
::
External
(
..
)
=>
{
// Safe to clone here since the Raw image data is an
// Arc, and the external image data is small.
updates
.push
((
image_template
.data
.clone
()
,
None
));
image_template
.data
.clone
()
}
ImageData
::
Blob
(
..
)
=>
{
let
blob_image
=
self
.rasterized_blob_images
.get
(
&
request
.key
)
.unwrap
();
match
blob_image
.data
.get
(
&
request
.tile
)
{
Some
(
result
)
=>
{
let
result
=
result
.as_ref
()
.expect
(
"Failed to render a blob image"
);
let
blob_image
=
self
.rasterized_blob_images
.get_mut
(
&
request
.key
)
.unwrap
();
match
(
blob_image
,
request
.tile
)
{
(
RasterizedBlob
::
Tiled
(
ref
tiles
),
Some
(
tile
))
=>
{
let
img
=
&
tiles
[
&
tile
];
updates
.push
((
ImageData
::
Raw
(
Arc
::
clone
(
&
img
.data
)),
Some
(
img
.rasterized_rect
)
));
}
(
RasterizedBlob
::
NonTiled
(
ref
mut
queue
),
None
)
=>
{
for
img
in
queue
.drain
(
..
)
{
updates
.push
((
ImageData
::
Raw
(
img
.data
),
Some
(
img
.rasterized_rect
)
));
}
// TODO: we may want to not panic and show a placeholder instead.
blob_rasterized_rect
=
Some
(
result
.rasterized_rect
);
ImageData
::
Raw
(
Arc
::
clone
(
&
result
.data
))
}
_
=>
{
None
=>
{
debug_assert!
(
false
,
"invalid blob image request during frame building"
);
continue
;
}
...
...
@@ -1498,102 +1449,100 @@ impl ResourceCache {
}
};
for
(
image_data
,
blob_rasterized_rect
)
in
updates
{
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
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
);
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"
)
};
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
};
match
(
blob_rasterized_rect
,
entry
.dirty_rect
)
{
(
Some
(
rasterized
),
Some
(
dirty
))
=>
{
debug_assert!
(
request
.tile
.is_some
()
||
rasterized
.contains_rect
(
&
dirty
));
}
_
=>
{}
}
// 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.
let
tiled_on_cpu
=
image_template
.data
.is_blob
();
if
!
tiled_on_cpu
{
let
bpp
=
descriptor
.format
.bytes_per_pixel
();
let
stride
=
descriptor
.compute_stride
();
descriptor
.stride
=
Some
(
stride
);
descriptor
.offset
+=
tile
.y
as
u32
*
tile_size
as
u32
*
stride
+
tile
.x
as
u32
*
tile_size
as
u32
*
bpp
;
}
let
mut
descriptor
=
image_template
.descriptor
.clone
();
let
local_dirty_rect
;
descriptor
.size
=
clipped_tile_size
;
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
{
local_dirty_rect
=
entry
.dirty_rect
.take
();
}
None
}
;
// 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
()
{
local_dirty_rect
=
blob_rasterized_rect
;
// 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.
let
tiled_on_cpu
=
image_template
.data
.is_blob
();
if
!
tiled_on_cpu
{
let
bpp
=
descriptor
.format
.bytes_per_pixel
();
let
stride
=
descriptor
.compute_stride
();
descriptor
.stride
=
Some
(
stride
);
descriptor
.offset
+=
tile
.y
as
u32
*
tile_size
as
u32
*
stride
+
tile
.x
as
u32
*
tile_size
as
u32
*
bpp
;
}
let
filter
=
match
request
.rendering
{
ImageRendering
::
Pixelated
=>
{
TextureFilter
::
Nearest
}
ImageRendering
::
Auto
|
ImageRendering
::
CrispEdges
=>
{
// If the texture uses linear filtering, enable mipmaps and
// trilinear filtering, for better image quality. We only
// support this for now on textures that are not placed
// into the shared cache. This accounts for any image
// that is > 512 in either dimension, so it should cover
// the most important use cases. We may want to support
// mip-maps on shared cache items in the future.
if
descriptor
.allow_mipmaps
&&
descriptor
.size.width
>
512
&&
descriptor
.size.height
>
512
&&
!
self
.texture_cache
.is_allowed_in_shared_cache
(
TextureFilter
::
Linear
,
&
descriptor
,
)
{
TextureFilter
::
Trilinear
}
else
{
TextureFilter
::
Linear
}
descriptor
.size
=
clipped_tile_size
;
}
else
{
local_dirty_rect
=
entry
.dirty_rect
.take
();
}
let
filter
=
match
request
.rendering
{
ImageRendering
::
Pixelated
=>
{
TextureFilter
::
Nearest
}
ImageRendering
::
Auto
|
ImageRendering
::
CrispEdges
=>
{
// If the texture uses linear filtering, enable mipmaps and
// trilinear filtering, for better image quality. We only
// support this for now on textures that are not placed
// into the shared cache. This accounts for any image
// that is > 512 in either dimension, so it should cover
// the most important use cases. We may want to support
// mip-maps on shared cache items in the future.
if
descriptor
.allow_mipmaps
&&
descriptor
.size.width
>
512
&&
descriptor
.size.height
>
512
&&
!
self
.texture_cache
.is_allowed_in_shared_cache
(
TextureFilter
::
Linear
,
&
descriptor
,
)
{
TextureFilter
::
Trilinear
}
else
{
TextureFilter
::
Linear
}
};
}
};
let
eviction
=
if
image_template
.data
.is_blob
()
{
Eviction
::
Manual
}
else
{
Eviction
::
Auto
};
let
eviction
=
if
image_template
.data
.is_blob
()
{
Eviction
::
Manual
}
else
{
Eviction
::
Auto
};
//Note: at this point, the dirty rectangle is local to the descriptor space
self
.texture_cache
.update
(
&
mut
entry
.texture_cache_handle
,
descriptor
,
filter
,
Some
(
image_data
),
[
0.0
;
3
],
local_dirty_rect
,
gpu_cache
,
None
,
UvRectKind
::
Rect
,
eviction
,
);
}
//Note: at this point, the dirty rectangle is local to the descriptor space
self
.texture_cache
.update
(
&
mut
entry
.texture_cache_handle
,
descriptor
,
filter
,
Some
(
image_data
),
[
0.0
;
3
],
local_dirty_rect
,
gpu_cache
,
None
,
UvRectKind
::
Rect
,
eviction
,
);
}
}
...
...
@@ -1671,6 +1620,9 @@ impl ResourceCache {
}
// Mesure rasterized blobs.
// TODO(gw): Temporarily disabled while we roll back a crash. We can re-enable
// these when that crash is fixed.
/*
for (_, image) in self.rasterized_blob_images.iter() {
let mut accumulate = |b: &RasterizedBlobImage| {
report.rasterized_blobs += unsafe { op(b.data.as_ptr() as *const c_void) };
...
...
@@ -1680,6 +1632,7 @@ impl ResourceCache {
RasterizedBlob::NonTiled(vec) => vec.iter().for_each(&mut accumulate),
};
}
*/
report
}
...
...
This diff is collapsed.
Click to expand it.
gfx/webrender_bindings/revision.txt
+
1
−
1
View file @
0640ea80
3f6016fbb6fb93b2f1fc7046bce186555ca836f3
4e7d0ed1b08f5402a6971230864a7e497b2453ec
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment