Bug 1570442 - Flip upside down recorded frames right side up on non-ANGLE configurations r=kvark
authorBarret Rennie <barret@brennie.ca>
Mon, 12 Aug 2019 18:54:55 +0000
changeset 487500 dccb73a9ee2b1ae7e890eac4d18769bfa8f2857b
parent 487499 019c1f042cb592d3614833fdc3f072b3a5ac9d93
child 487501 c62d636a6ac91622023a16823e2ff43e19c1ac2a
push id36425
push userbtara@mozilla.com
push dateTue, 13 Aug 2019 09:54:32 +0000
treeherdermozilla-central@e29ba984dad2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskvark
bugs1570442
milestone70.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 1570442 - Flip upside down recorded frames right side up on non-ANGLE configurations r=kvark Frames captured by the composition recorder on non-ANGLE configurations were previously written upside down to disk. We now flip them right side up when mapping them into memory. Differential Revision: https://phabricator.services.mozilla.com/D40113
gfx/wr/webrender/src/screen_capture.rs
--- a/gfx/wr/webrender/src/screen_capture.rs
+++ b/gfx/wr/webrender/src/screen_capture.rs
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Screen capture infrastructure for the Gecko Profiler and Composition Recorder.
 
 use std::collections::HashMap;
 
 use api::{ImageFormat, TextureTarget};
 use api::units::*;
+use gleam::gl::GlType;
 
 use crate::device::{Device, PBO, DrawTarget, ReadTarget, Texture, TextureFilter};
 use crate::internal_types::RenderTargetInfo;
 use crate::renderer::Renderer;
 use crate::util::round_up_to_multiple;
 
 /// A handle to a screenshot that is being asynchronously captured and scaled.
 #[repr(C)]
@@ -323,24 +324,26 @@ impl AsyncScreenshotGrabber {
             screenshot_size,
             buffer_stride,
             image_format,
         } = match self.awaiting_readback.remove(&handle) {
             Some(screenshot) => screenshot,
             None => return false,
         };
 
+        let gl_type = device.gl().get_type();
+
         let success = if let Some(bound_pbo) = device.map_pbo_for_readback(&pbo) {
             let src_buffer = &bound_pbo.data;
             let src_stride = buffer_stride;
             let src_width =
                 screenshot_size.width as usize * image_format.bytes_per_pixel() as usize;
 
-            for (src_slice, dst_slice) in src_buffer
-                .chunks(src_stride)
+            for (src_slice, dst_slice) in self
+                .iter_src_buffer_chunked(gl_type, src_buffer, src_stride)
                 .zip(dst_buffer.chunks_mut(dst_stride))
                 .take(screenshot_size.height as usize)
             {
                 dst_slice[.. src_width].copy_from_slice(&src_slice[.. src_width]);
             }
 
             true
         } else {
@@ -349,16 +352,38 @@ impl AsyncScreenshotGrabber {
 
         match self.mode {
             AsyncScreenshotGrabberMode::ProfilerScreenshots => self.available_pbos.push(pbo),
             AsyncScreenshotGrabberMode::CompositionRecorder => device.delete_pbo(pbo),
         }
 
         success
     }
+
+    fn iter_src_buffer_chunked<'a>(
+        &self,
+        gl_type: GlType,
+        src_buffer: &'a [u8],
+        src_stride: usize,
+    ) -> Box<dyn Iterator<Item = &'a [u8]> + 'a> {
+        use AsyncScreenshotGrabberMode::*;
+
+        let is_angle = cfg!(windows) && gl_type == GlType::Gles;
+
+        if self.mode == CompositionRecorder && !is_angle {
+            // This is a non-ANGLE configuration. in this case, the recorded frames were captured
+            // upside down, so we have to flip them right side up.
+            Box::new(src_buffer.chunks(src_stride).rev())
+        } else {
+            // This is either an ANGLE configuration in the `CompositionRecorder` mode or a
+            // non-ANGLE configuration in the `ProfilerScreenshots` mode. In either case, the
+            // captured frames are right-side up.
+            Box::new(src_buffer.chunks(src_stride))
+        }
+    }
 }
 
 // Screen-capture specific Renderer impls.
 impl Renderer {
     /// Record a frame for the Composition Recorder.
     ///
     /// The returned handle can be passed to `map_recorded_frame` to copy it into
     /// a buffer.