Bug 1517910 - Update webrender to commit bcc2cde64756e0d90dd8614f923ad74694bcd84c (WR PR #3475). r=kats
authorWR Updater Bot <graphics-team@mozilla.staktrace.com>
Sat, 05 Jan 2019 21:12:56 +0000
changeset 452644 98265e1b64a42c9b4be55e88cc96296a62f3d53b
parent 452641 e54046e15abef84a2cd6ec0fc4825a6cf15878ac
child 452645 e0e9c4425d132aa2798ec8686562befbcf1e59a1
push id35321
push useraciure@mozilla.com
push dateSun, 06 Jan 2019 09:48:33 +0000
treeherdermozilla-central@9aa94abacb92 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1517910
milestone66.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 1517910 - Update webrender to commit bcc2cde64756e0d90dd8614f923ad74694bcd84c (WR PR #3475). r=kats https://github.com/servo/webrender/pull/3475 Differential Revision: https://phabricator.services.mozilla.com/D15786
gfx/webrender_bindings/revision.txt
gfx/wr/webrender/src/gpu_cache.rs
gfx/wr/webrender/src/internal_types.rs
gfx/wr/webrender/src/render_backend.rs
gfx/wr/webrender/src/renderer.rs
--- a/gfx/webrender_bindings/revision.txt
+++ b/gfx/webrender_bindings/revision.txt
@@ -1,1 +1,1 @@
-48b6b15e68c935a07d66a36f7ca6dd7438924d57
+bcc2cde64756e0d90dd8614f923ad74694bcd84c
--- a/gfx/wr/webrender/src/gpu_cache.rs
+++ b/gfx/wr/webrender/src/gpu_cache.rs
@@ -299,16 +299,19 @@ pub struct GpuCacheDebugChunk {
 }
 
 #[must_use]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct GpuCacheUpdateList {
     /// The frame current update list was generated from.
     pub frame_id: FrameId,
+    /// Whether the texture should be cleared before updates
+    /// are applied.
+    pub clear: bool,
     /// The current height of the texture. The render thread
     /// should resize the texture if required.
     pub height: i32,
     /// List of updates to apply.
     pub updates: Vec<GpuCacheUpdate>,
     /// A flat list of GPU blocks that are pending upload
     /// to GPU memory.
     pub blocks: Vec<GpuBlockData>,
@@ -664,37 +667,42 @@ pub struct GpuCache {
     frame_id: FrameId,
     /// CPU-side texture allocator.
     texture: Texture,
     /// Number of blocks requested this frame that don't
     /// need to be re-uploaded.
     saved_block_count: usize,
     /// The current debug flags for the system.
     debug_flags: DebugFlags,
+    /// Whether there is a pending clear to send with the
+    /// next update.
+    pending_clear: bool,
 }
 
 impl GpuCache {
     pub fn new() -> Self {
         let debug_flags = DebugFlags::empty();
         GpuCache {
             frame_id: FrameId::INVALID,
             texture: Texture::new(Epoch(0), debug_flags),
             saved_block_count: 0,
             debug_flags,
+            pending_clear: false,
         }
     }
 
-    /// Drops everything in the GPU cache. Paired by the caller with a message
-    /// to the renderer thread telling it to do the same.
+    /// Drops everything in the GPU cache. Must not be called once gpu cache entries
+    /// for the next frame have already been requested.
     pub fn clear(&mut self) {
         assert!(self.texture.updates.is_empty(), "Clearing with pending updates");
         let mut next_base_epoch = self.texture.max_epoch;
         next_base_epoch.next();
         self.texture = Texture::new(next_base_epoch, self.debug_flags);
         self.saved_block_count = 0;
+        self.pending_clear = true;
     }
 
     /// Begin a new frame.
     pub fn begin_frame(&mut self, frame_id: FrameId) {
         debug_assert!(self.texture.pending_blocks.is_empty());
         self.frame_id = frame_id;
         self.texture.evict_old_blocks(self.frame_id);
         self.saved_block_count = 0;
@@ -800,18 +808,21 @@ impl GpuCache {
     /// should blow the cache away and rebuild it.
     pub fn should_reclaim_memory(&self) -> bool {
         self.texture.reached_reclaim_threshold
             .map_or(false, |t| t.elapsed() > Duration::from_secs(RECLAIM_DELAY_S))
     }
 
     /// Extract the pending updates from the cache.
     pub fn extract_updates(&mut self) -> GpuCacheUpdateList {
+        let clear = self.pending_clear;
+        self.pending_clear = false;
         GpuCacheUpdateList {
             frame_id: self.frame_id,
+            clear,
             height: self.texture.height,
             debug_commands: mem::replace(&mut self.texture.debug_commands, Vec::new()),
             updates: mem::replace(&mut self.texture.updates, Vec::new()),
             blocks: mem::replace(&mut self.texture.pending_blocks, Vec::new()),
         }
     }
 
     /// Sets the current debug flags for the system.
--- a/gfx/wr/webrender/src/internal_types.rs
+++ b/gfx/wr/webrender/src/internal_types.rs
@@ -290,17 +290,16 @@ pub enum DebugOutput {
 }
 
 #[allow(dead_code)]
 pub enum ResultMsg {
     DebugCommand(DebugCommand),
     DebugOutput(DebugOutput),
     RefreshShader(PathBuf),
     UpdateGpuCache(GpuCacheUpdateList),
-    ClearGpuCache,
     UpdateResources {
         updates: TextureUpdateList,
         memory_pressure: bool,
     },
     PublishPipelineInfo(PipelineInfo),
     PublishDocument(
         DocumentId,
         RenderedDocument,
--- a/gfx/wr/webrender/src/render_backend.rs
+++ b/gfx/wr/webrender/src/render_backend.rs
@@ -1003,17 +1003,17 @@ impl RenderBackend {
                 // We may want to look into something less extreme, but on the other hand this
                 // should only be used in situations where are running low enough on memory
                 // that we risk crashing if we don't do something about it.
                 // The advantage of clearing the cache completely is that it gets rid of any
                 // remaining fragmentation that could have persisted if we kept around the most
                 // recently used resources.
                 self.resource_cache.clear(ClearCache::all());
 
-                self.clear_gpu_cache();
+                self.gpu_cache.clear();
 
                 let pending_update = self.resource_cache.pending_updates();
                 let msg = ResultMsg::UpdateResources {
                     updates: pending_update,
                     memory_pressure: true,
                 };
                 self.result_tx.send(msg).unwrap();
                 self.notifier.wake_up();
@@ -1116,17 +1116,17 @@ impl RenderBackend {
                         // thread when the debug display is enabled, and thus
                         // enabling it when the cache is partially populated will
                         // give the renderer an incomplete view of the world.
                         // And since we might as well drop all the debugging state
                         // from the renderer when we disable the debug display,
                         // we just clear the cache on toggle.
                         let changed = self.debug_flags ^ flags;
                         if changed.contains(DebugFlags::GPU_CACHE_DBG) {
-                            self.clear_gpu_cache();
+                            self.gpu_cache.clear();
                         }
                         self.debug_flags = flags;
 
                         ResultMsg::DebugCommand(option)
                     }
                     _ => ResultMsg::DebugCommand(option),
                 };
                 self.result_tx.send(msg).unwrap();
@@ -1176,17 +1176,17 @@ impl RenderBackend {
             &mut txn.resource_updates,
             &mut profile_counters.resources,
         );
 
         // If we've been above the threshold for reclaiming GPU cache memory for
         // long enough, drop it and rebuild it. This needs to be done before any
         // updates for this frame are made.
         if self.gpu_cache.should_reclaim_memory() {
-            self.clear_gpu_cache();
+            self.gpu_cache.clear();
         }
 
         for scene_msg in transaction_msg.scene_ops.drain(..) {
             let _timer = profile_counters.total_time.timer();
             self.process_scene_msg(
                 document_id,
                 scene_msg,
                 *frame_counter,
@@ -1543,23 +1543,16 @@ impl RenderBackend {
 
         report += self.resource_cache.report_memory(op);
 
         // Send a message to report memory on the scene-builder thread, which
         // will add its report to this one and send the result back to the original
         // thread waiting on the request.
         self.scene_tx.send(SceneBuilderRequest::ReportMemory(report, tx)).unwrap();
     }
-
-    /// Drops everything in the GPU cache. Must not be called once gpu cache entries
-    /// for the next frame have already been requested.
-    fn clear_gpu_cache(&mut self) {
-        self.gpu_cache.clear();
-        self.result_tx.send(ResultMsg::ClearGpuCache).unwrap();
-    }
 }
 
 fn get_blob_image_updates(updates: &[ResourceUpdate]) -> Vec<BlobImageKey> {
     let mut requests = Vec::new();
     for update in updates {
         match *update {
             ResourceUpdate::AddBlobImage(ref img) => {
                 requests.push(img.key);
--- a/gfx/wr/webrender/src/renderer.rs
+++ b/gfx/wr/webrender/src/renderer.rs
@@ -1081,16 +1081,17 @@ impl GpuCacheTexture {
                 return;
             }
         }
 
         // Take the old texture, if any.
         let blit_source = self.texture.take();
 
         // Create the new texture.
+        assert!(height >= 2, "Height is too small for ANGLE");
         let new_size = DeviceIntSize::new(MAX_VERTEX_TEXTURE_WIDTH as _, height);
         let rt_info = Some(RenderTargetInfo { has_depth: false });
         let mut texture = device.create_texture(
             TextureTarget::Default,
             ImageFormat::RGBAF32,
             new_size.width,
             new_size.height,
             TextureFilter::Nearest,
@@ -2115,18 +2116,24 @@ impl Renderer {
                     //               frees Texture X.
                     //            3) bad stuff happens.
 
                     //TODO: associate `document_id` with target window
                     self.pending_texture_updates.push(texture_update_list);
                     self.backend_profile_counters = profile_counters;
                 }
                 ResultMsg::UpdateGpuCache(mut list) => {
+                    if list.clear {
+                        self.pending_gpu_cache_clear = true;
+                    }
                     #[cfg(feature = "debug_renderer")]
                     {
+                        if list.clear {
+                            self.gpu_cache_debug_chunks = Vec::new();
+                        }
                         for cmd in mem::replace(&mut list.debug_commands, Vec::new()) {
                             match cmd {
                                 GpuCacheDebugCmd::Alloc(chunk) => {
                                     let row = chunk.address.v as usize;
                                     if row >= self.gpu_cache_debug_chunks.len() {
                                         self.gpu_cache_debug_chunks.resize(row + 1, Vec::new());
                                     }
                                     self.gpu_cache_debug_chunks[row].push(chunk);
@@ -2137,23 +2144,16 @@ impl Renderer {
                                         .position(|x| x.address == address).unwrap();
                                     chunks.remove(pos);
                                 },
                             }
                         }
                     }
                     self.pending_gpu_cache_updates.push(list);
                 }
-                ResultMsg::ClearGpuCache => {
-                    #[cfg(feature = "debug_renderer")]
-                    {
-                        self.gpu_cache_debug_chunks = Vec::new();
-                    }
-                    self.pending_gpu_cache_clear = true;
-                }
                 ResultMsg::UpdateResources {
                     updates,
                     memory_pressure,
                 } => {
                     self.pending_texture_updates.push(updates);
                     self.device.begin_frame();
 
                     self.update_texture_cache();
@@ -2736,16 +2736,17 @@ impl Renderer {
         let _gm = self.gpu_profile.start_marker("gpu cache update");
 
         // For an artificial stress test of GPU cache resizing,
         // always pass an extra update list with at least one block in it.
         let gpu_cache_height = self.gpu_cache_texture.get_height();
         if gpu_cache_height != 0 && GPU_CACHE_RESIZE_TEST {
             self.pending_gpu_cache_updates.push(GpuCacheUpdateList {
                 frame_id: FrameId::INVALID,
+                clear: false,
                 height: gpu_cache_height,
                 blocks: vec![[1f32; 4].into()],
                 updates: Vec::new(),
                 debug_commands: Vec::new(),
             });
         }
 
         let (updated_blocks, max_requested_height) = self
@@ -3836,16 +3837,17 @@ impl Renderer {
         }
 
         let handler = self.external_image_handler
             .as_mut()
             .expect("Found external image, but no handler set!");
 
         let mut list = GpuCacheUpdateList {
             frame_id: FrameId::INVALID,
+            clear: false,
             height: self.gpu_cache_texture.get_height(),
             blocks: Vec::new(),
             updates: Vec::new(),
             debug_commands: Vec::new(),
         };
 
         for deferred_resolve in deferred_resolves {
             self.gpu_profile.place_marker("deferred resolve");