Backed out changeset 42d3ccf69629 (bug 1583879) for causing reftest failures on sort-startSame-1b.svg CLOSED TREE

This commit is contained in:
arthur.iakab 2019-10-11 18:27:52 +03:00
parent bbdd994f71
commit 604018cb2e
12 changed files with 177 additions and 314 deletions

View File

@ -333,26 +333,25 @@ struct Reader {
layers::BlobFont ReadBlobFont() { return Read<layers::BlobFont>(); }
};
static wr::BlobRenderStatus
Moz2DRenderCallback(const Range<const uint8_t> aBlob,
gfx::SurfaceFormat aFormat,
const mozilla::wr::DeviceIntRect* aVisibleRect,
const mozilla::wr::LayoutIntRect* aRenderRect,
const uint16_t* aTileSize,
const mozilla::wr::TileOffset* aTileOffset,
const mozilla::wr::LayoutIntRect* aDirtyRect,
Range<uint8_t> aOutput) {
static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
gfx::SurfaceFormat aFormat,
const mozilla::wr::DeviceIntRect* aVisibleRect,
const mozilla::wr::LayoutIntRect* aRenderRect,
const uint16_t* aTileSize,
const mozilla::wr::TileOffset* aTileOffset,
const mozilla::wr::LayoutIntRect* aDirtyRect,
Range<uint8_t> aOutput) {
IntSize size(aRenderRect->size.width, aRenderRect->size.height);
AUTO_PROFILER_TRACING("WebRender", "RasterizeSingleBlob", GRAPHICS);
MOZ_RELEASE_ASSERT(size.width > 0 && size.height > 0);
if (size.width <= 0 || size.height <= 0) {
return BlobRenderStatus::Error;
return false;
}
auto stride = size.width * gfx::BytesPerPixel(aFormat);
if (aOutput.length() < static_cast<size_t>(size.height * stride)) {
return BlobRenderStatus::Error;
return false;
}
// In bindings.rs we allocate a buffer filled with opaque white.
@ -363,7 +362,7 @@ Moz2DRenderCallback(const Range<const uint8_t> aBlob,
uninitialized);
if (!dt) {
return BlobRenderStatus::Error;
return false;
}
// We try hard to not have empty blobs but we can end up with
@ -393,7 +392,7 @@ Moz2DRenderCallback(const Range<const uint8_t> aBlob,
aDirtyRect->size.width, aDirtyRect->size.height));
}
wr::BlobRenderStatus status = wr::BlobRenderStatus::Empty;
bool ret = true;
size_t offset = 0;
auto absBounds = IntRectAbsolute::FromRect(bounds);
while (reader.pos < reader.len) {
@ -408,8 +407,6 @@ Moz2DRenderCallback(const Range<const uint8_t> aBlob,
continue;
}
status = BlobRenderStatus::Ok;
layers::WebRenderTranslator translator(dt);
Reader fontReader(aBlob.begin().get() + end, extra_end - end);
size_t count = fontReader.ReadSize();
@ -421,10 +418,9 @@ Moz2DRenderCallback(const Range<const uint8_t> aBlob,
}
Range<const uint8_t> blob(aBlob.begin() + offset, aBlob.begin() + end);
bool ok =
ret =
translator.TranslateRecording((char*)blob.begin().get(), blob.length());
if (!ok) {
status = BlobRenderStatus::Error;
if (!ret) {
gfxCriticalNote << "Replay failure: " << translator.GetError();
MOZ_RELEASE_ASSERT(false);
}
@ -451,7 +447,7 @@ Moz2DRenderCallback(const Range<const uint8_t> aBlob,
gfxUtils::WriteAsPNG(dt, filename);
#endif
return status;
return ret;
}
} // namespace wr
@ -459,15 +455,14 @@ Moz2DRenderCallback(const Range<const uint8_t> aBlob,
extern "C" {
mozilla::wr::BlobRenderStatus
wr_moz2d_render_cb(const mozilla::wr::ByteSlice blob,
mozilla::wr::ImageFormat aFormat,
const mozilla::wr::LayoutIntRect* aRenderRect,
const mozilla::wr::DeviceIntRect* aVisibleRect,
const uint16_t* aTileSize,
const mozilla::wr::TileOffset* aTileOffset,
const mozilla::wr::LayoutIntRect* aDirtyRect,
mozilla::wr::MutByteSlice output) {
bool wr_moz2d_render_cb(const mozilla::wr::ByteSlice blob,
mozilla::wr::ImageFormat aFormat,
const mozilla::wr::LayoutIntRect* aRenderRect,
const mozilla::wr::DeviceIntRect* aVisibleRect,
const uint16_t* aTileSize,
const mozilla::wr::TileOffset* aTileOffset,
const mozilla::wr::LayoutIntRect* aDirtyRect,
mozilla::wr::MutByteSlice output) {
return mozilla::wr::Moz2DRenderCallback(
mozilla::wr::ByteSliceToRange(blob),
mozilla::wr::ImageFormatToSurfaceFormat(aFormat), aVisibleRect,

View File

@ -3263,24 +3263,20 @@ pub unsafe extern "C" fn wr_dec_ref_arc(arc: *const VecU8) {
Arc::from_raw(arc);
}
#[repr(u32)]
pub enum BlobRenderStatus {
Ok,
Empty,
Error,
}
// TODO: nical
// Update for the new blob image interface changes.
//
extern "C" {
// TODO: figure out the API for tiled blob images.
pub fn wr_moz2d_render_cb(blob: ByteSlice,
format: ImageFormat,
render_rect: &LayoutIntRect,
visible_rect: &DeviceIntRect,
tile_size: Option<&u16>,
tile_offset: Option<&TileOffset>,
dirty_rect: Option<&LayoutIntRect>,
output: MutByteSlice)
-> BlobRenderStatus;
// TODO: figure out the API for tiled blob images.
pub fn wr_moz2d_render_cb(blob: ByteSlice,
format: ImageFormat,
render_rect: &LayoutIntRect,
visible_rect: &DeviceIntRect,
tile_size: Option<&u16>,
tile_offset: Option<&TileOffset>,
dirty_rect: Option<&LayoutIntRect>,
output: MutByteSlice)
-> bool;
}
#[no_mangle]

View File

@ -8,8 +8,7 @@
use webrender::api::*;
use webrender::api::units::{BlobDirtyRect, BlobToDeviceTranslation, DeviceIntRect};
use bindings::{ByteSlice, MutByteSlice, wr_moz2d_render_cb, ArcVecU8};
use bindings::{BlobRenderStatus, gecko_profiler_start_marker, gecko_profiler_end_marker};
use bindings::{ByteSlice, MutByteSlice, wr_moz2d_render_cb, ArcVecU8, gecko_profiler_start_marker, gecko_profiler_end_marker};
use rayon::ThreadPool;
use rayon::prelude::*;
@ -580,7 +579,7 @@ fn rasterize_blob(job: Job) -> (BlobImageRequest, BlobImageResult) {
assert!(descriptor.rect.size.width > 0 && descriptor.rect.size.height > 0);
let result = unsafe {
match wr_moz2d_render_cb(
if wr_moz2d_render_cb(
ByteSlice::new(&job.commands[..]),
descriptor.format,
&descriptor.rect,
@ -590,27 +589,18 @@ fn rasterize_blob(job: Job) -> (BlobImageRequest, BlobImageResult) {
dirty_rect.as_ref(),
MutByteSlice::new(output.as_mut_slice()),
) {
BlobRenderStatus::Ok => {
// We want the dirty rect local to the tile rather than the whole image.
// TODO(nical): move that up and avoid recomputing the tile bounds in the callback
let local_dirty_rect = job.dirty_rect.to_subrect_of(&descriptor.rect);
let tx: BlobToDeviceTranslation = (-descriptor.rect.origin.to_vector()).into();
let rasterized_rect = tx.transform_rect(&local_dirty_rect);
// We want the dirty rect local to the tile rather than the whole image.
// TODO(nical): move that up and avoid recomupting the tile bounds in the callback
let dirty_rect = job.dirty_rect.to_subrect_of(&descriptor.rect);
let tx: BlobToDeviceTranslation = (-descriptor.rect.origin.to_vector()).into();
let rasterized_rect = tx.transform_rect(&dirty_rect);
Ok(RasterizedBlobImage {
rasterized_rect,
data: Some(Arc::new(output)),
})
}
BlobRenderStatus::Empty => {
Ok(RasterizedBlobImage {
rasterized_rect: DeviceIntRect::zero(),
data: None,
})
}
BlobRenderStatus::Error => {
panic!("Moz2D replay problem");
}
Ok(RasterizedBlobImage {
rasterized_rect,
data: Arc::new(output),
})
} else {
panic!("Moz2D replay problem");
}
};

View File

@ -106,7 +106,7 @@ fn render_blob(
}
Ok(api::RasterizedBlobImage {
data: Some(Arc::new(texels)),
data: Arc::new(texels),
rasterized_rect: size2(w, h).into(),
})
}

View File

@ -403,26 +403,21 @@ impl ClipNodeInfo {
tile_size as i32,
);
for tile in tiles {
let mut render = true;
if request_resources {
render = resource_cache.request_image(
resource_cache.request_image(
request.with_tile(tile.offset),
gpu_cache,
).should_render();
}
if render {
mask_tiles.push(VisibleMaskImageTile {
tile_offset: tile.offset,
tile_rect: tile.rect,
});
);
}
mask_tiles.push(VisibleMaskImageTile {
tile_offset: tile.offset,
tile_rect: tile.rect,
});
}
}
visible_tiles = Some(mask_tiles);
} else if request_resources {
if resource_cache.request_image(request, gpu_cache).should_skip() {
return None;
}
resource_cache.request_image(request, gpu_cache);
}
} else {
// If the supplied image key doesn't exist in the resource cache,

View File

@ -17,7 +17,7 @@ use crate::prim_store::{
PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData,
PrimitiveStore, InternablePrimitive,
};
use crate::resource_cache::{ImageRequest, ResourceCache, ImageRequestStatus};
use crate::resource_cache::{ImageRequest, ResourceCache};
use crate::storage;
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -260,11 +260,11 @@ impl ImageBorderData {
&mut self,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
) -> ImageRequestStatus {
) {
resource_cache.request_image(
self.request,
gpu_cache,
)
);
}
fn write_prim_gpu_blocks(

View File

@ -24,7 +24,7 @@ use crate::render_task::{BlitSource, RenderTask};
use crate::render_task_cache::{
RenderTaskCacheEntryHandle, RenderTaskCacheKey, RenderTaskCacheKeyKind
};
use crate::resource_cache::{ImageRequest, ResourceCache, ImageRequestStatus};
use crate::resource_cache::{ImageRequest, ResourceCache};
use crate::util::pack_as_float;
#[derive(Debug)]
@ -457,11 +457,11 @@ impl YuvImageData {
&mut self,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
) -> ImageRequestStatus {
) {
let channel_num = self.format.get_plane_num();
debug_assert!(channel_num <= 3);
for channel in 0 .. channel_num {
let status = resource_cache.request_image(
resource_cache.request_image(
ImageRequest {
key: self.yuv_key[channel],
rendering: self.image_rendering,
@ -469,13 +469,7 @@ impl YuvImageData {
},
gpu_cache,
);
if status != ImageRequestStatus::Requested {
return status;
}
}
ImageRequestStatus::Requested
}
pub fn write_prim_gpu_blocks(&self, request: &mut GpuDataRequest) {

View File

@ -2364,12 +2364,11 @@ impl PrimitiveStore {
match image_properties {
Some(ImageProperties { tiling: None, .. }) => {
if frame_state.resource_cache.request_image(
frame_state.resource_cache.request_image(
request,
frame_state.gpu_cache,
).should_skip() {
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
}
);
}
Some(ImageProperties { tiling: Some(tile_size), visible_rect, .. }) => {
image_instance.visible_tiles.clear();
@ -2434,17 +2433,17 @@ impl PrimitiveStore {
);
for tile in tiles {
if frame_state.resource_cache.request_image(
frame_state.resource_cache.request_image(
request.with_tile(tile.offset),
frame_state.gpu_cache,
).should_render() {
image_instance.visible_tiles.push(VisibleImageTile {
tile_offset: tile.offset,
edge_flags: tile.edge_flags & edge_flags,
local_rect: tile.rect,
local_clip_rect: tight_clip_rect,
});
}
);
image_instance.visible_tiles.push(VisibleImageTile {
tile_offset: tile.offset,
edge_flags: tile.edge_flags & edge_flags,
local_rect: tile.rect,
local_clip_rect: tight_clip_rect,
});
}
}
@ -2458,21 +2457,17 @@ impl PrimitiveStore {
}
PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
let prim_data = &mut frame_state.data_stores.image_border[data_handle];
if prim_data.kind.request_resources(
prim_data.kind.request_resources(
frame_state.resource_cache,
frame_state.gpu_cache,
).should_skip() {
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
}
);
}
PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
let prim_data = &mut frame_state.data_stores.yuv_image[data_handle];
if prim_data.kind.request_resources(
prim_data.kind.request_resources(
frame_state.resource_cache,
frame_state.gpu_cache,
).should_skip() {
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
}
);
}
_ => {}
}

View File

@ -101,8 +101,6 @@ pub enum CachedImageData {
/// An image owned by the embedding, and referenced by WebRender. This may
/// take the form of a texture or a heap-allocated buffer.
External(ExternalImageData),
/// The image data is only transparent pixels, we can skip rendering it.
Empty,
}
impl From<ImageData> for CachedImageData {
@ -133,9 +131,8 @@ impl CachedImageData {
ExternalImageType::TextureHandle(_) => false,
ExternalImageType::Buffer => true,
},
CachedImageData::Blob
| CachedImageData::Raw(_)
| CachedImageData::Empty => true,
CachedImageData::Blob => true,
CachedImageData::Raw(_) => true,
}
}
}
@ -226,7 +223,6 @@ struct CachedImageInfo {
texture_cache_handle: TextureCacheHandle,
dirty_rect: ImageDirtyRect,
manual_eviction: bool,
is_fully_transparent: bool
}
impl CachedImageInfo {
@ -460,27 +456,6 @@ pub struct AsyncBlobImageInfo {
pub clear_requests: Vec<BlobImageClearParams>,
}
#[must_use]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ImageRequestStatus {
Requested,
FullyTransparent,
Error,
}
impl ImageRequestStatus {
pub fn should_render(self) -> bool {
match self {
Self::Requested => true,
_ => false,
}
}
pub fn should_skip(self) -> bool {
!self.should_render()
}
}
/// High-level container for resources managed by the `RenderBackend`.
///
/// This includes a variety of things, including images, fonts, and glyphs,
@ -574,9 +549,7 @@ impl ResourceCache {
fn should_tile(limit: i32, descriptor: &ImageDescriptor, data: &CachedImageData) -> bool {
let size_check = descriptor.size.width > limit || descriptor.size.height > limit;
match *data {
CachedImageData::Raw(_)
| CachedImageData::Blob
| CachedImageData::Empty => size_check,
CachedImageData::Raw(_) | CachedImageData::Blob => size_check,
CachedImageData::External(info) => {
// External handles already represent existing textures so it does
// not make sense to tile them into smaller ones.
@ -810,20 +783,6 @@ impl ResourceCache {
|| { RasterizedBlob::Tiled(FastHashMap::default()) }
);
if data.data.is_none() {
let entry = ensure_cached_image_entry(
&mut self.cached_images,
ImageRequest {
key: request.key.as_image(),
tile: request.tile,
rendering: ImageRendering::Auto,
},
);
// Mark the cached image as empty to skip rendering it later.
entry.is_fully_transparent = true;
}
if let Some(tile) = request.tile {
if let RasterizedBlob::NonTiled(..) = *image {
*image = RasterizedBlob::Tiled(FastHashMap::default());
@ -1151,13 +1110,11 @@ impl ResourceCache {
self.active_image_keys.insert(image_key);
}
// Returns false if the image should not be rendered, either due to an error,
// or if the image only contains fully transparent pixels.
pub fn request_image(
&mut self,
request: ImageRequest,
gpu_cache: &mut GpuCache,
) -> ImageRequestStatus {
) {
debug_assert_eq!(self.state, State::AddResources);
let template = match self.resources.image_templates.get(request.key) {
@ -1165,13 +1122,13 @@ impl ResourceCache {
None => {
warn!("ERROR: Trying to render deleted / non-existent key");
debug!("key={:?}", request.key);
return ImageRequestStatus::Error;
return
}
};
// Images that don't use the texture cache can early out.
if !template.data.uses_texture_cache() {
return ImageRequestStatus::Requested;
return;
}
let side_size =
@ -1182,27 +1139,76 @@ impl ResourceCache {
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.key, ImageResult::Err(ImageCacheError::OverLimitSize));
return ImageRequestStatus::Error;
return;
}
let entry = ensure_cached_image_entry(&mut self.cached_images, request);
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::invalid(),
dirty_rect: DirtyRect::All,
manual_eviction: false,
}))
}
_ => None
};
let needs_upload = self.texture_cache.request(&entry.texture_cache_handle, gpu_cache);
if entry.is_fully_transparent {
// Empty tile, skip rendering.
return ImageRequestStatus::FullyTransparent;
}
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);
}
}
entry
}
Vacant(entry) => {
entry.insert(if request.is_untiled_auto() {
ImageResult::UntiledAuto(CachedImageInfo {
texture_cache_handle: TextureCacheHandle::invalid(),
dirty_rect: DirtyRect::All,
manual_eviction: false,
})
} 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::invalid(),
dirty_rect: DirtyRect::All,
manual_eviction: false,
})
},
ImageResult::Err(_) => panic!("Errors should already have been handled"),
};
let needs_upload = self.texture_cache.request(&entry.texture_cache_handle, gpu_cache);
if !needs_upload && entry.dirty_rect.is_empty() {
return ImageRequestStatus::Requested;
return
}
if !self.pending_image_requests.insert(request) {
return ImageRequestStatus::Requested;
return
}
// By this point, we know that the image request is considered dirty, and will
@ -1250,8 +1256,6 @@ impl ResourceCache {
);
}
}
return ImageRequestStatus::Requested;
}
pub fn create_blob_scene_builder_requests(
@ -1579,14 +1583,6 @@ impl ResourceCache {
pub fn get_cached_image(&self, request: ImageRequest) -> Result<CacheItem, ()> {
debug_assert_eq!(self.state, State::QueryResources);
let image_info = self.get_image_info(request)?;
if image_info.is_fully_transparent {
// TODO(nical): Ideally we should have discarded the primitive already.
// If a blob image was not rasterized before frame building we end up
// knowing whether its content is transparent after the culling phase
// so we have to check again here. The plan is to remove the late blob
// rasterization code, after which we can simplify this.
return Err(())
}
Ok(self.get_texture_cache_item(&image_info.texture_cache_handle))
}
@ -1624,9 +1620,7 @@ impl ResourceCache {
ExternalImageType::Buffer => None,
},
// raw and blob image are all using resource_cache.
CachedImageData::Raw(..)
| CachedImageData::Blob
| CachedImageData::Empty => None,
CachedImageData::Raw(..) | CachedImageData::Blob => None,
};
ImageProperties {
@ -1733,9 +1727,7 @@ impl ResourceCache {
let mut updates: SmallVec<[(CachedImageData, Option<DeviceIntRect>); 1]> = SmallVec::new();
match image_template.data {
CachedImageData::Raw(..)
| CachedImageData::External(..)
| CachedImageData::Empty => {
CachedImageData::Raw(..) | CachedImageData::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));
@ -1746,29 +1738,17 @@ impl ResourceCache {
match (blob_image, request.tile) {
(RasterizedBlob::Tiled(ref tiles), Some(tile)) => {
let img = &tiles[&tile];
updates.push(
if let Some(ref data) = img.data {
(
CachedImageData::Raw(Arc::clone(data)),
Some(img.rasterized_rect)
)
} else {
(CachedImageData::Empty, None)
}
);
updates.push((
CachedImageData::Raw(Arc::clone(&img.data)),
Some(img.rasterized_rect)
));
}
(RasterizedBlob::NonTiled(ref mut queue), None) => {
for img in queue.drain(..) {
updates.push(
if let Some(data) = img.data {
(
CachedImageData::Raw(data),
Some(img.rasterized_rect)
)
} else {
(CachedImageData::Empty, None)
}
);
updates.push((
CachedImageData::Raw(img.data),
Some(img.rasterized_rect)
));
}
}
_ => {
@ -1946,9 +1926,7 @@ impl ResourceCache {
for (_, image) in self.resources.image_templates.images.iter() {
report.images += match image.data {
CachedImageData::Raw(ref v) => unsafe { op(v.as_ptr() as *const c_void) },
CachedImageData::Blob
| CachedImageData::External(..)
| CachedImageData::Empty => 0,
CachedImageData::Blob | CachedImageData::External(..) => 0,
}
}
@ -1993,72 +1971,6 @@ impl Drop for ResourceCache {
}
}
fn ensure_cached_image_entry(cached_images: &mut ImageCache, request: ImageRequest) -> &mut CachedImageInfo {
let storage = match 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::invalid(),
dirty_rect: DirtyRect::All,
manual_eviction: false,
is_fully_transparent: false,
}))
}
_ => 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);
}
}
entry
}
Vacant(entry) => {
entry.insert(
if request.is_untiled_auto() {
ImageResult::UntiledAuto(CachedImageInfo {
texture_cache_handle: TextureCacheHandle::invalid(),
dirty_rect: DirtyRect::All,
manual_eviction: false,
is_fully_transparent: false,
})
} else {
ImageResult::Multi(ResourceClassCache::new())
}
)
}
};
match *storage {
ImageResult::UntiledAuto(ref mut entry) => entry,
ImageResult::Multi(ref mut entries) => {
entries.entry(request.into())
.or_insert(CachedImageInfo {
texture_cache_handle: TextureCacheHandle::invalid(),
dirty_rect: DirtyRect::All,
manual_eviction: false,
is_fully_transparent: false,
})
},
ImageResult::Err(_) => panic!("Errors should already have been handled"),
}
}
pub fn get_blob_tiling(
tiling: Option<TileSize>,
size: DeviceIntSize,
@ -2241,7 +2153,7 @@ impl ResourceCache {
warn!("Tiled blob images aren't supported yet");
RasterizedBlobImage {
rasterized_rect: desc.size.into(),
data: None,
data: Arc::new(vec![0; desc.compute_total_size() as usize])
}
} else {
let blob_handler = self.blob_image_handler.as_mut().unwrap();
@ -2251,26 +2163,25 @@ impl ResourceCache {
result.expect("Blob rasterization failed")
};
num_blobs += 1;
assert_eq!(result.rasterized_rect.size, desc.size);
if let Some(ref data) = result.data {
assert_eq!(data.len(), desc.compute_total_size() as usize);
#[cfg(feature = "png")]
CaptureConfig::save_png(
root.join(format!("blobs/{}.png", num_blobs)),
desc.size,
desc.format,
data,
);
let file_name = format!("{}.raw", num_blobs);
let short_path = format!("blobs/{}", file_name);
let full_path = path_blobs.clone().join(&file_name);
fs::File::create(full_path)
.expect(&format!("Unable to create {}", short_path))
.write_all(data)
.unwrap();
other_paths.insert(key, short_path);
}
assert_eq!(result.data.len(), desc.compute_total_size() as usize);
num_blobs += 1;
#[cfg(feature = "png")]
CaptureConfig::save_png(
root.join(format!("blobs/{}.png", num_blobs)),
desc.size,
desc.format,
&result.data,
);
let file_name = format!("{}.raw", num_blobs);
let short_path = format!("blobs/{}", file_name);
let full_path = path_blobs.clone().join(&file_name);
fs::File::create(full_path)
.expect(&format!("Unable to create {}", short_path))
.write_all(&result.data)
.unwrap();
other_paths.insert(key, short_path);
}
CachedImageData::External(ref ext) => {
let short_path = format!("externals/{}", external_images.len() + 1);
@ -2281,7 +2192,6 @@ impl ResourceCache {
external: ext.clone(),
});
}
CachedImageData::Empty => {}
}
}

View File

@ -913,12 +913,6 @@ impl TextureCache {
) {
debug_assert!(self.now.is_valid());
if let Some(CachedImageData::Empty) = data {
self.mark_unused(handle);
*handle = TextureCacheHandle::invalid();
return;
}
// Determine if we need to allocate texture cache memory
// for this item. We need to reallocate if any of the following
// is true:
@ -1852,9 +1846,6 @@ impl TextureCacheUpdate {
CachedImageData::Blob => {
panic!("The vector image should have been rasterized.");
}
CachedImageData::Empty => {
panic!("The entry should have been cleared instead.");
}
CachedImageData::External(ext_image) => match ext_image.image_type {
ExternalImageType::TextureHandle(_) => {
panic!("External texture handle should not go through texture_cache.");

View File

@ -490,10 +490,7 @@ pub struct RasterizedBlobImage {
/// image or tile.
pub rasterized_rect: DeviceIntRect,
/// Backing store. The format is stored out of band in `BlobImageDescriptor`.
///
/// None means the image only has fully transparent content. We can skip storing
/// and rendering it.
pub data: Option<Arc<Vec<u8>>>,
pub data: Arc<Vec<u8>>,
}
/// Error code for when blob rasterization failed.

View File

@ -98,7 +98,7 @@ fn render_blob(
}
Ok(RasterizedBlobImage {
data: Some(Arc::new(texels)),
data: Arc::new(texels),
rasterized_rect,
})
}