Skip to content

Commit 833bc24

Browse files
committed
YUV work.
1 parent e0dd8fb commit 833bc24

File tree

9 files changed

+287
-2
lines changed

9 files changed

+287
-2
lines changed

webrender/res/prim_shared.glsl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,24 @@ Image fetch_image(int index) {
607607
return image;
608608
}
609609

610+
struct YuvImage {
611+
vec4 y_st_rect;
612+
vec4 u_st_rect;
613+
vec4 v_st_rect;
614+
};
615+
616+
YuvImage fetch_yuv_image(int index) {
617+
YuvImage image;
618+
619+
ivec2 uv = get_fetch_uv_2(index);
620+
621+
image.y_st_rect = texelFetchOffset(sData64, uv, 0, ivec2(0, 0));
622+
image.u_st_rect = texelFetchOffset(sData64, uv, 0, ivec2(1, 0));
623+
image.v_st_rect = texelFetchOffset(sData64, uv, 0, ivec2(2, 0));
624+
625+
return image;
626+
}
627+
610628
struct BoxShadow {
611629
vec4 src_rect;
612630
vec4 bs_rect;

webrender/res/ps_yuv_image.fs.glsl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#line 1
2+
3+
/* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6+
7+
uniform mat3 uYuvColorMatrix;
8+
9+
void main(void) {
10+
#ifdef WR_FEATURE_TRANSFORM
11+
float alpha = 0.0;
12+
vec2 pos = init_transform_fs(vLocalPos, vLocalRect, alpha);
13+
14+
// We clamp the texture coordinate calculation here to the local rectangle boundaries,
15+
// which makes the edge of the texture stretch instead of repeat.
16+
vec2 relative_pos_in_rect =
17+
clamp(pos, vLocalRect.xy, vLocalRect.xy + vLocalRect.zw) - vLocalRect.xy;
18+
#else
19+
float alpha = 1.0;;
20+
vec2 relative_pos_in_rect = vLocalPos;
21+
#endif
22+
23+
//vec2 position_in_tile = mod(relative_pos_in_rect, vStretchSize);
24+
vec2 position_in_tile = relative_pos_in_rect;
25+
//vec2 st_y = vTextureOffsetY + ((position_in_tile / vStretchSize) * vTextureSizeY);
26+
vec2 st_y = vTextureOffsetY + (position_in_tile * vTextureSizeY);
27+
28+
// TODO(nical)
29+
vec2 st_u = st_y; // TODO!
30+
vec2 st_v = st_y; // TODO!
31+
32+
float y = texture(sColor0, st_y).a;
33+
float u = texture(sColor1, st_u).a;
34+
float v = texture(sColor2, st_v).a;
35+
oFragColor.rgb = uYuvColorMatrix * vec3(y - 0.06275, u - 0.50196, v - 0.50196);
36+
oFragColor.a = alpha;
37+
}

webrender/res/ps_yuv_image.glsl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
flat varying vec2 vTextureOffsetY; // Offset of the y plane into the texture atlas.
6+
flat varying vec2 vTextureOffsetU; // Offset of the u plane into the texture atlas.
7+
flat varying vec2 vTextureOffsetV; // Offset of the v plane into the texture atlas.
8+
flat varying vec2 vTextureSizeY; // Size of the y plane in the texture atlas.
9+
flat varying vec2 vTextureSizeUv; // Size of the u and v planes in the texture atlas.
10+
11+
#ifdef WR_FEATURE_TRANSFORM
12+
varying vec3 vLocalPos;
13+
flat varying vec4 vLocalRect;
14+
#else
15+
varying vec2 vLocalPos;
16+
#endif

webrender/res/ps_yuv_image.vs.glsl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#line 1
2+
/* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
void main(void) {
7+
Primitive prim = load_primitive(gl_InstanceID);
8+
YuvImage image = fetch_yuv_image(prim.prim_index);
9+
#ifdef WR_FEATURE_TRANSFORM
10+
TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
11+
prim.local_clip_rect,
12+
prim.layer,
13+
prim.tile);
14+
vLocalRect = vi.clipped_local_rect;
15+
vLocalPos = vi.local_pos;
16+
#else
17+
VertexInfo vi = write_vertex(prim.local_rect,
18+
prim.local_clip_rect,
19+
prim.layer,
20+
prim.tile);
21+
vLocalPos = vi.local_clamped_pos - vi.local_rect.p0;
22+
#endif
23+
24+
vec2 y_texture_size = vec2(textureSize(sColor0, 0));
25+
vec2 y_st0 = image.y_st_rect.xy / y_texture_size;
26+
vec2 y_st1 = image.y_st_rect.zw / y_texture_size;
27+
28+
vTextureSizeY = y_st1 - y_st0;
29+
vTextureOffsetY = y_st0;
30+
31+
vec2 uv_texture_size = vec2(textureSize(sColor1, 0));
32+
vec2 u_st0 = image.u_st_rect.xy / uv_texture_size;
33+
vec2 u_st1 = image.u_st_rect.zw / uv_texture_size;
34+
vec2 v_st0 = image.v_st_rect.xy / uv_texture_size;
35+
vec2 v_st1 = image.v_st_rect.zw / uv_texture_size;
36+
37+
vTextureSizeUv = u_st1 - u_st0; // TODO(nical) double check this
38+
vTextureOffsetU = u_st0;
39+
vTextureOffsetV = v_st0;
40+
//vTileSpacing = image.stretch_size_and_tile_spacing.zw;
41+
//vStretchSize = image.stretch_size_and_tile_spacing.xy;
42+
}

webrender/src/frame.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,13 @@ impl Frame {
595595
info.image_key,
596596
info.image_rendering);
597597
}
598+
SpecificDisplayItem::YuvImage(ref info) => {
599+
builder.add_yuv_image(item.rect,
600+
&item.clip,
601+
info.y_image_key,
602+
info.u_image_key,
603+
info.v_image_key);
604+
}
598605
SpecificDisplayItem::Text(ref text_info) => {
599606
builder.add_text(item.rect,
600607
&item.clip,

webrender/src/prim_store.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub enum PrimitiveKind {
3434
Rectangle,
3535
TextRun,
3636
Image,
37+
YuvImage,
3738
Border,
3839
Gradient,
3940
BoxShadow,
@@ -96,6 +97,16 @@ pub struct ImagePrimitiveCpu {
9697
pub color_texture_id: TextureId,
9798
}
9899

100+
#[derive(Debug)]
101+
pub struct YuvImagePrimitiveCpu {
102+
pub y_key: ImageKey,
103+
pub u_key: ImageKey,
104+
pub v_key: ImageKey,
105+
pub y_texture_id: TextureId,
106+
pub u_texture_id: TextureId,
107+
pub v_texture_id: TextureId,
108+
}
109+
99110
#[derive(Debug, Clone)]
100111
pub struct ImagePrimitiveGpu {
101112
pub uv0: Point2D<f32>,
@@ -104,6 +115,17 @@ pub struct ImagePrimitiveGpu {
104115
pub tile_spacing: Size2D<f32>,
105116
}
106117

118+
#[derive(Debug, Clone)]
119+
pub struct YuvImagePrimitiveGpu {
120+
pub y_uv0: Point2D<f32>,
121+
pub y_uv1: Point2D<f32>,
122+
pub u_uv0: Point2D<f32>,
123+
pub u_uv1: Point2D<f32>,
124+
pub v_uv0: Point2D<f32>,
125+
pub v_uv1: Point2D<f32>,
126+
pub padding: [f32; 4]
127+
}
128+
107129
#[derive(Debug, Clone)]
108130
pub struct BorderPrimitiveCpu {
109131
pub inner_rect: Rect<f32>,
@@ -330,6 +352,7 @@ pub enum PrimitiveContainer {
330352
Rectangle(RectanglePrimitive),
331353
TextRun(TextRunPrimitiveCpu, TextRunPrimitiveGpu),
332354
Image(ImagePrimitiveCpu, ImagePrimitiveGpu),
355+
YuvImage(YuvImagePrimitiveCpu, YuvImagePrimitiveGpu),
333356
Border(BorderPrimitiveCpu, BorderPrimitiveGpu),
334357
Gradient(GradientPrimitiveCpu, GradientPrimitiveGpu),
335358
BoxShadow(BoxShadowPrimitiveGpu, Vec<Rect<f32>>),
@@ -340,6 +363,7 @@ pub struct PrimitiveStore {
340363
pub cpu_bounding_rects: Vec<Option<DeviceRect>>,
341364
pub cpu_text_runs: Vec<TextRunPrimitiveCpu>,
342365
pub cpu_images: Vec<ImagePrimitiveCpu>,
366+
pub cpu_yuv_images: Vec<YuvImagePrimitiveCpu>,
343367
pub cpu_gradients: Vec<GradientPrimitiveCpu>,
344368
pub cpu_metadata: Vec<PrimitiveMetadata>,
345369
pub cpu_borders: Vec<BorderPrimitiveCpu>,
@@ -363,6 +387,7 @@ impl PrimitiveStore {
363387
cpu_bounding_rects: Vec::new(),
364388
cpu_text_runs: Vec::new(),
365389
cpu_images: Vec::new(),
390+
cpu_yuv_images: Vec::new(),
366391
cpu_gradients: Vec::new(),
367392
cpu_borders: Vec::new(),
368393
gpu_geometry: GpuStore::new(),
@@ -462,6 +487,25 @@ impl PrimitiveStore {
462487
self.cpu_images.push(image_cpu);
463488
metadata
464489
}
490+
PrimitiveContainer::YuvImage(image_cpu, image_gpu) => {
491+
let gpu_address = self.gpu_data64.push(image_gpu);
492+
493+
let metadata = PrimitiveMetadata {
494+
is_opaque: true,
495+
mask_texture_id: TextureId::invalid(),
496+
clip_index: None,
497+
clip_source: clip_source,
498+
prim_kind: PrimitiveKind::YuvImage,
499+
cpu_prim_index: SpecificPrimitiveIndex(self.cpu_yuv_images.len()),
500+
gpu_prim_index: gpu_address,
501+
gpu_data_address: GpuStoreAddress(0),
502+
gpu_data_count: 0,
503+
cache_info: None,
504+
};
505+
506+
self.cpu_yuv_images.push(image_cpu);
507+
metadata
508+
}
465509
PrimitiveContainer::Border(border_cpu, border_gpu) => {
466510
let gpu_address = self.gpu_data128.push(border_gpu);
467511

@@ -617,6 +661,27 @@ impl PrimitiveStore {
617661
image_gpu.uv0 = cache_item.uv0;
618662
image_gpu.uv1 = cache_item.uv1;
619663
}
664+
PrimitiveKind::YuvImage => {
665+
let image_cpu = &mut self.cpu_yuv_images[metadata.cpu_prim_index.0];
666+
let image_gpu: &mut YuvImagePrimitiveGpu = unsafe {
667+
mem::transmute(self.gpu_data64.get_mut(metadata.gpu_prim_index))
668+
};
669+
670+
let y_cache_item = resource_cache.get_image(image_cpu.y_key, ImageRendering::Auto);
671+
let u_cache_item = resource_cache.get_image(image_cpu.u_key, ImageRendering::Auto);
672+
let v_cache_item = resource_cache.get_image(image_cpu.v_key, ImageRendering::Auto);
673+
674+
image_cpu.y_texture_id = y_cache_item.texture_id;
675+
image_cpu.u_texture_id = u_cache_item.texture_id;
676+
image_cpu.v_texture_id = v_cache_item.texture_id;
677+
678+
image_gpu.y_uv0 = y_cache_item.uv0;
679+
image_gpu.y_uv1 = y_cache_item.uv1;
680+
image_gpu.u_uv0 = u_cache_item.uv0;
681+
image_gpu.u_uv1 = u_cache_item.uv1;
682+
image_gpu.v_uv0 = v_cache_item.uv0;
683+
image_gpu.v_uv1 = v_cache_item.uv1;
684+
}
620685
}
621686
}
622687
}
@@ -812,6 +877,17 @@ impl PrimitiveStore {
812877
ImagePrimitiveKind::WebGL(..) => {}
813878
}
814879
}
880+
PrimitiveKind::YuvImage => {
881+
let image_cpu = &mut self.cpu_yuv_images[metadata.cpu_prim_index.0];
882+
prim_needs_resolve = true;
883+
884+
resource_cache.request_image(image_cpu.y_key, ImageRendering::Auto);
885+
resource_cache.request_image(image_cpu.u_key, ImageRendering::Auto);
886+
resource_cache.request_image(image_cpu.v_key, ImageRendering::Auto);
887+
888+
// TODO(nical): Currently assuming no tile_spacing for yuv images.
889+
metadata.is_opaque = true;
890+
}
815891
PrimitiveKind::Gradient => {
816892
let gradient = &mut self.cpu_gradients[metadata.cpu_prim_index.0];
817893
if gradient.cache_dirty {
@@ -934,6 +1010,14 @@ impl From<ImagePrimitiveGpu> for GpuBlock32 {
9341010
}
9351011
}
9361012

1013+
impl From<YuvImagePrimitiveGpu> for GpuBlock64 {
1014+
fn from(data: YuvImagePrimitiveGpu) -> GpuBlock64 {
1015+
unsafe {
1016+
mem::transmute::<YuvImagePrimitiveGpu, GpuBlock64>(data)
1017+
}
1018+
}
1019+
}
1020+
9371021
impl From<ClipRect> for GpuBlock32 {
9381022
fn from(data: ClipRect) -> GpuBlock32 {
9391023
unsafe {

webrender/src/renderer.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ pub struct Renderer {
323323
ps_text_run: PrimitiveShader,
324324
ps_text_run_subpixel: PrimitiveShader,
325325
ps_image: PrimitiveShader,
326+
ps_yuv_image: PrimitiveShader,
326327
ps_border: PrimitiveShader,
327328
ps_gradient: PrimitiveShader,
328329
ps_gradient_clip: PrimitiveShader,
@@ -450,6 +451,12 @@ impl Renderer {
450451
&mut device,
451452
&[],
452453
options.precache_shaders);
454+
let ps_yuv_image = PrimitiveShader::new("ps_yuv_image",
455+
max_ubo_vectors,
456+
max_prim_instances,
457+
&mut device,
458+
&[],
459+
options.precache_shaders);
453460
let ps_border = PrimitiveShader::new("ps_border",
454461
max_ubo_vectors,
455462
max_prim_instances,
@@ -663,6 +670,7 @@ impl Renderer {
663670
ps_text_run: ps_text_run,
664671
ps_text_run_subpixel: ps_text_run_subpixel,
665672
ps_image: ps_image,
673+
ps_yuv_image: ps_yuv_image,
666674
ps_border: ps_border,
667675
ps_rectangle_clip: ps_rectangle_clip,
668676
ps_image_clip: ps_image_clip,
@@ -1468,6 +1476,21 @@ impl Renderer {
14681476
max_prim_items,
14691477
&projection);
14701478
}
1479+
&PrimitiveBatchData::YuvImage(ref ubo_data) => {
1480+
assert!(!has_complex_clip);
1481+
// TODO(nical): send the uYuvColorMatrix uniform!
1482+
// TODO(nical): GPU_TAG_PRIM_YUV_IMAGE
1483+
self.gpu_profile.add_marker(GPU_TAG_PRIM_IMAGE);
1484+
let (shader, max_prim_items) = self.ps_yuv_image.get(
1485+
&mut self.device, transform_kind
1486+
);
1487+
self.draw_ubo_batch(ubo_data,
1488+
shader,
1489+
1,
1490+
&batch.key.textures,
1491+
max_prim_items,
1492+
&projection);
1493+
}
14711494
&PrimitiveBatchData::Borders(ref ubo_data) => {
14721495
self.gpu_profile.add_marker(GPU_TAG_PRIM_BORDER);
14731496
let (shader, max_prim_items) = self.ps_border.get(&mut self.device, transform_kind);

0 commit comments

Comments
 (0)