Bug 1540581 - P9. Add R16G16 type and update of P010/P016 resource update. r=sotaro
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 11 Apr 2019 12:37:23 +0000
changeset 469137 89bd3aee893e45ed10f08bf1d558d4dd03a13d06
parent 469136 d2b6cc14a04347d2b69015c0dc08bb7718863ba3
child 469138 cf9c8ae660ddbc7711844d943097b7ad53edc2d6
push id35856
push usercsabou@mozilla.com
push dateFri, 12 Apr 2019 03:19:48 +0000
treeherdermozilla-central@940684cd1065 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1540581
milestone68.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
Bug 1540581 - P9. Add R16G16 type and update of P010/P016 resource update. r=sotaro Differential Revision: https://phabricator.services.mozilla.com/D26464
gfx/2d/Types.h
gfx/layers/d3d11/TextureD3D11.cpp
gfx/webrender_bindings/WebRenderTypes.h
gfx/wr/webrender/src/device/gl.rs
gfx/wr/webrender_api/src/image.rs
gfx/wr/wrench/src/yaml_frame_reader.rs
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -58,16 +58,17 @@ enum class SurfaceFormat : int8_t {
   // endianness.
   R5G6B5_UINT16,  // 0bRRRRRGGGGGGBBBBB
 
   // This one is a single-byte, so endianness isn't an issue.
   A8,
   A16,
 
   R8G8,
+  R16G16,
 
   // These ones are their own special cases.
   YUV,
   NV12,  // YUV 4:2:0 image with a plane of 8 bit Y samples followed by
          // an interleaved U/V plane containing 8 bit 2x2 subsampled
          // colour difference samples.
   P016,  // Similar to NV12, but with 16 bits plane values
   P010,  // Identical to P016 but the 6 least significant bits are 0.
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -1027,25 +1027,30 @@ void DXGITextureHostD3D11::PushResourceU
     case gfx::SurfaceFormat::B8G8R8X8: {
       MOZ_ASSERT(aImageKeys.length() == 1);
 
       wr::ImageDescriptor descriptor(mSize, GetFormat());
       auto bufferType = wr::WrExternalImageBufferType::TextureExternalHandle;
       (aResources.*method)(aImageKeys[0], descriptor, aExtID, bufferType, 0);
       break;
     }
+    case gfx::SurfaceFormat::P010:
+    case gfx::SurfaceFormat::P016:
     case gfx::SurfaceFormat::NV12: {
       MOZ_ASSERT(aImageKeys.length() == 2);
       MOZ_ASSERT(mSize.width % 2 == 0);
       MOZ_ASSERT(mSize.height % 2 == 0);
 
-      // For now, no software decoder can output 10/12 bits NV12 images
-      // So forcing A8 is okay.
-      wr::ImageDescriptor descriptor0(mSize, gfx::SurfaceFormat::A8);
-      wr::ImageDescriptor descriptor1(mSize / 2, gfx::SurfaceFormat::R8G8);
+      wr::ImageDescriptor descriptor0(mSize, mFormat == gfx::SurfaceFormat::NV12
+                                                 ? gfx::SurfaceFormat::A8
+                                                 : gfx::SurfaceFormat::A16);
+      wr::ImageDescriptor descriptor1(mSize / 2,
+                                      mFormat == gfx::SurfaceFormat::NV12
+                                          ? gfx::SurfaceFormat::R8G8
+                                          : gfx::SurfaceFormat::R16G16);
       auto bufferType = wr::WrExternalImageBufferType::TextureExternalHandle;
       (aResources.*method)(aImageKeys[0], descriptor0, aExtID, bufferType, 0);
       (aResources.*method)(aImageKeys[1], descriptor1, aExtID, bufferType, 1);
       break;
     }
     default: {
       MOZ_ASSERT_UNREACHABLE("unexpected to be called");
     }
@@ -1061,31 +1066,25 @@ void DXGITextureHostD3D11::PushDisplayIt
     case gfx::SurfaceFormat::R8G8B8A8:
     case gfx::SurfaceFormat::B8G8R8A8:
     case gfx::SurfaceFormat::B8G8R8X8: {
       MOZ_ASSERT(aImageKeys.length() == 1);
       aBuilder.PushImage(aBounds, aClip, true, aFilter, aImageKeys[0],
                          !(mFlags & TextureFlags::NON_PREMULTIPLIED));
       break;
     }
+    case gfx::SurfaceFormat::P010:
+    case gfx::SurfaceFormat::P016:
     case gfx::SurfaceFormat::NV12: {
       MOZ_ASSERT(aImageKeys.length() == 2);
-      aBuilder.PushNV12Image(aBounds, aClip, true, aImageKeys[0], aImageKeys[1],
-                             wr::ColorDepth::Color8,
-                             wr::ToWrYuvColorSpace(YUVColorSpace::BT601),
-                             aFilter);
-      break;
-    }
-    case gfx::SurfaceFormat::P010:
-    case gfx::SurfaceFormat::P016: {
-      MOZ_ASSERT(aImageKeys.length() == 2);
-      aBuilder.PushNV12Image(aBounds, aClip, true, aImageKeys[0], aImageKeys[1],
-                             wr::ColorDepth::Color16,
-                             wr::ToWrYuvColorSpace(YUVColorSpace::BT601),
-                             aFilter);
+      aBuilder.PushNV12Image(
+          aBounds, aClip, true, aImageKeys[0], aImageKeys[1],
+          GetFormat() == gfx::SurfaceFormat::NV12 ? wr::ColorDepth::Color8
+                                                  : wr::ColorDepth::Color16,
+          wr::ToWrYuvColorSpace(YUVColorSpace::BT601), aFilter);
       break;
     }
     default: {
       MOZ_ASSERT_UNREACHABLE("unexpected to be called");
     }
   }
 }
 
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -155,16 +155,18 @@ inline Maybe<wr::ImageFormat> SurfaceFor
     case gfx::SurfaceFormat::B8G8R8A8:
       return Some(wr::ImageFormat::BGRA8);
     case gfx::SurfaceFormat::A8:
       return Some(wr::ImageFormat::R8);
     case gfx::SurfaceFormat::A16:
       return Some(wr::ImageFormat::R16);
     case gfx::SurfaceFormat::R8G8:
       return Some(wr::ImageFormat::RG8);
+    case gfx::SurfaceFormat::R16G16:
+      return Some(wr::ImageFormat::RG16);
     case gfx::SurfaceFormat::UNKNOWN:
     default:
       return Nothing();
   }
 }
 
 inline gfx::SurfaceFormat ImageFormatToSurfaceFormat(ImageFormat aFormat) {
   switch (aFormat) {
--- a/gfx/wr/webrender/src/device/gl.rs
+++ b/gfx/wr/webrender/src/device/gl.rs
@@ -3141,28 +3141,34 @@ impl Device {
                 external: gl::RGBA_INTEGER,
                 pixel_type: gl::INT,
             },
             ImageFormat::RG8 => FormatDesc {
                 internal: gl::RG8,
                 external: gl::RG,
                 pixel_type: gl::UNSIGNED_BYTE,
             },
+            ImageFormat::RG16 => FormatDesc {
+                internal: gl::RG16,
+                external: gl::RG,
+                pixel_type: gl::UNSIGNED_SHORT,
+            },
         }
     }
 
     /// Returns a GL format matching an ImageFormat suitable for a renderbuffer.
     fn matching_renderbuffer_format(&self, format: ImageFormat) -> gl::GLenum {
         match format {
             ImageFormat::R8 => gl::R8,
             ImageFormat::R16 => gl::R16UI,
             // BGRA8 is not usable with renderbuffers so use RGBA8.
             ImageFormat::BGRA8 => gl::RGBA8,
             ImageFormat::RGBAF32 => gl::RGBA32F,
             ImageFormat::RG8 => gl::RG8,
+            ImageFormat::RG16 => gl::RG16,
             ImageFormat::RGBAI32 => gl::RGBA32I,
             ImageFormat::RGBA8 => gl::RGBA8,
         }
     }
 
     /// Generates a memory report for the resources managed by the device layer.
     pub fn report_memory(&self) -> MemoryReport {
         let mut report = MemoryReport::default();
@@ -3356,16 +3362,17 @@ impl<'a, T> TextureUploader<'a, T> {
 impl<'a> UploadTarget<'a> {
     fn update_impl(&mut self, chunk: UploadChunk) {
         let (gl_format, bpp, data_type) = match self.texture.format {
             ImageFormat::R8 => (gl::RED, 1, gl::UNSIGNED_BYTE),
             ImageFormat::R16 => (gl::RED, 2, gl::UNSIGNED_SHORT),
             ImageFormat::BGRA8 => (self.bgra_format, 4, gl::UNSIGNED_BYTE),
             ImageFormat::RGBA8 => (gl::RGBA, 4, gl::UNSIGNED_BYTE),
             ImageFormat::RG8 => (gl::RG, 2, gl::UNSIGNED_BYTE),
+            ImageFormat::RG16 => (gl::RG, 4, gl::UNSIGNED_SHORT),
             ImageFormat::RGBAF32 => (gl::RGBA, 16, gl::FLOAT),
             ImageFormat::RGBAI32 => (gl::RGBA_INTEGER, 16, gl::INT),
         };
 
         let row_length = match chunk.stride {
             Some(value) => value / bpp,
             None => self.texture.size.width,
         };
--- a/gfx/wr/webrender_api/src/image.rs
+++ b/gfx/wr/webrender_api/src/image.rs
@@ -108,31 +108,36 @@ pub enum ImageFormat {
     R16 = 2,
     /// Four channels, byte storage.
     BGRA8 = 3,
     /// Four channels, float storage.
     RGBAF32 = 4,
     /// Two-channels, byte storage. Similar to `R8`, this just means
     /// "two channels" rather than "red and green".
     RG8 = 5,
+    /// Two-channels, byte storage. Similar to `R16`, this just means
+    /// "two channels" rather than "red and green".
+    RG16 = 6,
+
     /// Four channels, signed integer storage.
-    RGBAI32 = 6,
+    RGBAI32 = 7,
     /// Four channels, byte storage.
-    RGBA8 = 7,
+    RGBA8 = 8,
 }
 
 impl ImageFormat {
     /// Returns the number of bytes per pixel for the given format.
     pub fn bytes_per_pixel(self) -> i32 {
         match self {
             ImageFormat::R8 => 1,
             ImageFormat::R16 => 2,
             ImageFormat::BGRA8 => 4,
             ImageFormat::RGBAF32 => 16,
             ImageFormat::RG8 => 2,
+            ImageFormat::RG16 => 4,
             ImageFormat::RGBAI32 => 16,
             ImageFormat::RGBA8 => 4,
         }
     }
 }
 
 /// Specifies the color depth of an image. Currently only used for YUV images.
 #[repr(u8)]
--- a/gfx/wr/wrench/src/yaml_frame_reader.rs
+++ b/gfx/wr/wrench/src/yaml_frame_reader.rs
@@ -186,16 +186,17 @@ fn is_image_opaque(format: ImageFormat, 
                 if bytes[i * 4 + 3] != 255 {
                     is_opaque = false;
                     break;
                 }
             }
             is_opaque
         }
         ImageFormat::RG8 => true,
+        ImageFormat::RG16 => true,
         ImageFormat::R8 => false,
         ImageFormat::R16 => false,
         ImageFormat::RGBAF32 |
         ImageFormat::RGBAI32 => unreachable!(),
     }
 }
 
 pub struct YamlFrameReader {