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

Add support for temporary (per-frame) allocations in GPU cache. #1349

Merged
merged 1 commit into from Jun 7, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Add support for temporary (per-frame) allocations in GPU cache.

This API is used for uploading data that changes every frame.

Port the split geometry code to use it as an example of how the
API works, and remove all the split geometry texture sampler
related code.
  • Loading branch information
gw3583 committed Jun 7, 2017
commit a5bf30153a87be15ca4b27d8c808837c99bc45a3
@@ -110,7 +110,6 @@ varying vec3 vClipMaskUv;

#define VECS_PER_LAYER 9
#define VECS_PER_RENDER_TASK 3
#define VECS_PER_SPLIT_GEOM 3
#define VECS_PER_PRIM_HEADER 2
#define VECS_PER_TEXT_RUN 1

@@ -3,18 +3,16 @@
* 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/. */

uniform sampler2D sSplitGeometry;

struct SplitGeometry {
vec3 points[4];
};

SplitGeometry fetch_split_geometry(int index) {
ivec2 uv = get_fetch_uv(index, VECS_PER_SPLIT_GEOM);
SplitGeometry fetch_split_geometry(int address) {
ivec2 uv = get_resource_cache_uv(address);

vec4 data0 = texelFetchOffset(sSplitGeometry, uv, 0, ivec2(0, 0));
vec4 data1 = texelFetchOffset(sSplitGeometry, uv, 0, ivec2(1, 0));
vec4 data2 = texelFetchOffset(sSplitGeometry, uv, 0, ivec2(2, 0));
vec4 data0 = texelFetchOffset(sResourceCache, uv, 0, ivec2(0, 0));
vec4 data1 = texelFetchOffset(sResourceCache, uv, 0, ivec2(1, 0));
vec4 data2 = texelFetchOffset(sResourceCache, uv, 0, ivec2(2, 0));

SplitGeometry geo;
geo.points = vec3[4](
@@ -1574,11 +1574,6 @@ impl Device {
self.gl.uniform_1i(u_gradients, TextureSampler::Gradients as i32);
}

let u_split_geometry = self.gl.get_uniform_location(program.id, "sSplitGeometry");
if u_split_geometry != -1 {
self.gl.uniform_1i(u_split_geometry, TextureSampler::SplitGeometry as i32);
}

Ok(())
}

@@ -12,7 +12,7 @@ use plane_split::{BspSplitter, Polygon, Splitter};
use prim_store::{GradientPrimitiveCpu, ImagePrimitiveCpu};
use prim_store::{ImagePrimitiveKind, PrimitiveContainer, PrimitiveIndex};
use prim_store::{PrimitiveStore, RadialGradientPrimitiveCpu};
use prim_store::{RectanglePrimitive, SplitGeometry, TextRunPrimitiveCpu};
use prim_store::{RectanglePrimitive, TextRunPrimitiveCpu};
use prim_store::{BoxShadowPrimitiveCpu, TexelRect, YuvImagePrimitiveCpu};
use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
use render_task::{AlphaRenderItem, MaskCacheKey, MaskResult, RenderTask, RenderTaskIndex};
@@ -1145,7 +1145,9 @@ impl FrameBuilder {
}
}

fn build_render_task(&mut self, clip_scroll_tree: &ClipScrollTree)
fn build_render_task(&mut self,
clip_scroll_tree: &ClipScrollTree,
gpu_cache: &mut GpuCache)
-> (RenderTask, usize) {
profile_scope!("build_render_task");

@@ -1169,7 +1171,6 @@ impl FrameBuilder {
// The plane splitter, using a simple BSP tree.
let mut splitter = BspSplitter::new();

self.prim_store.gpu_split_geometry.clear();
debug!("build_render_task()");

for cmd in &self.cmds {
@@ -1292,14 +1293,13 @@ impl FrameBuilder {
let task_id = preserve_3d_map[&sc_index].id;
debug!("\t\tproduce {:?} -> {:?} for {:?}", sc_index, poly, task_id);
let pp = &poly.points;
let split_geo = SplitGeometry {
data: [pp[0].x, pp[0].y, pp[0].z,
pp[1].x, pp[1].y, pp[1].z,
pp[2].x, pp[2].y, pp[2].z,
pp[3].x, pp[3].y, pp[3].z],
};
let gpu_index = self.prim_store.gpu_split_geometry.push(split_geo);
let item = AlphaRenderItem::SplitComposite(sc_index, task_id, gpu_index, next_z);
let gpu_blocks = [
[pp[0].x, pp[0].y, pp[0].z, pp[1].x].into(),
[pp[1].y, pp[1].z, pp[2].x, pp[2].y].into(),
[pp[2].z, pp[3].x, pp[3].y, pp[3].z].into(),
];
let handle = gpu_cache.push_per_frame_blocks(&gpu_blocks);
let item = AlphaRenderItem::SplitComposite(sc_index, task_id, handle, next_z);
current_task.as_alpha_batch().items.push(item);
}
splitter.reset();
@@ -1393,7 +1393,7 @@ impl FrameBuilder {
&mut profile_counters,
device_pixel_ratio);

let (main_render_task, static_render_task_count) = self.build_render_task(clip_scroll_tree);
let (main_render_task, static_render_task_count) = self.build_render_task(clip_scroll_tree, gpu_cache);
let mut render_tasks = RenderTaskCollection::new(static_render_task_count);

let mut required_pass_count = 0;
@@ -1455,7 +1455,6 @@ impl FrameBuilder {
render_task_data: render_tasks.render_task_data,
gpu_data32: self.prim_store.gpu_data32.build(),
gpu_gradient_data: self.prim_store.gpu_gradient_data.build(),
gpu_split_geometry: self.prim_store.gpu_split_geometry.build(),
gpu_resource_rects: self.prim_store.gpu_resource_rects.build(),
deferred_resolves: deferred_resolves,
gpu_cache_updates: Some(gpu_cache_updates),
@@ -484,6 +484,7 @@ impl GpuCache {
return None
}
}

Some(GpuDataRequest {
handle: handle,
frame_id: self.frame_id,
@@ -492,6 +493,23 @@ impl GpuCache {
})
}

// Push an array of data blocks to be uploaded to the GPU
// unconditionally for this frame. The cache handle will
// assert if the caller tries to retrieve the address
// of this handle on a subsequent frame. This is typically
// used for uploading data that changes every frame, and
// therefore makes no sense to try and cache.
pub fn push_per_frame_blocks(&mut self, blocks: &[GpuBlockData]) -> GpuCacheHandle {
let start_index = self.texture.pending_blocks.len();
self.texture.pending_blocks.extend_from_slice(blocks);
let location = self.texture.push_data(start_index,
blocks.len(),
self.frame_id);
GpuCacheHandle {
location: Some(location),
}
}

/// End the frame. Return the list of updates to apply to the
/// device specific cache texture.
pub fn end_frame(&mut self,
@@ -73,7 +73,6 @@ pub enum TextureSampler {
RenderTasks,
ResourceRects,
Gradients,
SplitGeometry,
Dither,
}

@@ -10,7 +10,7 @@ use gpu_cache::{GpuBlockData, GpuCache, GpuCacheHandle, GpuDataRequest, ToGpuBlo
use gpu_store::GpuStoreAddress;
use internal_types::{SourceTexture, PackedTexel};
use mask_cache::{ClipMode, ClipSource, MaskCacheInfo};
use renderer::{VertexDataStore, GradientDataStore, SplitGeometryStore, MAX_VERTEX_TEXTURE_WIDTH};
use renderer::{VertexDataStore, GradientDataStore, MAX_VERTEX_TEXTURE_WIDTH};
use render_task::{RenderTask, RenderTaskLocation};
use resource_cache::{CacheItem, ImageProperties, ResourceCache};
use std::mem;
@@ -139,20 +139,6 @@ impl PrimitiveMetadata {
}
}

#[derive(Debug, Clone)]
pub struct SplitGeometry {
pub data: [f32; 12],
}

impl Default for SplitGeometry {
fn default() -> SplitGeometry {
SplitGeometry {
data: unsafe { mem::uninitialized() },
}
}
}


#[derive(Debug, Clone)]
#[repr(C)]
pub struct RectanglePrimitive {
@@ -663,9 +649,6 @@ pub struct PrimitiveStore {
pub gpu_data32: VertexDataStore<GpuBlock32>,
pub gpu_gradient_data: GradientDataStore,

/// Geometry generated by plane splitting.
pub gpu_split_geometry: SplitGeometryStore,

/// Resolved resource rects.
pub gpu_resource_rects: VertexDataStore<TexelRect>,

@@ -689,7 +672,6 @@ impl PrimitiveStore {
prims_to_resolve: Vec::new(),
gpu_data32: VertexDataStore::new(),
gpu_gradient_data: GradientDataStore::new(),
gpu_split_geometry: SplitGeometryStore::new(),
gpu_resource_rects: VertexDataStore::new(),
}
}
@@ -709,7 +691,6 @@ impl PrimitiveStore {
prims_to_resolve: recycle_vec(self.prims_to_resolve),
gpu_data32: self.gpu_data32.recycle(),
gpu_gradient_data: self.gpu_gradient_data.recycle(),
gpu_split_geometry: self.gpu_split_geometry.recycle(),
gpu_resource_rects: self.gpu_resource_rects.recycle(),
}
}
@@ -2,7 +2,7 @@
* 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 gpu_store::GpuStoreAddress;
use gpu_cache::GpuCacheHandle;
use internal_types::{HardwareCompositeOp, LowLevelFilterOp};
use mask_cache::{MaskBounds, MaskCacheInfo};
use prim_store::{PrimitiveCacheKey, PrimitiveIndex};
@@ -55,7 +55,7 @@ pub enum AlphaRenderItem {
Primitive(Option<ClipScrollGroupIndex>, PrimitiveIndex, i32),
Blend(StackingContextIndex, RenderTaskId, LowLevelFilterOp, i32),
Composite(StackingContextIndex, RenderTaskId, RenderTaskId, MixBlendMode, i32),
SplitComposite(StackingContextIndex, RenderTaskId, GpuStoreAddress, i32),
SplitComposite(StackingContextIndex, RenderTaskId, GpuCacheHandle, i32),
HardwareComposite(StackingContextIndex, RenderTaskId, HardwareCompositeOp, i32),
}

@@ -24,7 +24,7 @@ use internal_types::{CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp};
use internal_types::{TextureUpdateList, PackedVertex, RenderTargetMode};
use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, SourceTexture};
use internal_types::{BatchTextures, TextureSampler};
use prim_store::{GradientData, SplitGeometry};
use prim_store::GradientData;
use profiler::{Profiler, BackendProfileCounters};
use profiler::{GpuProfileTag, RendererProfileTimers, RendererProfileCounters};
use record::ApiRecordingReceiver;
@@ -344,26 +344,6 @@ impl GpuStoreLayout for GradientDataTextureLayout {
type GradientDataTexture = GpuDataTexture<GradientDataTextureLayout>;
pub type GradientDataStore = GpuStore<GradientData, GradientDataTextureLayout>;

pub struct SplitGeometryTextureLayout;

impl GpuStoreLayout for SplitGeometryTextureLayout {
fn image_format() -> ImageFormat {
//TODO: use normalized integers
ImageFormat::RGBAF32
}

fn texture_width<T>() -> usize {
MAX_VERTEX_TEXTURE_WIDTH - (MAX_VERTEX_TEXTURE_WIDTH % Self::texels_per_item::<T>())
}

fn texture_filter() -> TextureFilter {
TextureFilter::Nearest
}
}

type SplitGeometryTexture = GpuDataTexture<SplitGeometryTextureLayout>;
pub type SplitGeometryStore = GpuStore<SplitGeometry, SplitGeometryTextureLayout>;

const TRANSFORM_FEATURE: &'static str = "TRANSFORM";
const SUBPIXEL_AA_FEATURE: &'static str = "SUBPIXEL_AA";
const CLIP_FEATURE: &'static str = "CLIP";
@@ -532,7 +512,6 @@ struct GpuDataTextures {
data32_texture: VertexDataTexture,
resource_rects_texture: VertexDataTexture,
gradient_data_texture: GradientDataTexture,
split_geometry_texture: SplitGeometryTexture,
}

impl GpuDataTextures {
@@ -543,7 +522,6 @@ impl GpuDataTextures {
data32_texture: VertexDataTexture::new(device),
resource_rects_texture: VertexDataTexture::new(device),
gradient_data_texture: GradientDataTexture::new(device),
split_geometry_texture: SplitGeometryTexture::new(device),
}
}

@@ -553,14 +531,12 @@ impl GpuDataTextures {
self.layer_texture.init(device, &mut frame.layer_texture_data);
self.render_task_texture.init(device, &mut frame.render_task_data);
self.gradient_data_texture.init(device, &mut frame.gpu_gradient_data);
self.split_geometry_texture.init(device, &mut frame.gpu_split_geometry);

device.bind_texture(TextureSampler::Layers, self.layer_texture.id);
device.bind_texture(TextureSampler::RenderTasks, self.render_task_texture.id);
device.bind_texture(TextureSampler::Data32, self.data32_texture.id);
device.bind_texture(TextureSampler::ResourceRects, self.resource_rects_texture.id);
device.bind_texture(TextureSampler::Gradients, self.gradient_data_texture.id);
device.bind_texture(TextureSampler::SplitGeometry, self.split_geometry_texture.id);
}
}

@@ -12,7 +12,7 @@ use internal_types::{ANGLE_FLOAT_TO_FIXED, BatchTextures, CacheTextureId, LowLev
use internal_types::SourceTexture;
use mask_cache::MaskCacheInfo;
use prim_store::{CLIP_DATA_GPU_SIZE, DeferredResolve, GpuBlock32};
use prim_store::{GradientData, SplitGeometry, PrimitiveCacheKey};
use prim_store::{GradientData, PrimitiveCacheKey};
use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore, TexelRect};
use profiler::FrameProfileCounters;
use render_task::{AlphaRenderItem, MaskGeometryKind, MaskSegment, RenderTask, RenderTaskData};
@@ -602,19 +602,20 @@ impl AlphaRenderItem {
}
}
}
AlphaRenderItem::SplitComposite(sc_index, task_id, gpu_address, z) => {
AlphaRenderItem::SplitComposite(sc_index, task_id, gpu_handle, z) => {
let key = AlphaBatchKey::new(AlphaBatchKind::SplitComposite,
AlphaBatchKeyFlags::empty(),
BlendMode::PremultipliedAlpha,
BatchTextures::no_texture());
let stacking_context = &ctx.stacking_context_store[sc_index.0];
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
let source_task = render_tasks.get_task_index(&task_id, child_pass_index);
let gpu_address = gpu_handle.as_int(ctx.gpu_cache);

let instance = CompositePrimitiveInstance::new(task_index,
source_task,
RenderTaskIndex(0),
gpu_address.0,
gpu_address,
0,
z);

@@ -1638,7 +1639,6 @@ pub struct Frame {
pub render_task_data: Vec<RenderTaskData>,
pub gpu_data32: Vec<GpuBlock32>,
pub gpu_gradient_data: Vec<GradientData>,
pub gpu_split_geometry: Vec<SplitGeometry>,
pub gpu_resource_rects: Vec<TexelRect>,

// List of updates that need to be pushed to the
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.