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

Picture caching support, part 1 (of 2). #3332

Merged
merged 10 commits into from Nov 23, 2018

Address review comments.

  • Loading branch information
gw3583 committed Nov 22, 2018
commit e9ac545a1c8bfb77c69d3a7331fc123cca726871
@@ -24,6 +24,8 @@ void brush_vs(
#define BRUSH_FLAG_SEGMENT_REPEAT_Y 8
#define BRUSH_FLAG_TEXEL_RECT 16

#define INVALID_SEGMENT_INDEX 0xffff

void main(void) {
// Load the brush instance from vertex attributes.
int prim_header_address = aData.x;
@@ -37,15 +39,15 @@ void main(void) {
// Fetch the segment of this brush primitive we are drawing.
vec4 segment_data;
RectWithSize segment_rect;
if (segment_index == 0xffff) {
if (segment_index == INVALID_SEGMENT_INDEX) {
segment_rect = ph.local_rect;
segment_data = vec4(0.0);
} else {
int segment_address = ph.specific_prim_address +
VECS_PER_SPECIFIC_BRUSH +
segment_index * VECS_PER_SEGMENT;

vec4 segment_info[2] = fetch_from_gpu_cache_2(segment_address);
vec4[2] segment_info = fetch_from_gpu_cache_2(segment_address);
segment_rect = RectWithSize(segment_info[0].xy, segment_info[0].zw);
segment_data = segment_info[1];
}
@@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use api::{AlphaType, ClipMode, DeviceIntRect, DeviceIntPoint, DeviceIntSize};
use api::{ExternalImageType, FilterOp, ImageRendering, LayoutRect};
use api::{YuvColorSpace, YuvFormat, PictureRect, ColorDepth};
use api::{ExternalImageType, FilterOp, ImageRendering, LayoutRect, LayoutSize};
use api::{YuvColorSpace, YuvFormat, PictureRect, ColorDepth, LayoutPoint};
use clip::{ClipDataStore, ClipNodeFlags, ClipNodeRange, ClipItem, ClipStore};
use clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX, SpatialNodeIndex};
use glyph_rasterizer::GlyphFormat;
@@ -27,12 +27,15 @@ use scene::FilterOpHelpers;
use smallvec::SmallVec;
use std::{f32, i32, usize};
use tiling::{RenderTargetContext};
use util::{RectHelpers, TransformedRectKind};
use util::{TransformedRectKind};

// Special sentinel value recognized by the shader. It is considered to be
// a dummy task that doesn't mask out anything.
const OPAQUE_TASK_ADDRESS: RenderTaskAddress = RenderTaskAddress(0x7fff);

// Used to signal there are no segments provided with this primitive.
const INVALID_SEGMENT_INDEX: i32 = 0xffff;

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
@@ -906,78 +909,84 @@ impl AlphaBatchBuilder {

let tile_cache = picture.tile_cache.as_ref().unwrap();

for y in 0 .. tile_cache.y_tiles {
for x in 0 .. tile_cache.x_tiles {
let i = y * tile_cache.x_tiles + x;
for y in 0 .. tile_cache.tile_rect.size.height {
for x in 0 .. tile_cache.tile_rect.size.width {
let i = y * tile_cache.tile_rect.size.width + x;
let tile = &tile_cache.tiles[i as usize];

// Check if the tile is visible.
if tile.is_visible {

// Get the local rect of the tile.
let tx0 = (tile_cache.tile_x0 + x) as f32 * tile_cache.local_tile_size.width;
let ty0 = (tile_cache.tile_y0 + y) as f32 * tile_cache.local_tile_size.height;
let tx1 = tx0 + tile_cache.local_tile_size.width;
let ty1 = ty0 + tile_cache.local_tile_size.height;
let tile_rect = LayoutRect::from_floats(tx0, ty0, tx1, ty1);

// Construct a local clip rect that ensures we only draw pixels where
// the local bounds of the picture extend to within the edge tiles.
let local_clip_rect = prim_instance
.combined_local_clip_rect
.intersection(&picture.local_rect)
.expect("bug: invalid picture local rect");

let prim_header = PrimitiveHeader {
local_rect: tile_rect,
local_clip_rect,
task_address,
specific_prim_address: prim_cache_address,
clip_task_address,
transform_id,
};

let prim_header_index = prim_headers.push(&prim_header, z_id, [
ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
RasterizationSpace::Local as i32,
get_shader_opacity(1.0),
]);

let cache_item = ctx
.resource_cache
.get_texture_cache_item(&tile.handle);

let key = BatchKey::new(
kind,
non_segmented_blend_mode,
BatchTextures::color(cache_item.texture_id),
);
if !tile.is_visible {
continue;
}

let uv_rect_address = gpu_cache
.get_address(&cache_item.uv_rect_handle)
.as_int();

let instance = BrushInstance {
prim_header_index,
clip_task_address,
segment_index: 0xffff,
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags: BrushFlags::empty(),
user_data: uv_rect_address,
};

// Instead of retrieving the batch once and adding each tile instance,
// use this API to get an appropriate batch for each tile, since
// the batch textures may be different. The batch list internally
// caches the current batch if the key hasn't changed.
let batch = self.batch_list.set_params_and_get_batch(
key,
bounding_rect,
z_id,
);
// Get the local rect of the tile.
let tile_rect = LayoutRect::new(
LayoutPoint::new(
(tile_cache.tile_rect.origin.x + x) as f32 * tile_cache.local_tile_size.width,
(tile_cache.tile_rect.origin.y + y) as f32 * tile_cache.local_tile_size.height,
),
LayoutSize::new(
tile_cache.local_tile_size.width,
tile_cache.local_tile_size.height,
),
);

batch.push(PrimitiveInstanceData::from(instance));
}
// Construct a local clip rect that ensures we only draw pixels where
// the local bounds of the picture extend to within the edge tiles.
let local_clip_rect = prim_instance
.combined_local_clip_rect
.intersection(&picture.local_rect)
.expect("bug: invalid picture local rect");

let prim_header = PrimitiveHeader {
local_rect: tile_rect,
local_clip_rect,
task_address,
specific_prim_address: prim_cache_address,
clip_task_address,
transform_id,
};

let prim_header_index = prim_headers.push(&prim_header, z_id, [
ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
RasterizationSpace::Local as i32,
get_shader_opacity(1.0),
]);

let cache_item = ctx
.resource_cache
.get_texture_cache_item(&tile.handle);

let key = BatchKey::new(
kind,
non_segmented_blend_mode,
BatchTextures::color(cache_item.texture_id),
);

let uv_rect_address = gpu_cache
.get_address(&cache_item.uv_rect_handle)
.as_int();

let instance = BrushInstance {
prim_header_index,
clip_task_address,
segment_index: INVALID_SEGMENT_INDEX,
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags: BrushFlags::empty(),
user_data: uv_rect_address,
};

// Instead of retrieving the batch once and adding each tile instance,
// use this API to get an appropriate batch for each tile, since
// the batch textures may be different. The batch list internally
// caches the current batch if the key hasn't changed.
let batch = self.batch_list.set_params_and_get_batch(
key,
bounding_rect,
z_id,
);

batch.push(PrimitiveInstanceData::from(instance));
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.