@@ -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,46 @@ 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
+ let int_color_space: u8 = unsafe { mem:: transmute ( color_space) } ;
174
+ YuvImagePrimitiveGpu {
175
+ y_uv0 : DevicePoint :: zero ( ) ,
176
+ y_uv1 : DevicePoint :: zero ( ) ,
177
+ u_uv0 : DevicePoint :: zero ( ) ,
178
+ u_uv1 : DevicePoint :: zero ( ) ,
179
+ v_uv0 : DevicePoint :: zero ( ) ,
180
+ v_uv1 : DevicePoint :: zero ( ) ,
181
+ size : size,
182
+ color_space : int_color_space as f32 ,
183
+ padding : 0.0 ,
184
+ }
185
+ }
186
+ }
187
+
147
188
#[ derive( Debug , Clone ) ]
148
189
pub struct BorderPrimitiveCpu {
149
190
pub inner_rect : LayerRect ,
@@ -362,6 +403,7 @@ pub enum PrimitiveContainer {
362
403
Rectangle ( RectanglePrimitive ) ,
363
404
TextRun ( TextRunPrimitiveCpu , TextRunPrimitiveGpu ) ,
364
405
Image ( ImagePrimitiveCpu , ImagePrimitiveGpu ) ,
406
+ YuvImage ( YuvImagePrimitiveCpu , YuvImagePrimitiveGpu ) ,
365
407
Border ( BorderPrimitiveCpu , BorderPrimitiveGpu ) ,
366
408
Gradient ( GradientPrimitiveCpu , GradientPrimitiveGpu ) ,
367
409
BoxShadow ( BoxShadowPrimitiveGpu , Vec < LayerRect > ) ,
@@ -372,6 +414,7 @@ pub struct PrimitiveStore {
372
414
pub cpu_bounding_rects : Vec < Option < DeviceIntRect > > ,
373
415
pub cpu_text_runs : Vec < TextRunPrimitiveCpu > ,
374
416
pub cpu_images : Vec < ImagePrimitiveCpu > ,
417
+ pub cpu_yuv_images : Vec < YuvImagePrimitiveCpu > ,
375
418
pub cpu_gradients : Vec < GradientPrimitiveCpu > ,
376
419
pub cpu_metadata : Vec < PrimitiveMetadata > ,
377
420
pub cpu_borders : Vec < BorderPrimitiveCpu > ,
@@ -398,6 +441,7 @@ impl PrimitiveStore {
398
441
cpu_bounding_rects : Vec :: new ( ) ,
399
442
cpu_text_runs : Vec :: new ( ) ,
400
443
cpu_images : Vec :: new ( ) ,
444
+ cpu_yuv_images : Vec :: new ( ) ,
401
445
cpu_gradients : Vec :: new ( ) ,
402
446
cpu_borders : Vec :: new ( ) ,
403
447
gpu_geometry : GpuStore :: new ( ) ,
@@ -487,6 +531,24 @@ impl PrimitiveStore {
487
531
self . cpu_images . push ( image_cpu) ;
488
532
metadata
489
533
}
534
+ PrimitiveContainer :: YuvImage ( image_cpu, image_gpu) => {
535
+ let gpu_address = self . gpu_data64 . push ( image_gpu) ;
536
+
537
+ let metadata = PrimitiveMetadata {
538
+ is_opaque : true ,
539
+ clip_source : clip_source,
540
+ clip_cache_info : clip_info,
541
+ prim_kind : PrimitiveKind :: YuvImage ,
542
+ cpu_prim_index : SpecificPrimitiveIndex ( self . cpu_yuv_images . len ( ) ) ,
543
+ gpu_prim_index : gpu_address,
544
+ gpu_data_address : GpuStoreAddress ( 0 ) ,
545
+ gpu_data_count : 0 ,
546
+ render_task : None ,
547
+ } ;
548
+
549
+ self . cpu_yuv_images . push ( image_cpu) ;
550
+ metadata
551
+ }
490
552
PrimitiveContainer :: Border ( border_cpu, border_gpu) => {
491
553
let gpu_address = self . gpu_data128 . push ( border_gpu) ;
492
554
@@ -663,6 +725,33 @@ impl PrimitiveStore {
663
725
}
664
726
image_cpu. color_texture_id = texture_id;
665
727
}
728
+ PrimitiveKind :: YuvImage => {
729
+ let image_cpu = & mut self . cpu_yuv_images [ metadata. cpu_prim_index . 0 ] ;
730
+ let image_gpu: & mut YuvImagePrimitiveGpu = unsafe {
731
+ mem:: transmute ( self . gpu_data64 . get_mut ( metadata. gpu_prim_index ) )
732
+ } ;
733
+
734
+ if image_cpu. y_texture_id == SourceTexture :: Invalid {
735
+ let y_cache_item = resource_cache. get_cached_image ( image_cpu. y_key , ImageRendering :: Auto ) ;
736
+ image_cpu. y_texture_id = y_cache_item. texture_id ;
737
+ image_gpu. y_uv0 = y_cache_item. uv0 ;
738
+ image_gpu. y_uv1 = y_cache_item. uv1 ;
739
+ }
740
+
741
+ if image_cpu. u_texture_id == SourceTexture :: Invalid {
742
+ let u_cache_item = resource_cache. get_cached_image ( image_cpu. u_key , ImageRendering :: Auto ) ;
743
+ image_cpu. u_texture_id = u_cache_item. texture_id ;
744
+ image_gpu. u_uv0 = u_cache_item. uv0 ;
745
+ image_gpu. u_uv1 = u_cache_item. uv1 ;
746
+ }
747
+
748
+ if image_cpu. v_texture_id == SourceTexture :: Invalid {
749
+ let v_cache_item = resource_cache. get_cached_image ( image_cpu. v_key , ImageRendering :: Auto ) ;
750
+ image_cpu. v_texture_id = v_cache_item. texture_id ;
751
+ image_gpu. v_uv0 = v_cache_item. uv0 ;
752
+ image_gpu. v_uv1 = v_cache_item. uv1 ;
753
+ }
754
+ }
666
755
}
667
756
}
668
757
@@ -851,6 +940,17 @@ impl PrimitiveStore {
851
940
ImagePrimitiveKind :: WebGL ( ..) => { }
852
941
}
853
942
}
943
+ PrimitiveKind :: YuvImage => {
944
+ let image_cpu = & mut self . cpu_yuv_images [ metadata. cpu_prim_index . 0 ] ;
945
+ prim_needs_resolve = true ;
946
+
947
+ resource_cache. request_image ( image_cpu. y_key , ImageRendering :: Auto ) ;
948
+ resource_cache. request_image ( image_cpu. u_key , ImageRendering :: Auto ) ;
949
+ resource_cache. request_image ( image_cpu. v_key , ImageRendering :: Auto ) ;
950
+
951
+ // TODO(nical): Currently assuming no tile_spacing for yuv images.
952
+ metadata. is_opaque = true ;
953
+ }
854
954
PrimitiveKind :: Gradient => {
855
955
let gradient = & mut self . cpu_gradients [ metadata. cpu_prim_index . 0 ] ;
856
956
if gradient. cache_dirty {
@@ -973,6 +1073,14 @@ impl From<GradientStop> for GpuBlock32 {
973
1073
}
974
1074
}
975
1075
1076
+ impl From < YuvImagePrimitiveGpu > for GpuBlock64 {
1077
+ fn from ( data : YuvImagePrimitiveGpu ) -> GpuBlock64 {
1078
+ unsafe {
1079
+ mem:: transmute :: < YuvImagePrimitiveGpu , GpuBlock64 > ( data)
1080
+ }
1081
+ }
1082
+ }
1083
+
976
1084
impl From < ClipRect > for GpuBlock32 {
977
1085
fn from ( data : ClipRect ) -> GpuBlock32 {
978
1086
unsafe {
0 commit comments