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

Don't request source image from texture cache, if pre-rendered cache is valid. #2391

Merged
merged 2 commits into from Feb 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

@@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use api::{AlphaType, DeviceIntRect, DeviceIntSize, ImageKey, LayerToWorldScale};
use api::{AlphaType, DeviceIntRect, DeviceIntSize, LayerToWorldScale};
use api::{DeviceUintRect, DeviceUintPoint, DeviceUintSize, ExternalImageType, FilterOp, ImageRendering, LayerRect};
use api::{SubpixelDirection, TileOffset, YuvColorSpace, YuvFormat};
use api::{SubpixelDirection, YuvColorSpace, YuvFormat};
use api::{LayerToWorldTransform, WorldPixel};
use border::{BorderCornerInstance, BorderCornerSide, BorderEdgeKind};
use clip::{ClipSource, ClipStore};
@@ -25,7 +25,7 @@ use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKind};
use render_task::{RenderTaskTree};
use renderer::{BlendMode, ImageBufferKind};
use renderer::BLOCKS_PER_UV_RECT;
use resource_cache::{CacheItem, GlyphFetchResult, ResourceCache};
use resource_cache::{CacheItem, GlyphFetchResult, ImageRequest, ResourceCache};
use std::{usize, f32, i32};
use tiling::{RenderTargetContext, RenderTargetKind};
use util::{MatrixHelpers, TransformedRectKind};
@@ -710,9 +710,7 @@ impl AlphaBatcher {
let cache_item = match image_cpu.source {
ImageSource::Default => {
resolve_image(
image_cpu.key.image_key,
image_cpu.key.image_rendering,
image_cpu.key.tile_offset,
image_cpu.key.request,
ctx.resource_cache,
gpu_cache,
deferred_resolves,
@@ -1176,9 +1174,11 @@ impl AlphaBatcher {
let image_key = image_yuv_cpu.yuv_key[channel];

let cache_item = resolve_image(
image_key,
image_yuv_cpu.image_rendering,
None,
ImageRequest {
key: image_key,
rendering: image_yuv_cpu.image_rendering,
tile: None,
},
ctx.resource_cache,
gpu_cache,
deferred_resolves,
@@ -1385,14 +1385,12 @@ impl AlphaBatchHelpers for PrimitiveStore {
}

pub fn resolve_image(
image_key: ImageKey,
image_rendering: ImageRendering,
tile_offset: Option<TileOffset>,
request: ImageRequest,
resource_cache: &ResourceCache,
gpu_cache: &mut GpuCache,
deferred_resolves: &mut Vec<DeferredResolve>,
) -> CacheItem {
match resource_cache.get_image_properties(image_key) {
match resource_cache.get_image_properties(request.key) {
Some(image_properties) => {
// Check if an external image that needs to be resolved
// by the render thread.
@@ -1423,7 +1421,7 @@ pub fn resolve_image(
cache_item
}
None => {
if let Ok(cache_item) = resource_cache.get_cached_image(image_key, image_rendering, tile_offset) {
if let Ok(cache_item) = resource_cache.get_cached_image(request) {
cache_item
} else {
// There is no usable texture entry for the image key. Just return an invalid texture here.
@@ -1516,7 +1514,13 @@ impl ClipBatcher {

match *source {
ClipSource::Image(ref mask) => {
if let Ok(cache_item) = resource_cache.get_cached_image(mask.image, ImageRendering::Auto, None) {
if let Ok(cache_item) = resource_cache.get_cached_image(
ImageRequest {
key: mask.image,
rendering: ImageRendering::Auto,
tile: None,
}
) {
self.images
.entry(cache_item.texture_id)
.or_insert(Vec::new())
@@ -10,7 +10,7 @@ use ellipse::Ellipse;
use freelist::{FreeList, FreeListHandle, WeakFreeListHandle};
use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks};
use prim_store::{ClipData, ImageMaskData};
use resource_cache::ResourceCache;
use resource_cache::{ImageRequest, ResourceCache};
use util::{MaxRect, MatrixHelpers, calculate_screen_bounding_rect, extract_inner_rect_safe};

pub type ClipStore = FreeList<ClipSources>;
@@ -230,7 +230,14 @@ impl ClipSources {
}

if let ClipSource::Image(ref mask) = *source {
resource_cache.request_image(mask.image, ImageRendering::Auto, None, gpu_cache);
resource_cache.request_image(
ImageRequest {
key: mask.image,
rendering: ImageRendering::Auto,
tile: None,
},
gpu_cache,
);
}
}
}
@@ -31,7 +31,7 @@ use prim_store::{PrimitiveStore, RadialGradientPrimitiveCpu};
use prim_store::{BrushSegmentDescriptor, PrimitiveRun, TextRunPrimitiveCpu};
use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
use render_task::{ClearMode, ClipChain, RenderTask, RenderTaskId, RenderTaskTree};
use resource_cache::ResourceCache;
use resource_cache::{ImageRequest, ResourceCache};
use scene::{ScenePipeline, SceneProperties};
use std::{mem, usize, f32};
use tiling::{CompositeOps, Frame, RenderPass, RenderTargetKind};
@@ -1518,9 +1518,11 @@ impl FrameBuilder {
current_epoch: Epoch::invalid(),
source: ImageSource::Default,
key: ImageCacheKey {
image_key,
image_rendering,
tile_offset,
request: ImageRequest {
key: image_key,
rendering: image_rendering,
tile: tile_offset,
},
texel_rect: sub_rect.map(|texel_rect| {
DeviceIntRect::new(
DeviceIntPoint::new(
@@ -7,7 +7,7 @@ use api::{ColorF, ColorU, DeviceIntRect, DeviceIntSize, DevicePixelScale, Epoch}
use api::{ComplexClipRegion, ExtendMode, FontRenderMode};
use api::{GlyphInstance, GlyphKey, GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag};
use api::{LayerPoint, LayerRect, LayerSize, LayerToWorldTransform, LayerVector2D, LineOrientation};
use api::{LineStyle, PremultipliedColorF, TileOffset};
use api::{LineStyle, PremultipliedColorF};
use api::{WorldToLayerTransform, YuvColorSpace, YuvFormat};
use border::{BorderCornerInstance, BorderEdgeKind};
use clip_scroll_tree::{CoordinateSystemId};
@@ -22,7 +22,7 @@ use picture::{PictureKind, PicturePrimitive};
use render_task::{BlitSource, ClipChain, ClipChainNode, ClipChainNodeIter, ClipChainNodeRef, ClipWorkItem};
use render_task::{RenderTask, RenderTaskCacheKey, RenderTaskCacheKeyKind, RenderTaskId};
use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
use resource_cache::{CacheItem, ImageProperties, ResourceCache};
use resource_cache::{CacheItem, ImageProperties, ImageRequest, ResourceCache};
use segment::SegmentBuilder;
use std::{mem, usize};
use std::rc::Rc;
@@ -325,12 +325,7 @@ impl BrushPrimitive {
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct ImageCacheKey {
// TODO(gw): Consider introducing a struct that collectively
// identifies an image in the resource cache
// uniquely. We pass this around to a few places.
pub image_key: ImageKey,
pub image_rendering: ImageRendering,
pub tile_offset: Option<TileOffset>,
pub request: ImageRequest,
pub texel_rect: Option<DeviceIntRect>,
}

@@ -1186,7 +1181,7 @@ impl PrimitiveStore {
let image_cpu = &mut self.cpu_images[metadata.cpu_prim_index.0];
let image_properties = frame_state
.resource_cache
.get_image_properties(image_cpu.key.image_key);
.get_image_properties(image_cpu.key.request.key);

// TODO(gw): Add image.rs and move this code out to a separate
// source file as it gets more complicated, and we
@@ -1221,60 +1216,72 @@ impl PrimitiveStore {
};
}

// TODO(gw): Don't actually need this in cached source mode if
// the cache item is still valid...
frame_state.resource_cache.request_image(
image_cpu.key.image_key,
image_cpu.key.image_rendering,
image_cpu.key.tile_offset,
frame_state.gpu_cache,
);
// Set if we need to request the source image from the cache this frame.
let mut request_source_image = false;

// Every frame, for cached items, we need to request the render
// task cache item. The closure will be invoked on the first
// time through, and any time the render task output has been
// evicted from the texture cache.
if let ImageSource::Cache { size, ref mut item } = image_cpu.source {
let key = image_cpu.key;

// Request a pre-rendered image task.
*item = frame_state.resource_cache.request_render_task(
RenderTaskCacheKey {
size,
kind: RenderTaskCacheKeyKind::Image(key),
},
frame_state.gpu_cache,
frame_state.render_tasks,
|render_tasks| {
// Create a task to blit from the texture cache to
// a normal transient render task surface. This will
// copy only the sub-rect, if specified.
let cache_to_target_task = RenderTask::new_blit(
size,
BlitSource::Image {
key,
},
);
let cache_to_target_task_id = render_tasks.add(cache_to_target_task);

// Create a task to blit the rect from the child render
// task above back into the right spot in the persistent
// render target cache.
let target_to_cache_task = RenderTask::new_blit(
match image_cpu.source {
ImageSource::Cache { size, ref mut item } => {
let key = image_cpu.key;

// Request a pre-rendered image task.
*item = frame_state.resource_cache.request_render_task(
RenderTaskCacheKey {
size,
BlitSource::RenderTask {
task_id: cache_to_target_task_id,
},
);
let target_to_cache_task_id = render_tasks.add(target_to_cache_task);

// Hook this into the render task tree at the right spot.
pic_state.tasks.push(target_to_cache_task_id);

// Pass the image opacity, so that the cached render task
// item inherits the same opacity properties.
(target_to_cache_task_id, [0.0; 3], image_properties.descriptor.is_opaque)
}
kind: RenderTaskCacheKeyKind::Image(key),
},
frame_state.gpu_cache,
frame_state.render_tasks,
|render_tasks| {
// We need to render the image cache this frame,
// so will need access to the source texture.
request_source_image = true;

// Create a task to blit from the texture cache to
// a normal transient render task surface. This will
// copy only the sub-rect, if specified.
let cache_to_target_task = RenderTask::new_blit(
size,
BlitSource::Image {
key,
},
);
let cache_to_target_task_id = render_tasks.add(cache_to_target_task);

// Create a task to blit the rect from the child render
// task above back into the right spot in the persistent
// render target cache.
let target_to_cache_task = RenderTask::new_blit(
size,
BlitSource::RenderTask {
task_id: cache_to_target_task_id,
},
);
let target_to_cache_task_id = render_tasks.add(target_to_cache_task);

// Hook this into the render task tree at the right spot.
pic_state.tasks.push(target_to_cache_task_id);

// Pass the image opacity, so that the cached render task
// item inherits the same opacity properties.
(target_to_cache_task_id, [0.0; 3], image_properties.descriptor.is_opaque)
}
);
}
ImageSource::Default => {
// Normal images just reference the source texture each frame.
request_source_image = true;
}
}

// Request source image from the texture cache, if required.
if request_source_image {
frame_state.resource_cache.request_image(
image_cpu.key.request,
frame_state.gpu_cache,
);
}
}
@@ -1286,9 +1293,11 @@ impl PrimitiveStore {
debug_assert!(channel_num <= 3);
for channel in 0 .. channel_num {
frame_state.resource_cache.request_image(
image_cpu.yuv_key[channel],
image_cpu.image_rendering,
None,
ImageRequest {
key: image_cpu.yuv_key[channel],
rendering: image_cpu.image_rendering,
tile: None,
},
frame_state.gpu_cache,
);
}
@@ -209,10 +209,10 @@ where
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
struct ImageRequest {
key: ImageKey,
rendering: ImageRendering,
tile: Option<TileOffset>,
pub struct ImageRequest {
pub key: ImageKey,
pub rendering: ImageRendering,
pub tile: Option<TileOffset>,
}

impl Into<BlobImageRequest> for ImageRequest {
@@ -538,23 +538,16 @@ impl ResourceCache {

pub fn request_image(
&mut self,
key: ImageKey,
rendering: ImageRendering,
tile: Option<TileOffset>,
request: ImageRequest,
gpu_cache: &mut GpuCache,
) {
debug_assert_eq!(self.state, State::AddResources);
let request = ImageRequest {
key,
rendering,
tile,
};

let template = match self.resources.image_templates.get(key) {
let template = match self.resources.image_templates.get(request.key) {
Some(template) => template,
None => {
warn!("ERROR: Trying to render deleted / non-existent key");
debug!("key={:?}", key);
debug!("key={:?}", request.key);
return
}
};
@@ -734,26 +727,19 @@ impl ResourceCache {
#[inline]
pub fn get_cached_image(
&self,
image_key: ImageKey,
image_rendering: ImageRendering,
tile: Option<TileOffset>,
request: ImageRequest,
) -> Result<CacheItem, ()> {
debug_assert_eq!(self.state, State::QueryResources);
let key = ImageRequest {
key: image_key,
rendering: image_rendering,
tile,
};

// TODO(Jerry): add a debug option to visualize the corresponding area for
// the Err() case of CacheItem.
match *self.cached_images.get(&key) {
Ok(ref image_info) => {
Ok(self.texture_cache.get(&image_info.texture_cache_handle))
}
Err(_) => {
Err(())
}
match *self.cached_images.get(&request) {
Ok(ref image_info) => {
Ok(self.texture_cache.get(&image_info.texture_cache_handle))
}
Err(_) => {
Err(())
}
}
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.