@@ -12,7 +12,7 @@ use std::mem;
12
12
use std:: usize;
13
13
use tiling:: RenderTask ;
14
14
use util:: TransformedRect ;
15
- use webrender_traits:: { AuxiliaryLists , ColorF , ImageKey , ImageRendering } ;
15
+ use webrender_traits:: { AuxiliaryLists , ColorF , ImageKey , ImageRendering , YuvColorSpace } ;
16
16
use webrender_traits:: { ClipRegion , ComplexClipRegion , ItemRange , GlyphKey } ;
17
17
use webrender_traits:: { FontKey , FontRenderMode , WebGLContextId } ;
18
18
use webrender_traits:: { device_length, DeviceIntRect , DeviceIntSize } ;
@@ -73,6 +73,7 @@ pub enum PrimitiveKind {
73
73
Rectangle ,
74
74
TextRun ,
75
75
Image ,
76
+ YuvImage ,
76
77
Border ,
77
78
Gradient ,
78
79
BoxShadow ,
@@ -144,6 +145,45 @@ pub struct ImagePrimitiveGpu {
144
145
pub tile_spacing : LayerSize ,
145
146
}
146
147
148
+ #[ derive( Debug ) ]
149
+ pub struct YuvImagePrimitiveCpu {
150
+ pub y_key : ImageKey ,
151
+ pub u_key : ImageKey ,
152
+ pub v_key : ImageKey ,
153
+ pub y_texture_id : SourceTexture ,
154
+ pub u_texture_id : SourceTexture ,
155
+ pub v_texture_id : SourceTexture ,
156
+ }
157
+
158
+ #[ derive( Debug , Clone ) ]
159
+ pub struct YuvImagePrimitiveGpu {
160
+ pub y_uv0 : DevicePoint ,
161
+ pub y_uv1 : DevicePoint ,
162
+ pub u_uv0 : DevicePoint ,
163
+ pub u_uv1 : DevicePoint ,
164
+ pub v_uv0 : DevicePoint ,
165
+ pub v_uv1 : DevicePoint ,
166
+ pub size : LayerSize ,
167
+ pub color_space : f32 ,
168
+ pub padding : f32 ,
169
+ }
170
+
171
+ impl YuvImagePrimitiveGpu {
172
+ pub fn new ( size : LayerSize , color_space : YuvColorSpace ) -> Self {
173
+ YuvImagePrimitiveGpu {
174
+ y_uv0 : DevicePoint :: zero ( ) ,
175
+ y_uv1 : DevicePoint :: zero ( ) ,
176
+ u_uv0 : DevicePoint :: zero ( ) ,
177
+ u_uv1 : DevicePoint :: zero ( ) ,
178
+ v_uv0 : DevicePoint :: zero ( ) ,
179
+ v_uv1 : DevicePoint :: zero ( ) ,
180
+ size : size,
181
+ color_space : color_space as u32 as f32 ,
182
+ padding : 0.0 ,
183
+ }
184
+ }
185
+ }
186
+
147
187
#[ derive( Debug , Clone ) ]
148
188
pub struct BorderPrimitiveCpu {
149
189
pub inner_rect : LayerRect ,
@@ -362,6 +402,7 @@ pub enum PrimitiveContainer {
362
402
Rectangle ( RectanglePrimitive ) ,
363
403
TextRun ( TextRunPrimitiveCpu , TextRunPrimitiveGpu ) ,
364
404
Image ( ImagePrimitiveCpu , ImagePrimitiveGpu ) ,
405
+ YuvImage ( YuvImagePrimitiveCpu , YuvImagePrimitiveGpu ) ,
365
406
Border ( BorderPrimitiveCpu , BorderPrimitiveGpu ) ,
366
407
Gradient ( GradientPrimitiveCpu , GradientPrimitiveGpu ) ,
367
408
BoxShadow ( BoxShadowPrimitiveGpu , Vec < LayerRect > ) ,
@@ -372,6 +413,7 @@ pub struct PrimitiveStore {
372
413
pub cpu_bounding_rects : Vec < Option < DeviceIntRect > > ,
373
414
pub cpu_text_runs : Vec < TextRunPrimitiveCpu > ,
374
415
pub cpu_images : Vec < ImagePrimitiveCpu > ,
416
+ pub cpu_yuv_images : Vec < YuvImagePrimitiveCpu > ,
375
417
pub cpu_gradients : Vec < GradientPrimitiveCpu > ,
376
418
pub cpu_metadata : Vec < PrimitiveMetadata > ,
377
419
pub cpu_borders : Vec < BorderPrimitiveCpu > ,
@@ -398,6 +440,7 @@ impl PrimitiveStore {
398
440
cpu_bounding_rects : Vec :: new ( ) ,
399
441
cpu_text_runs : Vec :: new ( ) ,
400
442
cpu_images : Vec :: new ( ) ,
443
+ cpu_yuv_images : Vec :: new ( ) ,
401
444
cpu_gradients : Vec :: new ( ) ,
402
445
cpu_borders : Vec :: new ( ) ,
403
446
gpu_geometry : GpuStore :: new ( ) ,
@@ -487,6 +530,24 @@ impl PrimitiveStore {
487
530
self . cpu_images . push ( image_cpu) ;
488
531
metadata
489
532
}
533
+ PrimitiveContainer :: YuvImage ( image_cpu, image_gpu) => {
534
+ let gpu_address = self . gpu_data64 . push ( image_gpu) ;
535
+
536
+ let metadata = PrimitiveMetadata {
537
+ is_opaque : true ,
538
+ clip_source : clip_source,
539
+ clip_cache_info : clip_info,
540
+ prim_kind : PrimitiveKind :: YuvImage ,
541
+ cpu_prim_index : SpecificPrimitiveIndex ( self . cpu_yuv_images . len ( ) ) ,
542
+ gpu_prim_index : gpu_address,
543
+ gpu_data_address : GpuStoreAddress ( 0 ) ,
544
+ gpu_data_count : 0 ,
545
+ render_task : None ,
546
+ } ;
547
+
548
+ self . cpu_yuv_images . push ( image_cpu) ;
549
+ metadata
550
+ }
490
551
PrimitiveContainer :: Border ( border_cpu, border_gpu) => {
491
552
let gpu_address = self . gpu_data128 . push ( border_gpu) ;
492
553
@@ -663,6 +724,33 @@ impl PrimitiveStore {
663
724
}
664
725
image_cpu. color_texture_id = texture_id;
665
726
}
727
+ PrimitiveKind :: YuvImage => {
728
+ let image_cpu = & mut self . cpu_yuv_images [ metadata. cpu_prim_index . 0 ] ;
729
+ let image_gpu: & mut YuvImagePrimitiveGpu = unsafe {
730
+ mem:: transmute ( self . gpu_data64 . get_mut ( metadata. gpu_prim_index ) )
731
+ } ;
732
+
733
+ if image_cpu. y_texture_id == SourceTexture :: Invalid {
734
+ let y_cache_item = resource_cache. get_cached_image ( image_cpu. y_key , ImageRendering :: Auto ) ;
735
+ image_cpu. y_texture_id = y_cache_item. texture_id ;
736
+ image_gpu. y_uv0 = y_cache_item. uv0 ;
737
+ image_gpu. y_uv1 = y_cache_item. uv1 ;
738
+ }
739
+
740
+ if image_cpu. u_texture_id == SourceTexture :: Invalid {
741
+ let u_cache_item = resource_cache. get_cached_image ( image_cpu. u_key , ImageRendering :: Auto ) ;
742
+ image_cpu. u_texture_id = u_cache_item. texture_id ;
743
+ image_gpu. u_uv0 = u_cache_item. uv0 ;
744
+ image_gpu. u_uv1 = u_cache_item. uv1 ;
745
+ }
746
+
747
+ if image_cpu. v_texture_id == SourceTexture :: Invalid {
748
+ let v_cache_item = resource_cache. get_cached_image ( image_cpu. v_key , ImageRendering :: Auto ) ;
749
+ image_cpu. v_texture_id = v_cache_item. texture_id ;
750
+ image_gpu. v_uv0 = v_cache_item. uv0 ;
751
+ image_gpu. v_uv1 = v_cache_item. uv1 ;
752
+ }
753
+ }
666
754
}
667
755
}
668
756
@@ -851,6 +939,17 @@ impl PrimitiveStore {
851
939
ImagePrimitiveKind :: WebGL ( ..) => { }
852
940
}
853
941
}
942
+ PrimitiveKind :: YuvImage => {
943
+ let image_cpu = & mut self . cpu_yuv_images [ metadata. cpu_prim_index . 0 ] ;
944
+ prim_needs_resolve = true ;
945
+
946
+ resource_cache. request_image ( image_cpu. y_key , ImageRendering :: Auto ) ;
947
+ resource_cache. request_image ( image_cpu. u_key , ImageRendering :: Auto ) ;
948
+ resource_cache. request_image ( image_cpu. v_key , ImageRendering :: Auto ) ;
949
+
950
+ // TODO(nical): Currently assuming no tile_spacing for yuv images.
951
+ metadata. is_opaque = true ;
952
+ }
854
953
PrimitiveKind :: Gradient => {
855
954
let gradient = & mut self . cpu_gradients [ metadata. cpu_prim_index . 0 ] ;
856
955
if gradient. cache_dirty {
@@ -973,6 +1072,14 @@ impl From<GradientStop> for GpuBlock32 {
973
1072
}
974
1073
}
975
1074
1075
+ impl From < YuvImagePrimitiveGpu > for GpuBlock64 {
1076
+ fn from ( data : YuvImagePrimitiveGpu ) -> GpuBlock64 {
1077
+ unsafe {
1078
+ mem:: transmute :: < YuvImagePrimitiveGpu , GpuBlock64 > ( data)
1079
+ }
1080
+ }
1081
+ }
1082
+
976
1083
impl From < ClipRect > for GpuBlock32 {
977
1084
fn from ( data : ClipRect ) -> GpuBlock32 {
978
1085
unsafe {
0 commit comments