Bug 1532174 - Strongly typed vertex data stores in WR r=gw
authorDzmitry Malyshau <dmalyshau@mozilla.com>
Tue, 12 Mar 2019 02:26:51 +0000
changeset 521473 46ad1441e7f2eb2ee61dfaf9cd16cb04564b1d8b
parent 521472 662d2392cb0167ea31aa1d078551204f45fe3c5c
child 521474 c154ee9861abc7f3e3a29210785a3d2d8e854fd0
push id10866
push usernerli@mozilla.com
push dateTue, 12 Mar 2019 18:59:09 +0000
treeherdermozilla-beta@445c24a51727 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw
bugs1532174
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1532174 - Strongly typed vertex data stores in WR r=gw Establishes a clear link of TransformData with the shader. Associates a vertex data type permanently, which makes the code cleaner and allow finding the relevant bits quickly with search. Differential Revision: https://phabricator.services.mozilla.com/D23006
gfx/wr/webrender/src/batch.rs
gfx/wr/webrender/src/gpu_types.rs
gfx/wr/webrender/src/renderer.rs
--- a/gfx/wr/webrender/src/batch.rs
+++ b/gfx/wr/webrender/src/batch.rs
@@ -13,17 +13,17 @@ use gpu_cache::{GpuBlockData, GpuCache, 
 use gpu_types::{BrushFlags, BrushInstance, PrimitiveHeaders, ZBufferId, ZBufferIdGenerator};
 use gpu_types::{ClipMaskInstance, SplitCompositeInstance, SnapOffsets};
 use gpu_types::{PrimitiveInstanceData, RasterizationSpace, GlyphInstance};
 use gpu_types::{PrimitiveHeader, PrimitiveHeaderIndex, TransformPaletteId, TransformPalette};
 use internal_types::{FastHashMap, SavedTargetIndex, TextureSource};
 use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureSurface};
 use prim_store::{DeferredResolve, EdgeAaSegmentMask, PrimitiveInstanceKind, PrimitiveVisibilityIndex};
 use prim_store::{VisibleGradientTile, PrimitiveInstance, PrimitiveOpacity, SegmentInstanceIndex};
-use prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex};
+use prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex, VECS_PER_SEGMENT};
 use prim_store::image::ImageSource;
 use render_backend::DataStores;
 use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskTree, TileBlit};
 use renderer::{BlendMode, ImageBufferKind, ShaderColorMode};
 use renderer::{BLOCKS_PER_UV_RECT, MAX_VERTEX_TEXTURE_WIDTH};
 use resource_cache::{CacheItem, GlyphFetchResult, ImageRequest, ResourceCache, ImageProperties};
 use scene::FilterOpHelpers;
 use smallvec::SmallVec;
@@ -2013,17 +2013,16 @@ impl AlphaBatchBuilder {
                         transform_kind,
                         render_tasks,
                         z_id,
                         prim_info.clip_task_index,
                         ctx,
                     );
                 } else {
                     const VECS_PER_SPECIFIC_BRUSH: usize = 3;
-                    const VECS_PER_SEGMENT: usize = 2;
                     let max_tiles_per_header = (MAX_VERTEX_TEXTURE_WIDTH - VECS_PER_SPECIFIC_BRUSH) / VECS_PER_SEGMENT;
 
                     // use temporary block storage since we don't know the number of visible tiles beforehand
                     let mut gpu_blocks = Vec::<GpuBlockData>::new();
                     for chunk in image_instance.visible_tiles.chunks(max_tiles_per_header) {
                         gpu_blocks.clear();
                         gpu_blocks.push(PremultipliedColorF::WHITE.into()); //color
                         gpu_blocks.push(PremultipliedColorF::WHITE.into()); //bg color
--- a/gfx/wr/webrender/src/gpu_types.rs
+++ b/gfx/wr/webrender/src/gpu_types.rs
@@ -13,16 +13,18 @@ use gpu_cache::{GpuCacheAddress, GpuData
 use internal_types::FastHashMap;
 use prim_store::EdgeAaSegmentMask;
 use render_task::RenderTaskAddress;
 use std::i32;
 use util::{TransformedRectKind, MatrixHelpers};
 
 // Contains type that must exactly match the same structures declared in GLSL.
 
+pub const VECS_PER_TRANSFORM: usize = 8;
+
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[repr(C)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct ZBufferId(i32);
 
 impl ZBufferId {
     pub fn invalid() -> Self {
@@ -386,17 +388,17 @@ impl TransformPaletteId {
         if (self.0 >> 24) == 0 {
             TransformedRectKind::AxisAligned
         } else {
             TransformedRectKind::Complex
         }
     }
 }
 
-// The GPU data payload for a transform palette entry.
+/// The GPU data payload for a transform palette entry.
 #[derive(Debug, Clone)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 #[repr(C)]
 pub struct TransformData {
     transform: LayoutToPictureTransform,
     inv_transform: PictureToLayoutTransform,
 }
@@ -440,16 +442,17 @@ struct RelativeTransformKey {
 pub struct TransformPalette {
     pub transforms: Vec<TransformData>,
     metadata: Vec<TransformMetadata>,
     map: FastHashMap<RelativeTransformKey, usize>,
 }
 
 impl TransformPalette {
     pub fn new() -> Self {
+        let _ = VECS_PER_TRANSFORM;
         TransformPalette {
             transforms: Vec::new(),
             metadata: Vec::new(),
             map: FastHashMap::default(),
         }
     }
 
     pub fn allocate(&mut self, count: usize) {
--- a/gfx/wr/webrender/src/renderer.rs
+++ b/gfx/wr/webrender/src/renderer.rs
@@ -59,17 +59,17 @@ use euclid::rect;
 use euclid::Transform3D;
 use frame_builder::{ChasePrimitive, FrameBuilderConfig};
 use gleam::gl;
 use glyph_rasterizer::{GlyphFormat, GlyphRasterizer};
 use gpu_cache::{GpuBlockData, GpuCacheUpdate, GpuCacheUpdateList};
 use gpu_cache::{GpuCacheDebugChunk, GpuCacheDebugCmd};
 #[cfg(feature = "pathfinder")]
 use gpu_glyph_renderer::GpuGlyphRenderer;
-use gpu_types::ScalingInstance;
+use gpu_types::{PrimitiveHeaderI, PrimitiveHeaderF, ScalingInstance, TransformData};
 use internal_types::{TextureSource, ORTHO_FAR_PLANE, ORTHO_NEAR_PLANE, ResourceCacheError};
 use internal_types::{CacheTextureId, DebugOutput, FastHashMap, LayerIndex, RenderedDocument, ResultMsg};
 use internal_types::{TextureCacheAllocationKind, TextureCacheUpdate, TextureUpdateList, TextureUpdateSource};
 use internal_types::{RenderTargetInfo, SavedTargetIndex};
 use malloc_size_of::MallocSizeOfOps;
 use picture::{RecordedDirtyRegion, TileCache};
 use prim_store::DeferredResolve;
 use profiler::{BackendProfileCounters, FrameProfileCounters, TimeProfileCounter,
@@ -77,25 +77,26 @@ use profiler::{BackendProfileCounters, F
 use profiler::{Profiler, ChangeIndicator};
 use device::query::GpuProfiler;
 use rayon::{ThreadPool, ThreadPoolBuilder};
 use record::ApiRecordingReceiver;
 use render_backend::{FrameId, RenderBackend};
 use scene_builder::{SceneBuilder, LowPrioritySceneBuilder};
 use shade::{Shaders, WrShaders};
 use smallvec::SmallVec;
-use render_task::RenderTaskTree;
+use render_task::{RenderTaskData, RenderTaskTree};
 use resource_cache::ResourceCache;
 use util::drain_filter;
 
 use std;
 use std::cmp;
 use std::collections::VecDeque;
 use std::collections::hash_map::Entry;
 use std::f32;
+use std::marker::PhantomData;
 use std::mem;
 use std::os::raw::c_void;
 use std::path::PathBuf;
 use std::rc::Rc;
 use std::sync::Arc;
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::mpsc::{channel, Receiver};
 use std::thread;
@@ -1401,42 +1402,47 @@ impl GpuCacheTexture {
                 );
                 device.draw_nonindexed_points(0, count as _);
                 0
             }
         }
     }
 }
 
-struct VertexDataTexture {
+struct VertexDataTexture<T> {
     texture: Option<Texture>,
     format: ImageFormat,
     pbo: PBO,
+    _marker: PhantomData<T>,
 }
 
-impl VertexDataTexture {
+impl<T> VertexDataTexture<T> {
     fn new(
         device: &mut Device,
         format: ImageFormat,
-    ) -> VertexDataTexture {
-        let pbo = device.create_pbo();
-        VertexDataTexture { texture: None, format, pbo }
+    ) -> Self {
+        VertexDataTexture {
+            texture: None,
+            format,
+            pbo: device.create_pbo(),
+            _marker: PhantomData,
+        }
     }
 
     /// Returns a borrow of the GPU texture. Panics if it hasn't been initialized.
     fn texture(&self) -> &Texture {
         self.texture.as_ref().unwrap()
     }
 
     /// Returns an estimate of the GPU memory consumed by this VertexDataTexture.
     fn size_in_bytes(&self) -> usize {
         self.texture.as_ref().map_or(0, |t| t.size_in_bytes())
     }
 
-    fn update<T>(&mut self, device: &mut Device, data: &mut Vec<T>) {
+    fn update(&mut self, device: &mut Device, data: &mut Vec<T>) {
         debug_assert!(mem::size_of::<T>() % 16 == 0);
         let texels_per_item = mem::size_of::<T>() / 16;
         let items_per_row = MAX_VERTEX_TEXTURE_WIDTH / texels_per_item;
 
         // Ensure we always end up with a texture when leaving this method.
         if data.is_empty() {
             if self.texture.is_some() {
                 return;
@@ -1604,20 +1610,20 @@ pub struct Renderer {
     new_scene_indicator: ChangeIndicator,
     slow_frame_indicator: ChangeIndicator,
 
     last_time: u64,
 
     pub gpu_profile: GpuProfiler<GpuProfileTag>,
     vaos: RendererVAOs,
 
-    prim_header_f_texture: VertexDataTexture,
-    prim_header_i_texture: VertexDataTexture,
-    transforms_texture: VertexDataTexture,
-    render_task_texture: VertexDataTexture,
+    prim_header_f_texture: VertexDataTexture<PrimitiveHeaderF>,
+    prim_header_i_texture: VertexDataTexture<PrimitiveHeaderI>,
+    transforms_texture: VertexDataTexture<TransformData>,
+    render_task_texture: VertexDataTexture<RenderTaskData>,
     gpu_cache_texture: GpuCacheTexture,
 
     /// When the GPU cache debugger is enabled, we keep track of the live blocks
     /// in the GPU cache so that we can use them for the debug display. This
     /// member stores those live blocks, indexed by row.
     gpu_cache_debug_chunks: Vec<Vec<GpuCacheDebugChunk>>,
 
     gpu_cache_frame_id: FrameId,