diff --git a/gfx/wr/webrender/res/brush.glsl b/gfx/wr/webrender/res/brush.glsl index a338afb30814..94b528a01e8a 100644 --- a/gfx/wr/webrender/res/brush.glsl +++ b/gfx/wr/webrender/res/brush.glsl @@ -72,6 +72,11 @@ void brush_vs( #define INVALID_SEGMENT_INDEX 0xffff +// These constants must match the BrushShaderKind enum in gpu_types.rs. +#define BRUSH_KIND_SOLID 0x1000000 +#define BRUSH_KIND_IMAGE 0x2000000 +#define BRUSH_KIND_TEXT 0x4000000 + void main(void) { // Load the brush instance from vertex attributes. Instance instance = decode_instance_attributes(); @@ -158,7 +163,7 @@ void main(void) { ph.local_rect, segment_rect, ph.user_data, - instance.user_data, + instance.resource_address, transform.m, pic_task, brush_flags, diff --git a/gfx/wr/webrender/res/prim_shared.glsl b/gfx/wr/webrender/res/prim_shared.glsl index de0ce1f1ee94..27bd03e6b2cb 100644 --- a/gfx/wr/webrender/res/prim_shared.glsl +++ b/gfx/wr/webrender/res/prim_shared.glsl @@ -57,7 +57,8 @@ struct Instance int clip_address; int segment_index; int flags; - int user_data; + int resource_address; + int brush_kind; }; Instance decode_instance_attributes() { @@ -68,7 +69,8 @@ Instance decode_instance_attributes() { instance.clip_address = aData.y & 0xffff; instance.segment_index = aData.z & 0xffff; instance.flags = aData.z & 0xffff0000; - instance.user_data = aData.w; + instance.resource_address = aData.w & 0xffffff; + instance.brush_kind = aData.w & 0xff000000; return instance; } diff --git a/gfx/wr/webrender/res/ps_text_run.glsl b/gfx/wr/webrender/res/ps_text_run.glsl index 4df830d04c62..80252b9e0ece 100644 --- a/gfx/wr/webrender/res/ps_text_run.glsl +++ b/gfx/wr/webrender/res/ps_text_run.glsl @@ -178,7 +178,6 @@ void main(void) { int glyph_index = instance.segment_index; int subpx_dir = (instance.flags >> 24) & 0xff; int color_mode = (instance.flags >> 16) & 0xff; - int resource_address = instance.user_data; PrimitiveHeader ph = fetch_prim_header(instance.prim_header_address); Transform transform = fetch_transform(ph.transform_id); @@ -195,7 +194,7 @@ void main(void) { Glyph glyph = fetch_glyph(ph.specific_prim_address, glyph_index); glyph.offset += ph.local_rect.p0 - text_offset; - GlyphResource res = fetch_glyph_resource(resource_address); + GlyphResource res = fetch_glyph_resource(instance.resource_address); #ifdef WR_FEATURE_GLYPH_TRANSFORM // Transform from local space to glyph space. diff --git a/gfx/wr/webrender/src/batch.rs b/gfx/wr/webrender/src/batch.rs index 5bc78356a091..d13d516e27ac 100644 --- a/gfx/wr/webrender/src/batch.rs +++ b/gfx/wr/webrender/src/batch.rs @@ -11,7 +11,7 @@ use crate::composite::{CompositeState, CompositeTile, CompositeTileSurface}; use crate::glyph_rasterizer::GlyphFormat; use crate::gpu_cache::{GpuBlockData, GpuCache, GpuCacheHandle, GpuCacheAddress}; use crate::gpu_types::{BrushFlags, BrushInstance, PrimitiveHeaders, ZBufferId, ZBufferIdGenerator}; -use crate::gpu_types::{ClipMaskInstance, SplitCompositeInstance}; +use crate::gpu_types::{ClipMaskInstance, SplitCompositeInstance, BrushShaderKind}; use crate::gpu_types::{PrimitiveInstanceData, RasterizationSpace, GlyphInstance}; use crate::gpu_types::{PrimitiveHeader, PrimitiveHeaderIndex, TransformPaletteId, TransformPalette}; use crate::internal_types::{FastHashMap, SavedTargetIndex, Swizzle, TextureSource, Filter}; @@ -70,6 +70,17 @@ pub enum BatchKind { Brush(BrushBatchKind), } +impl BatchKind { + fn shader_kind(&self) -> BrushShaderKind { + match self { + BatchKind::Brush(BrushBatchKind::Solid) => BrushShaderKind::Solid, + BatchKind::Brush(BrushBatchKind::Image(..)) => BrushShaderKind::Image, + BatchKind::TextRun(..) => BrushShaderKind::Text, + _ => BrushShaderKind::None, + } + } +} + /// Optional textures that can be used as a source in the shaders. /// Textures that are not used by the batch are equal to TextureId::invalid(). #[derive(Copy, Clone, Debug)] @@ -575,7 +586,7 @@ impl BatchBuilder { clip_task_address: RenderTaskAddress, brush_flags: BrushFlags, prim_header_index: PrimitiveHeaderIndex, - user_data: i32, + resource_address: i32, prim_vis_mask: PrimitiveVisibilityMask, ) { for batcher in &mut self.batchers { @@ -589,7 +600,8 @@ impl BatchBuilder { render_task_address, brush_flags, prim_header_index, - user_data, + resource_address, + brush_kind: batch_key.kind.shader_kind(), }; batcher.push_single_instance( diff --git a/gfx/wr/webrender/src/gpu_types.rs b/gfx/wr/webrender/src/gpu_types.rs index 8808bde3cc1e..8259c9ca8ace 100644 --- a/gfx/wr/webrender/src/gpu_types.rs +++ b/gfx/wr/webrender/src/gpu_types.rs @@ -63,6 +63,21 @@ impl ZBufferIdGenerator { } } +/// A shader kind identifier that can be used by a generic-shader to select the behavior at runtime. +/// +/// Not all brush kinds need to be present in this enum, only those we want to support in the generic +/// brush shader. +/// Do not use the 24 lowest bits. This will be packed with other information in the vertex attributes. +/// The constants must match the corresponding defines in brush.glsl. +#[repr(i32)] +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum BrushShaderKind { + None = 0, + Solid = 0x1000000, + Image = 0x2000000, + Text = 0x4000000, +} + #[derive(Debug, Copy, Clone)] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] @@ -342,13 +357,13 @@ impl GlyphInstance { // TODO(gw): Some of these fields can be moved to the primitive // header since they are constant, and some can be // compressed to a smaller size. - pub fn build(&self, data0: i32, data1: i32, data2: i32) -> PrimitiveInstanceData { + pub fn build(&self, data0: i32, data1: i32, resource_address: i32) -> PrimitiveInstanceData { PrimitiveInstanceData { data: [ self.prim_header_index.0 as i32, data0, data1, - data2, + resource_address | BrushShaderKind::Text as i32, ], } } @@ -395,10 +410,7 @@ bitflags! { } } -// TODO(gw): Some of these fields can be moved to the primitive -// header since they are constant, and some can be -// compressed to a smaller size. -#[repr(C)] +/// Convenience structure to encode into PrimitiveInstanceData. pub struct BrushInstance { pub prim_header_index: PrimitiveHeaderIndex, pub render_task_address: RenderTaskAddress, @@ -406,7 +418,8 @@ pub struct BrushInstance { pub segment_index: i32, pub edge_flags: EdgeAaSegmentMask, pub brush_flags: BrushFlags, - pub user_data: i32, + pub resource_address: i32, + pub brush_kind: BrushShaderKind, } impl From for PrimitiveInstanceData { @@ -414,12 +427,13 @@ impl From for PrimitiveInstanceData { PrimitiveInstanceData { data: [ instance.prim_header_index.0, - ((instance.render_task_address.0 as i32) << 16) | - instance.clip_task_address.0 as i32, - instance.segment_index | - ((instance.edge_flags.bits() as i32) << 16) | - ((instance.brush_flags.bits() as i32) << 24), - instance.user_data, + ((instance.render_task_address.0 as i32) << 16) + | instance.clip_task_address.0 as i32, + instance.segment_index + | ((instance.edge_flags.bits() as i32) << 16) + | ((instance.brush_flags.bits() as i32) << 24), + instance.resource_address + | instance.brush_kind as i32, ] } }