| author | Glenn Watson <gw@intuitionlibrary.com> |
| Sun, 01 Mar 2020 03:56:02 +0000 | |
| changeset 516286 | 8f267ed8f2e3d09ced8c665af0a6db3694197116 |
| parent 516285 | 6814870342efc284b2edec7c9aeb45240cb0fe09 |
| child 516287 | 85f45093d17263d329e170335a62240058ac31aa |
| push id | 37172 |
| push user | malexandru@mozilla.com |
| push date | Mon, 02 Mar 2020 09:48:18 +0000 |
| treeherder | mozilla-central@51efc4b931f7 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | Bert |
| bugs | 1579235 |
| milestone | 75.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
|
--- a/gfx/wr/webrender/res/composite.glsl +++ b/gfx/wr/webrender/res/composite.glsl @@ -51,35 +51,35 @@ void main(void) { float yuv_coefficient = aParams.w; vYuvColorMatrix = get_yuv_color_matrix(yuv_color_space); vYuvCoefficient = yuv_coefficient; vYuvFormat = yuv_format; write_uv_rect( aUvRect0.xy, - aUvRect0.xy + aUvRect0.zw, + aUvRect0.zw, aTextureLayers.x, uv, TEX_SIZE(sColor0), vUV_y, vUVBounds_y ); write_uv_rect( aUvRect1.xy, - aUvRect1.xy + aUvRect1.zw, + aUvRect1.zw, aTextureLayers.y, uv, TEX_SIZE(sColor1), vUV_u, vUVBounds_u ); write_uv_rect( aUvRect2.xy, - aUvRect2.xy + aUvRect2.zw, + aUvRect2.zw, aTextureLayers.z, uv, TEX_SIZE(sColor2), vUV_v, vUVBounds_v ); #else vUv = uv;
--- a/gfx/wr/webrender/src/composite.rs +++ b/gfx/wr/webrender/src/composite.rs @@ -1,15 +1,15 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use api::{ColorF, ImageKey, YuvColorSpace, YuvFormat, ImageRendering}; use api::units::{DeviceRect, DeviceIntSize, DeviceIntRect, DeviceIntPoint, WorldRect}; -use api::units::{DevicePixelScale, DevicePoint, PictureRect}; +use api::units::{DevicePixelScale, DevicePoint, PictureRect, TexelRect}; use crate::batch::{resolve_image, get_buffer_kind}; use crate::gpu_cache::GpuCache; use crate::gpu_types::{ZBufferId, ZBufferIdGenerator}; use crate::internal_types::TextureSource; use crate::picture::{ResolvedSurfaceTexture, TileCacheInstance, TileSurface}; use crate::prim_store::DeferredResolve; use crate::renderer::ImageBufferKind; use crate::resource_cache::{ImageRequest, ResourceCache}; @@ -111,25 +111,25 @@ pub struct ExternalSurfaceDescriptor { } /// Information about a plane in a YUV surface. #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] pub struct YuvPlaneDescriptor { pub texture: TextureSource, pub texture_layer: i32, - pub uv_rect: DeviceRect, + pub uv_rect: TexelRect, } impl YuvPlaneDescriptor { fn invalid() -> Self { YuvPlaneDescriptor { texture: TextureSource::Invalid, texture_layer: 0, - uv_rect: DeviceRect::zero(), + uv_rect: TexelRect::invalid(), } } } /// An ExternalSurfaceDescriptor that has had image keys /// resolved to texture handles. This contains all the /// information that the compositor step in renderer /// needs to know. @@ -486,17 +486,17 @@ impl CompositeState { ); if cache_item.texture_id != TextureSource::Invalid { valid_plane_count += 1; *plane = YuvPlaneDescriptor { texture: cache_item.texture_id, texture_layer: cache_item.texture_layer, - uv_rect: cache_item.uv_rect.to_f32(), + uv_rect: cache_item.uv_rect.into(), }; } } // Check if there are valid images added for each YUV plane if valid_plane_count < required_plane_count { warn!("Warnings: skip a YUV compositor surface, found {}/{} valid images", valid_plane_count,
--- a/gfx/wr/webrender/src/device/gl.rs +++ b/gfx/wr/webrender/src/device/gl.rs @@ -481,31 +481,42 @@ impl<T> Drop for VBO<T> { } #[cfg_attr(feature = "replay", derive(Clone))] #[derive(Debug)] pub struct ExternalTexture { id: gl::GLuint, target: gl::GLuint, swizzle: Swizzle, + uv_rect: TexelRect, } impl ExternalTexture { - pub fn new(id: u32, target: TextureTarget, swizzle: Swizzle) -> Self { + pub fn new( + id: u32, + target: TextureTarget, + swizzle: Swizzle, + uv_rect: TexelRect, + ) -> Self { ExternalTexture { id, target: get_gl_target(target), swizzle, + uv_rect, } } #[cfg(feature = "replay")] pub fn internal_id(&self) -> gl::GLuint { self.id } + + pub fn get_uv_rect(&self) -> TexelRect { + self.uv_rect + } } bitflags! { #[derive(Default)] pub struct TextureFlags: u32 { /// This texture corresponds to one of the shared texture caches. const IS_SHARED_TEXTURE_CACHE = 1 << 0; } @@ -613,16 +624,23 @@ impl Texture { } #[cfg(feature = "replay")] pub fn into_external(mut self) -> ExternalTexture { let ext = ExternalTexture { id: self.id, target: self.target, swizzle: Swizzle::default(), + // TODO(gw): Support custom UV rect for external textures during captures + uv_rect: TexelRect::new( + 0.0, + 0.0, + self.size.width as f32, + self.size.height as f32, + ), }; self.id = 0; // don't complain, moved out ext } } impl Drop for Texture { fn drop(&mut self) {
--- a/gfx/wr/webrender/src/gpu_types.rs +++ b/gfx/wr/webrender/src/gpu_types.rs @@ -250,17 +250,17 @@ pub struct CompositeInstance { // Packed into a single vec4 (aParams) z_id: f32, yuv_color_space: f32, // YuvColorSpace yuv_format: f32, // YuvFormat yuv_rescale: f32, // UV rectangles (pixel space) for color / yuv texture planes - uv_rects: [DeviceRect; 3], + uv_rects: [TexelRect; 3], // Texture array layers for color / yuv texture planes texture_layers: [f32; 3], } impl CompositeInstance { pub fn new( rect: DeviceRect, @@ -273,29 +273,29 @@ impl CompositeInstance { rect, clip_rect, color, z_id: z_id.0 as f32, yuv_color_space: 0.0, yuv_format: 0.0, yuv_rescale: 0.0, texture_layers: [layer, 0.0, 0.0], - uv_rects: [DeviceRect::zero(); 3], + uv_rects: [TexelRect::invalid(); 3], } } pub fn new_yuv( rect: DeviceRect, clip_rect: DeviceRect, z_id: ZBufferId, yuv_color_space: YuvColorSpace, yuv_format: YuvFormat, yuv_rescale: f32, texture_layers: [f32; 3], - uv_rects: [DeviceRect; 3], + uv_rects: [TexelRect; 3], ) -> Self { CompositeInstance { rect, clip_rect, color: PremultipliedColorF::WHITE, z_id: z_id.0 as f32, yuv_color_space: pack_as_float(yuv_color_space as u32), yuv_format: pack_as_float(yuv_format as u32),
--- a/gfx/wr/webrender/src/renderer.rs +++ b/gfx/wr/webrender/src/renderer.rs @@ -1248,16 +1248,36 @@ impl TextureResolver { Some((&self.texture_cache_map[&index], swizzle)) } TextureSource::RenderTaskCache(saved_index, swizzle) => { Some((&self.saved_targets[saved_index.0], swizzle)) } } } + // Retrieve the deferred / resolved UV rect if an external texture, otherwise + // return the default supplied UV rect. + fn get_uv_rect( + &self, + source: &TextureSource, + default_value: TexelRect, + ) -> TexelRect { + match source { + TextureSource::External(ref external_image) => { + let texture = self.external_images + .get(&(external_image.id, external_image.channel_index)) + .expect("BUG: External image should be resolved by now"); + texture.get_uv_rect() + } + _ => { + default_value + } + } + } + fn report_memory(&self) -> MemoryReport { let mut report = MemoryReport::default(); // We're reporting GPU memory rather than heap-allocations, so we don't // use size_of_op. for t in self.texture_cache_map.values() { report.texture_cache_textures += t.size_in_bytes(); } @@ -4368,34 +4388,41 @@ impl Renderer { VertexArrayKind::Composite, ¤t_textures, stats, ); instances.clear(); } current_textures = textures; + // When the texture is an external texture, the UV rect is not known when + // the external surface descriptor is created, because external textures + // are not resolved until the lock() callback is invoked at the start of + // the frame render. To handle this, query the texture resolver for the + // UV rect if it's an external texture, otherwise use the default UV rect. + let uv_rects = [ + self.texture_resolver.get_uv_rect(&textures.colors[0], surface.yuv_planes[0].uv_rect), + self.texture_resolver.get_uv_rect(&textures.colors[1], surface.yuv_planes[1].uv_rect), + self.texture_resolver.get_uv_rect(&textures.colors[2], surface.yuv_planes[2].uv_rect), + ]; + // Create the instance and add to current batch let instance = CompositeInstance::new_yuv( surface.device_rect, surface.clip_rect, surface.z_id, surface.yuv_color_space, surface.yuv_format, surface.yuv_rescale, [ surface.yuv_planes[0].texture_layer as f32, surface.yuv_planes[1].texture_layer as f32, surface.yuv_planes[2].texture_layer as f32, ], - [ - surface.yuv_planes[0].uv_rect, - surface.yuv_planes[1].uv_rect, - surface.yuv_planes[2].uv_rect, - ], + uv_rects, ); instances.push(instance); } // Flush the last batch if !instances.is_empty() { self.draw_instanced_batch( &instances, @@ -5144,27 +5171,37 @@ impl Renderer { }; // In order to produce the handle, the external image handler may call into // the GL context and change some states. self.device.reset_state(); let texture = match image.source { ExternalImageSource::NativeTexture(texture_id) => { - ExternalTexture::new(texture_id, texture_target, Swizzle::default()) + ExternalTexture::new( + texture_id, + texture_target, + Swizzle::default(), + image.uv, + ) } ExternalImageSource::Invalid => { warn!("Invalid ext-image"); debug!( "For ext_id:{:?}, channel:{}.", ext_image.id, ext_image.channel_index ); // Just use 0 as the gl handle for this failed case. - ExternalTexture::new(0, texture_target, Swizzle::default()) + ExternalTexture::new( + 0, + texture_target, + Swizzle::default(), + image.uv, + ) } ExternalImageSource::RawData(_) => { panic!("Raw external data is not expected for deferred resolves!"); } }; self.texture_resolver .external_images
--- a/gfx/wr/webrender_api/src/units.rs +++ b/gfx/wr/webrender_api/src/units.rs @@ -165,16 +165,25 @@ impl TexelRect { pub fn invalid() -> Self { TexelRect { uv0: DevicePoint::new(-1.0, -1.0), uv1: DevicePoint::new(-1.0, -1.0), } } } +impl Into<TexelRect> for DeviceIntRect { + fn into(self) -> TexelRect { + TexelRect { + uv0: self.min().to_f32(), + uv1: self.max().to_f32(), + } + } +} + const MAX_AU_FLOAT: f32 = 1.0e6; pub trait AuHelpers<T> { fn from_au(data: T) -> Self; fn to_au(&self) -> T; } impl AuHelpers<LayoutSizeAu> for LayoutSize {