Bug 1406507. Move the displaylist ByteBuf into a Vec instead of copying. r=kats
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 30 Nov 2017 18:14:41 -0500
changeset 394464 bdfdf0fa188910163d001272cc535f1b497431a1
parent 394463 4a31601120ad6fecef1b3f1836cf15124eaf86ba
child 394465 492835cff9328bf33dd11eda60eb486f67f1aec6
push id97881
push userjmuizelaar@mozilla.com
push dateThu, 30 Nov 2017 23:15:19 +0000
treeherdermozilla-inbound@bdfdf0fa1889 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1406507
milestone59.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 1406507. Move the displaylist ByteBuf into a Vec instead of copying. r=kats This eliminates a copy of the displaylist on the compositor thread. DONTBUILD
gfx/layers/wr/AsyncImagePipelineManager.cpp
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/WebRenderTypes.cpp
gfx/webrender_bindings/WebRenderTypes.h
gfx/webrender_bindings/moz.build
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/layers/wr/AsyncImagePipelineManager.cpp
+++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp
@@ -348,17 +348,17 @@ AsyncImagePipelineManager::ApplyAsyncIma
     }
     builder.PopStackingContext();
 
     wr::BuiltDisplayList dl;
     wr::LayoutSize builderContentSize;
     builder.Finalize(builderContentSize, dl);
     mApi->SetDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f), epoch, LayerSize(pipeline->mScBounds.Width(), pipeline->mScBounds.Height()),
                          pipelineId, builderContentSize,
-                         dl.dl_desc, dl.dl.inner.data, dl.dl.inner.length,
+                         dl.dl_desc, dl.dl,
                          resourceUpdates);
   }
 }
 
 void
 AsyncImagePipelineManager::HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
 {
   if (mDestroyed) {
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -109,16 +109,17 @@ gecko_profiler_register_thread(const cha
 
 void
 gecko_profiler_unregister_thread()
 {
   PROFILER_UNREGISTER_THREAD();
 }
 
 namespace mozilla {
+
 namespace layers {
 
 using namespace mozilla::gfx;
 
 class MOZ_STACK_CLASS AutoWebRenderBridgeParentAsyncMessageSender
 {
 public:
   explicit AutoWebRenderBridgeParentAsyncMessageSender(WebRenderBridgeParent* aWebRenderBridgeParent,
@@ -593,28 +594,31 @@ WebRenderBridgeParent::RecvSetDisplayLis
   mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
   ProcessWebRenderParentCommands(aCommands);
 
   wr::ResourceUpdateQueue resources;
   if (!UpdateResources(aResourceUpdates, aSmallShmems, aLargeShmems, resources)) {
     return IPC_FAIL(this, "Failed to deserialize resource updates");
   }
 
+
+  wr::Vec_u8 dlData(Move(dl));
+
   // If id namespaces do not match, it means the command is obsolete, probably
   // because the tab just moved to a new window.
   // In that case do not send the commands to webrender.
   if (mIdNamespace == aIdNamespace) {
     if (mWidget) {
       LayoutDeviceIntSize size = mWidget->GetClientSize();
       mApi->SetWindowParameters(size);
     }
     gfx::Color clearColor(0.f, 0.f, 0.f, 0.f);
     mApi->SetDisplayList(clearColor, wr::NewEpoch(wrEpoch), LayerSize(aSize.width, aSize.height),
                         mPipelineId, aContentSize,
-                        dlDesc, dl.mData, dl.mLen,
+                        dlDesc, dlData,
                         resources);
 
     ScheduleGenerateFrame();
 
     if (ShouldParentObserveEpoch()) {
       mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
     }
   }
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -260,29 +260,27 @@ WebRenderAPI::GenerateFrame(const nsTArr
 
 void
 WebRenderAPI::SetDisplayList(gfx::Color aBgColor,
                              Epoch aEpoch,
                              mozilla::LayerSize aViewportSize,
                              wr::WrPipelineId pipeline_id,
                              const LayoutSize& content_size,
                              wr::BuiltDisplayListDescriptor dl_descriptor,
-                             uint8_t *dl_data,
-                             size_t dl_size,
+                             wr::Vec_u8& dl_data,
                              ResourceUpdateQueue& aResources)
 {
   wr_api_set_display_list(mDocHandle,
                           ToColorF(aBgColor),
                           aEpoch,
                           aViewportSize.width, aViewportSize.height,
                           pipeline_id,
                           content_size,
                           dl_descriptor,
-                          dl_data,
-                          dl_size,
+                          &dl_data.inner,
                           aResources.Raw());
 }
 
 void
 WebRenderAPI::ClearDisplayList(Epoch aEpoch, wr::WrPipelineId pipeline_id)
 {
   wr_api_clear_display_list(mDocHandle, aEpoch, pipeline_id);
 }
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -156,18 +156,17 @@ public:
   void SetWindowParameters(LayoutDeviceIntSize size);
 
   void SetDisplayList(gfx::Color aBgColor,
                       Epoch aEpoch,
                       mozilla::LayerSize aViewportSize,
                       wr::WrPipelineId pipeline_id,
                       const wr::LayoutSize& content_size,
                       wr::BuiltDisplayListDescriptor dl_descriptor,
-                      uint8_t *dl_data,
-                      size_t dl_size,
+                      wr::Vec_u8& dl_data,
                       ResourceUpdateQueue& aResources);
 
   void ClearDisplayList(Epoch aEpoch, wr::WrPipelineId pipeline_id);
 
   void SetRootPipeline(wr::PipelineId aPipeline);
 
   void RemovePipeline(wr::PipelineId aPipeline);
 
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/WebRenderTypes.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "WebRenderTypes.h"
+
+#include "mozilla/ipc/ByteBuf.h"
+
+namespace mozilla {
+namespace wr {
+
+Vec_u8::Vec_u8(mozilla::ipc::ByteBuf&& aSrc) {
+  inner.data = aSrc.mData;
+  inner.length = aSrc.mLen;
+  inner.capacity = aSrc.mCapacity;
+  aSrc.mData = nullptr;
+  aSrc.mLen = 0;
+  aSrc.mCapacity = 0;
+}
+
+} // namespace wr
+} // namespace mozilla
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -16,16 +16,21 @@
 #include "mozilla/PodOperations.h"
 #include "mozilla/Range.h"
 #include "mozilla/Variant.h"
 #include "Units.h"
 #include "RoundedRect.h"
 #include "nsStyleConsts.h"
 
 namespace mozilla {
+
+namespace ipc {
+class ByteBuf;
+} // namespace ipc
+
 namespace wr {
 
 typedef wr::WrWindowId WindowId;
 typedef wr::WrPipelineId PipelineId;
 typedef wr::WrImageKey ImageKey;
 typedef wr::WrFontKey FontKey;
 typedef wr::WrFontInstanceKey FontInstanceKey;
 typedef wr::WrEpoch Epoch;
@@ -571,16 +576,18 @@ struct Vec_u8 {
     SetEmpty();
   }
   Vec_u8(Vec_u8&) = delete;
   Vec_u8(Vec_u8&& src) {
     inner = src.inner;
     src.SetEmpty();
   }
 
+  explicit Vec_u8(mozilla::ipc::ByteBuf&& aSrc);
+
   Vec_u8&
   operator=(Vec_u8&& src) {
     inner = src.inner;
     src.SetEmpty();
     return *this;
   }
 
   wr::WrVecU8
--- a/gfx/webrender_bindings/moz.build
+++ b/gfx/webrender_bindings/moz.build
@@ -24,16 +24,17 @@ UNIFIED_SOURCES += [
     'Moz2DImageRenderer.cpp',
     'RenderBufferTextureHost.cpp',
     'RendererOGL.cpp',
     'RenderSharedSurfaceTextureHost.cpp',
     'RenderTextureHost.cpp',
     'RenderTextureHostOGL.cpp',
     'RenderThread.cpp',
     'WebRenderAPI.cpp',
+    'WebRenderTypes.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     EXPORTS.mozilla.webrender += [
         'RenderMacIOSurfaceTextureHostOGL.h',
     ]
     UNIFIED_SOURCES += [
         'RenderMacIOSurfaceTextureHostOGL.cpp',
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -953,33 +953,29 @@ pub unsafe extern "C" fn wr_api_set_disp
     dh: &mut DocumentHandle,
     color: ColorF,
     epoch: WrEpoch,
     viewport_width: f32,
     viewport_height: f32,
     pipeline_id: WrPipelineId,
     content_size: LayoutSize,
     dl_descriptor: BuiltDisplayListDescriptor,
-    dl_data: *mut u8,
-    dl_size: usize,
+    dl_data: &mut WrVecU8,
     resources: &mut ResourceUpdates,
 ) {
     let resource_updates = mem::replace(resources, ResourceUpdates::new());
 
     let color = if color.a == 0.0 { None } else { Some(color) };
 
     // See the documentation of set_display_list in api.rs. I don't think
     // it makes a difference in gecko at the moment(until APZ is figured out)
     // but I suppose it is a good default.
     let preserve_frame_state = true;
 
-    let dl_slice = make_slice(dl_data, dl_size);
-    let mut dl_vec = Vec::new();
-    // XXX: see if we can get rid of the copy here
-    dl_vec.extend_from_slice(dl_slice);
+    let dl_vec = dl_data.flush_into_vec();
     let dl = BuiltDisplayList::from_data(dl_vec, dl_descriptor);
 
     dh.api.set_display_list(
         dh.document_id,
         epoch,
         color,
         LayoutSize::new(viewport_width, viewport_height),
         (pipeline_id, content_size, dl),
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1063,18 +1063,17 @@ WR_INLINE
 void wr_api_set_display_list(DocumentHandle *aDh,
                              ColorF aColor,
                              WrEpoch aEpoch,
                              float aViewportWidth,
                              float aViewportHeight,
                              WrPipelineId aPipelineId,
                              LayoutSize aContentSize,
                              BuiltDisplayListDescriptor aDlDescriptor,
-                             uint8_t *aDlData,
-                             size_t aDlSize,
+                             WrVecU8 *aDlData,
                              ResourceUpdates *aResources)
 WR_FUNC;
 
 WR_INLINE
 void wr_api_set_root_pipeline(DocumentHandle *aDh,
                               WrPipelineId aPipelineId)
 WR_FUNC;