[scenic] Factor sysmem wrapper code out of DisplayManager

Change-Id: I65341fb5d72a9fef070544b0a8e07109cff73ba7
diff --git a/garnet/bin/ui/scenic/app.cc b/garnet/bin/ui/scenic/app.cc
index aa9c3b4..29954c1 100644
--- a/garnet/bin/ui/scenic/app.cc
+++ b/garnet/bin/ui/scenic/app.cc
@@ -99,7 +99,7 @@
                                             gfx::DefaultFrameScheduler::kInitialUpdateDuration),
       scenic_.inspect_node()->CreateChild("FrameScheduler"));
 
-  engine_.emplace(frame_scheduler_, &display_manager_, escher_->GetWeakPtr(),
+  engine_.emplace(frame_scheduler_, &sysmem_, &display_manager_, escher_->GetWeakPtr(),
                   scenic_.inspect_node()->CreateChild("Engine"));
   frame_scheduler_->SetFrameRenderer(engine_->GetWeakPtr());
 
diff --git a/garnet/bin/ui/scenic/app.h b/garnet/bin/ui/scenic/app.h
index 76794ee..880958d 100644
--- a/garnet/bin/ui/scenic/app.h
+++ b/garnet/bin/ui/scenic/app.h
@@ -27,6 +27,7 @@
   void InitializeServices(escher::EscherUniquePtr escher, gfx::Display* display);
 
   async::Executor executor_;
+  gfx::Sysmem sysmem_;
   gfx::DisplayManager display_manager_;
   escher::EscherUniquePtr escher_;
   std::shared_ptr<gfx::FrameScheduler> frame_scheduler_;
diff --git a/garnet/lib/ui/gfx/BUILD.gn b/garnet/lib/ui/gfx/BUILD.gn
index 2e17a1a..cde793a 100644
--- a/garnet/lib/ui/gfx/BUILD.gn
+++ b/garnet/lib/ui/gfx/BUILD.gn
@@ -185,6 +185,8 @@
     "swapchain/swapchain.h",
     "swapchain/swapchain_factory.cc",
     "swapchain/swapchain_factory.h",
+    "sysmem.cc",
+    "sysmem.h",
   ]
 
   public_configs = [
diff --git a/garnet/lib/ui/gfx/displays/display_manager.cc b/garnet/lib/ui/gfx/displays/display_manager.cc
index 78b3de8..95cd278a 100644
--- a/garnet/lib/ui/gfx/displays/display_manager.cc
+++ b/garnet/lib/ui/gfx/displays/display_manager.cc
@@ -4,26 +4,14 @@
 
 #include "garnet/lib/ui/gfx/displays/display_manager.h"
 
+#include <fuchsia/ui/scenic/cpp/fidl.h>
 #include <lib/async/default.h>
-#include <lib/fdio/directory.h>
-#include <zircon/syscalls.h>
 
-#include <trace/event.h>
-
-#include "fuchsia/ui/scenic/cpp/fidl.h"
+#include "src/lib/fxl/logging.h"
 
 namespace scenic_impl {
 namespace gfx {
 
-DisplayManager::DisplayManager() {
-  zx_status_t status = fdio_service_connect("/svc/fuchsia.sysmem.Allocator",
-                                            sysmem_allocator_.NewRequest().TakeChannel().release());
-  if (status != ZX_OK) {
-    sysmem_allocator_.Unbind();
-    FXL_LOG(ERROR) << "Unable to connect to sysmem: " << status;
-  }
-}
-
 DisplayManager::~DisplayManager() {
   if (wait_.object() != ZX_HANDLE_INVALID) {
     wait_.Cancel();
@@ -194,28 +182,6 @@
   }
 }
 
-fuchsia::sysmem::BufferCollectionTokenSyncPtr DisplayManager::CreateBufferCollection() {
-  fuchsia::sysmem::BufferCollectionTokenSyncPtr local_token;
-  zx_status_t status = sysmem_allocator_->AllocateSharedCollection(local_token.NewRequest());
-  if (status != ZX_OK) {
-    FXL_LOG(ERROR) << "CreateBufferCollection failed " << status;
-    return nullptr;
-  }
-  return local_token;
-}
-
-fuchsia::sysmem::BufferCollectionSyncPtr DisplayManager::GetCollectionFromToken(
-    fuchsia::sysmem::BufferCollectionTokenSyncPtr token) {
-  fuchsia::sysmem::BufferCollectionSyncPtr collection;
-  zx_status_t status =
-      sysmem_allocator_->BindSharedCollection(std::move(token), collection.NewRequest());
-  if (status != ZX_OK) {
-    FXL_LOG(ERROR) << "BindSharedCollection failed " << status;
-    return nullptr;
-  }
-  return collection;
-}
-
 uint64_t DisplayManager::ImportBufferCollection(
     fuchsia::sysmem::BufferCollectionTokenSyncPtr token) {
   uint64_t buffer_collection_id = next_buffer_collection_id_++;
diff --git a/garnet/lib/ui/gfx/displays/display_manager.h b/garnet/lib/ui/gfx/displays/display_manager.h
index d831470..206a6b7 100644
--- a/garnet/lib/ui/gfx/displays/display_manager.h
+++ b/garnet/lib/ui/gfx/displays/display_manager.h
@@ -5,17 +5,17 @@
 #ifndef GARNET_LIB_UI_GFX_DISPLAYS_DISPLAY_MANAGER_H_
 #define GARNET_LIB_UI_GFX_DISPLAYS_DISPLAY_MANAGER_H_
 
+#include <fuchsia/hardware/display/cpp/fidl.h>
+#include <fuchsia/sysmem/cpp/fidl.h>
+#include <lib/async/cpp/wait.h>
 #include <lib/fit/function.h>
 #include <lib/zx/event.h>
 #include <zircon/pixelformat.h>
 
 #include <cstdint>
 
-#include "fuchsia/hardware/display/cpp/fidl.h"
-#include "fuchsia/sysmem/cpp/fidl.h"
 #include "garnet/lib/ui/gfx/displays/display.h"
 #include "garnet/lib/ui/gfx/displays/display_controller_watcher.h"
-#include "lib/async/cpp/wait.h"
 #include "src/lib/fxl/macros.h"
 
 namespace scenic_impl {
@@ -24,7 +24,7 @@
 // Provides support for enumerating available displays.
 class DisplayManager {
  public:
-  DisplayManager();
+   DisplayManager() = default;
   ~DisplayManager();
 
   using VsyncCallback =
@@ -43,10 +43,6 @@
   // Sets the config which will be used for all imported images.
   void SetImageConfig(int32_t width, int32_t height, zx_pixel_format_t format);
 
-  fuchsia::sysmem::BufferCollectionTokenSyncPtr CreateBufferCollection();
-  fuchsia::sysmem::BufferCollectionSyncPtr GetCollectionFromToken(
-      fuchsia::sysmem::BufferCollectionTokenSyncPtr token);
-
   // Import a buffer collection token into the display controller so the
   // constraints will be set on it. Returns an id that can be used to refer to
   // the collection.
@@ -80,8 +76,6 @@
   // Enables display vsync events and sets the callback which handles them.
   bool EnableVsync(VsyncCallback vsync_cb);
 
-  bool is_initialized() { return sysmem_allocator_.is_bound(); }
-
  private:
   void OnAsync(async_dispatcher_t* dispatcher, async::WaitBase* self, zx_status_t status,
                const zx_packet_signal_t* signal);
@@ -97,8 +91,6 @@
   fidl::InterfacePtr<fuchsia::hardware::display::Controller> dc_event_dispatcher_;
   zx_handle_t dc_channel_;  // display_controller_ owns the zx::channel
 
-  fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator_;
-
   uint64_t next_event_id_ = fuchsia::hardware::display::invalidId + 1;
   uint64_t next_buffer_collection_id_ = fuchsia::hardware::display::invalidId + 1;
 
diff --git a/garnet/lib/ui/gfx/engine/engine.cc b/garnet/lib/ui/gfx/engine/engine.cc
index c800d14..05ff2ee 100644
--- a/garnet/lib/ui/gfx/engine/engine.cc
+++ b/garnet/lib/ui/gfx/engine/engine.cc
@@ -30,10 +30,11 @@
 namespace scenic_impl {
 namespace gfx {
 
-Engine::Engine(const std::shared_ptr<FrameScheduler>& frame_scheduler,
+Engine::Engine(const std::shared_ptr<FrameScheduler>& frame_scheduler, Sysmem* sysmem,
                DisplayManager* display_manager, escher::EscherWeakPtr weak_escher,
                inspect_deprecated::Node inspect_node)
-    : display_manager_(display_manager),
+    : sysmem_(sysmem),
+      display_manager_(display_manager),
       escher_(std::move(weak_escher)),
       engine_renderer_(std::make_unique<EngineRenderer>(
           escher_, escher_->device()->caps().GetMatchingDepthStencilFormat(
@@ -51,11 +52,12 @@
   InitializeInspectObjects();
 }
 
-Engine::Engine(const std::shared_ptr<FrameScheduler>& frame_scheduler,
+Engine::Engine(const std::shared_ptr<FrameScheduler>& frame_scheduler, Sysmem* sysmem,
                DisplayManager* display_manager,
                std::unique_ptr<escher::ReleaseFenceSignaller> release_fence_signaller,
                escher::EscherWeakPtr weak_escher)
-    : display_manager_(display_manager),
+    : sysmem_(sysmem),
+      display_manager_(display_manager),
       escher_(std::move(weak_escher)),
       release_fence_signaller_(std::move(release_fence_signaller)),
       frame_scheduler_(frame_scheduler),
diff --git a/garnet/lib/ui/gfx/engine/engine.h b/garnet/lib/ui/gfx/engine/engine.h
index 3dcd652..25107e4 100644
--- a/garnet/lib/ui/gfx/engine/engine.h
+++ b/garnet/lib/ui/gfx/engine/engine.h
@@ -24,6 +24,7 @@
 #include "garnet/lib/ui/gfx/id.h"
 #include "garnet/lib/ui/gfx/resources/import.h"
 #include "garnet/lib/ui/gfx/resources/nodes/scene.h"
+#include "garnet/lib/ui/gfx/sysmem.h"
 #include "garnet/lib/ui/scenic/event_reporter.h"
 #include "src/ui/lib/escher/escher.h"
 #include "src/ui/lib/escher/flib/release_fence_signaller.h"
@@ -54,11 +55,13 @@
 // producing output when prompted through the FrameRenderer interface.
 class Engine : public FrameRenderer {
  public:
-  Engine(const std::shared_ptr<FrameScheduler>& frame_scheduler, DisplayManager* display_manager,
-         escher::EscherWeakPtr escher, inspect_deprecated::Node inspect_node);
+  Engine(const std::shared_ptr<FrameScheduler>& frame_scheduler, Sysmem* sysmem,
+         DisplayManager* display_manager, escher::EscherWeakPtr escher,
+         inspect_deprecated::Node inspect_node);
 
   // Only used for testing.
-  Engine(const std::shared_ptr<FrameScheduler>& frame_scheduler, DisplayManager* display_manager,
+  Engine(const std::shared_ptr<FrameScheduler>& frame_scheduler, Sysmem* sysmem,
+         DisplayManager* display_manager,
          std::unique_ptr<escher::ReleaseFenceSignaller> release_fence_signaller,
          escher::EscherWeakPtr escher);
 
@@ -86,6 +89,7 @@
                           escher_rounded_rect_factory(),
                           release_fence_signaller(),
                           frame_scheduler_,
+                          sysmem_,
                           display_manager_,
                           scene_graph(),
                           &resource_linker_,
@@ -136,6 +140,7 @@
   void UpdateMetrics(Node* node, const ::fuchsia::ui::gfx::Metrics& parent_metrics,
                      std::vector<Node*>* updated_nodes);
 
+  Sysmem* const sysmem_;
   DisplayManager* const display_manager_;
   const escher::EscherWeakPtr escher_;
 
diff --git a/garnet/lib/ui/gfx/engine/gfx_command_applier.cc b/garnet/lib/ui/gfx/engine/gfx_command_applier.cc
index 5443176..81b32ee 100644
--- a/garnet/lib/ui/gfx/engine/gfx_command_applier.cc
+++ b/garnet/lib/ui/gfx/engine/gfx_command_applier.cc
@@ -1494,7 +1494,8 @@
 
   return fxl::AdoptRef(new DisplayCompositor(
       session, id, session->session_context().scene_graph, display,
-      SwapchainFactory::CreateDisplaySwapchain(display, session->session_context().display_manager,
+      SwapchainFactory::CreateDisplaySwapchain(display, session->session_context().sysmem,
+                                               session->session_context().display_manager,
                                                session->session_context().escher)));
 }
 
diff --git a/garnet/lib/ui/gfx/engine/session_context.h b/garnet/lib/ui/gfx/engine/session_context.h
index 222b93d..52f5d5e4 100644
--- a/garnet/lib/ui/gfx/engine/session_context.h
+++ b/garnet/lib/ui/gfx/engine/session_context.h
@@ -17,6 +17,7 @@
 class SessionManager;
 class FrameScheduler;
 class UpdateScheduler;
+class Sysmem;
 class DisplayManager;
 class SceneGraph;
 class ResourceLinker;
@@ -40,6 +41,7 @@
   escher::RoundedRectFactory* escher_rounded_rect_factory = nullptr;
   escher::ReleaseFenceSignaller* release_fence_signaller = nullptr;
   std::shared_ptr<FrameScheduler> frame_scheduler;
+  Sysmem* sysmem = nullptr;
   DisplayManager* display_manager = nullptr;
   SceneGraphWeakPtr scene_graph;
   ResourceLinker* resource_linker = nullptr;
diff --git a/garnet/lib/ui/gfx/gfx_system.h b/garnet/lib/ui/gfx/gfx_system.h
index 5ef5971..1ad1c8f3 100644
--- a/garnet/lib/ui/gfx/gfx_system.h
+++ b/garnet/lib/ui/gfx/gfx_system.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "garnet/lib/ui/gfx/displays/display_manager.h"
 #include "garnet/lib/ui/gfx/engine/engine.h"
 #include "garnet/lib/ui/gfx/engine/gfx_command_applier.h"
 #include "garnet/lib/ui/gfx/resources/compositor/compositor.h"
diff --git a/garnet/lib/ui/gfx/swapchain/display_swapchain.cc b/garnet/lib/ui/gfx/swapchain/display_swapchain.cc
index 2cd7fd8..134b935 100644
--- a/garnet/lib/ui/gfx/swapchain/display_swapchain.cc
+++ b/garnet/lib/ui/gfx/swapchain/display_swapchain.cc
@@ -4,15 +4,16 @@
 
 #include "garnet/lib/ui/gfx/swapchain/display_swapchain.h"
 
+#include <fuchsia/sysmem/cpp/fidl.h>
 #include <lib/async/default.h>
 
 #include <fbl/auto_call.h>
 #include <trace/event.h>
 
-#include "fuchsia/sysmem/cpp/fidl.h"
 #include "garnet/lib/ui/gfx/displays/display.h"
 #include "garnet/lib/ui/gfx/displays/display_manager.h"
 #include "garnet/lib/ui/gfx/engine/frame_timings.h"
+#include "garnet/lib/ui/gfx/sysmem.h"
 #include "src/ui/lib/escher/escher.h"
 #include "src/ui/lib/escher/flib/fence.h"
 #include "src/ui/lib/escher/impl/naive_image.h"
@@ -70,10 +71,11 @@
 
 }  // namespace
 
-DisplaySwapchain::DisplaySwapchain(DisplayManager* display_manager, Display* display,
-                                   escher::Escher* escher)
-    : escher_(escher), display_manager_(display_manager), display_(display) {
+DisplaySwapchain::DisplaySwapchain(Sysmem* sysmem, DisplayManager* display_manager,
+                                   Display* display, escher::Escher* escher)
+    : escher_(escher), sysmem_(sysmem), display_manager_(display_manager), display_(display) {
   FXL_DCHECK(display);
+  FXL_DCHECK(sysmem);
 
   if (escher_) {
     device_ = escher_->vk_device();
@@ -147,8 +149,7 @@
   display_manager_->SetImageConfig(width_in_px, height_in_px, pixel_format);
   for (uint32_t i = 0; i < kSwapchainImageCount; i++) {
     // Create all the tokens.
-    fuchsia::sysmem::BufferCollectionTokenSyncPtr local_token =
-        display_manager_->CreateBufferCollection();
+    fuchsia::sysmem::BufferCollectionTokenSyncPtr local_token = sysmem_->CreateBufferCollection();
     if (!local_token) {
       FXL_LOG(ERROR) << "Sysmem tokens couldn't be allocated";
       return false;
@@ -212,7 +213,7 @@
     // fails, and to ensure everything's allocated before trying to import it
     // into another process.
     fuchsia::sysmem::BufferCollectionSyncPtr sysmem_collection =
-        display_manager_->GetCollectionFromToken(std::move(local_token));
+        sysmem_->GetCollectionFromToken(std::move(local_token));
     if (!sysmem_collection) {
       return false;
     }
diff --git a/garnet/lib/ui/gfx/swapchain/display_swapchain.h b/garnet/lib/ui/gfx/swapchain/display_swapchain.h
index 398fb48..e9dddf6 100644
--- a/garnet/lib/ui/gfx/swapchain/display_swapchain.h
+++ b/garnet/lib/ui/gfx/swapchain/display_swapchain.h
@@ -23,13 +23,15 @@
 
 class Display;
 class DisplayManager;
+class Sysmem;
 
 // DisplaySwapchain implements the Swapchain interface by using a Vulkan
 // swapchain to present images to a physical display using the Zircon
 // display controller API.
 class DisplaySwapchain : public Swapchain {
  public:
-  DisplaySwapchain(DisplayManager* display_manager, Display* display, escher::Escher* escher);
+  DisplaySwapchain(Sysmem* sysmem, DisplayManager* display_manager, Display* display,
+                   escher::Escher* escher);
   ~DisplaySwapchain() override;
 
   // Callback to call on every vsync. Arguments are:
@@ -90,6 +92,7 @@
   // through its (valid) pointer.
   escher::Escher* const escher_ = nullptr;
 
+  Sysmem* sysmem_;
   DisplayManager* display_manager_;
   Display* const display_;
 
diff --git a/garnet/lib/ui/gfx/swapchain/swapchain_factory.cc b/garnet/lib/ui/gfx/swapchain/swapchain_factory.cc
index d401869..8a4a868 100644
--- a/garnet/lib/ui/gfx/swapchain/swapchain_factory.cc
+++ b/garnet/lib/ui/gfx/swapchain/swapchain_factory.cc
@@ -10,9 +10,9 @@
 namespace gfx {
 
 std::unique_ptr<DisplaySwapchain> SwapchainFactory::CreateDisplaySwapchain(
-    Display* display, DisplayManager* display_manager, escher::Escher* escher) {
+    Display* display, Sysmem* sysmem, DisplayManager* display_manager, escher::Escher* escher) {
   FXL_DCHECK(!display->is_claimed());
-  return std::make_unique<DisplaySwapchain>(display_manager, display, escher);
+  return std::make_unique<DisplaySwapchain>(sysmem, display_manager, display, escher);
 }
 
 }  // namespace gfx
diff --git a/garnet/lib/ui/gfx/swapchain/swapchain_factory.h b/garnet/lib/ui/gfx/swapchain/swapchain_factory.h
index 14b259c..479b1c7 100644
--- a/garnet/lib/ui/gfx/swapchain/swapchain_factory.h
+++ b/garnet/lib/ui/gfx/swapchain/swapchain_factory.h
@@ -15,12 +15,13 @@
 namespace gfx {
 
 class DisplayManager;
+class Sysmem;
 
 class SwapchainFactory {
  public:
   // Create a swapchain for the specified display.  The display must not
   // already be claimed by another swapchain.
-  static std::unique_ptr<DisplaySwapchain> CreateDisplaySwapchain(Display* display,
+  static std::unique_ptr<DisplaySwapchain> CreateDisplaySwapchain(Display* display, Sysmem* sysmem,
                                                                   DisplayManager* display_manager,
                                                                   escher::Escher* escher);
 
diff --git a/garnet/lib/ui/gfx/sysmem.cc b/garnet/lib/ui/gfx/sysmem.cc
new file mode 100644
index 0000000..d6ee5f4
--- /dev/null
+++ b/garnet/lib/ui/gfx/sysmem.cc
@@ -0,0 +1,46 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "garnet/lib/ui/gfx/sysmem.h"
+
+#include <lib/fdio/directory.h>
+
+#include "src/lib/fxl/logging.h"
+
+namespace scenic_impl {
+namespace gfx {
+
+Sysmem::Sysmem() {
+  zx_status_t status = fdio_service_connect("/svc/fuchsia.sysmem.Allocator",
+                                            sysmem_allocator_.NewRequest().TakeChannel().release());
+  if (status != ZX_OK) {
+    sysmem_allocator_.Unbind();
+    FXL_LOG(ERROR) << "Unable to connect to sysmem: " << status;
+  }
+}
+
+fuchsia::sysmem::BufferCollectionTokenSyncPtr Sysmem::CreateBufferCollection() {
+  fuchsia::sysmem::BufferCollectionTokenSyncPtr local_token;
+  zx_status_t status = sysmem_allocator_->AllocateSharedCollection(local_token.NewRequest());
+  if (status != ZX_OK) {
+    FXL_LOG(ERROR) << "CreateBufferCollection failed " << status;
+    return nullptr;
+  }
+  return local_token;
+}
+
+fuchsia::sysmem::BufferCollectionSyncPtr Sysmem::GetCollectionFromToken(
+    fuchsia::sysmem::BufferCollectionTokenSyncPtr token) {
+  fuchsia::sysmem::BufferCollectionSyncPtr collection;
+  zx_status_t status =
+      sysmem_allocator_->BindSharedCollection(std::move(token), collection.NewRequest());
+  if (status != ZX_OK) {
+    FXL_LOG(ERROR) << "BindSharedCollection failed " << status;
+    return nullptr;
+  }
+  return collection;
+}
+
+}  // namespace gfx
+}  // namespace scenic_impl
diff --git a/garnet/lib/ui/gfx/sysmem.h b/garnet/lib/ui/gfx/sysmem.h
new file mode 100644
index 0000000..e72e5c3
--- /dev/null
+++ b/garnet/lib/ui/gfx/sysmem.h
@@ -0,0 +1,37 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GARNET_LIB_UI_GFX_SYSMEM_H_
+#define GARNET_LIB_UI_GFX_SYSMEM_H_
+
+#include <fuchsia/sysmem/cpp/fidl.h>
+
+#include "src/lib/fxl/macros.h"
+
+namespace scenic_impl {
+namespace gfx {
+
+// Wrapper class for the Sysmem Allocator service. Initializes and owns a connection to
+// fuchsia::sysmem::Allocator and exposes methods for creating and importing buffer collections.
+class Sysmem {
+ public:
+  Sysmem();
+  ~Sysmem() = default;
+
+  bool is_initialized() { return sysmem_allocator_.is_bound(); }
+
+  fuchsia::sysmem::BufferCollectionTokenSyncPtr CreateBufferCollection();
+  fuchsia::sysmem::BufferCollectionSyncPtr GetCollectionFromToken(
+      fuchsia::sysmem::BufferCollectionTokenSyncPtr token);
+
+ private:
+  fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator_;
+
+  FXL_DISALLOW_COPY_AND_ASSIGN(Sysmem);
+};
+
+}  // namespace gfx
+}  // namespace scenic_impl
+
+#endif  // GARNET_LIB_UI_GFX_SYSMEM_H_
diff --git a/garnet/lib/ui/gfx/tests/gfx_test.cc b/garnet/lib/ui/gfx/tests/gfx_test.cc
index 6715b09..3b8277b 100644
--- a/garnet/lib/ui/gfx/tests/gfx_test.cc
+++ b/garnet/lib/ui/gfx/tests/gfx_test.cc
@@ -29,8 +29,8 @@
       display_.get(),
       std::make_unique<FramePredictor>(gfx::DefaultFrameScheduler::kInitialRenderDuration,
                                        gfx::DefaultFrameScheduler::kInitialUpdateDuration));
-  engine_ = std::make_unique<Engine>(frame_scheduler_,
-                                     /*display_manager*/ nullptr, std::move(signaller),
+  engine_ = std::make_unique<Engine>(frame_scheduler_, /* sysmem */ nullptr,
+                                     /* display_manager */ nullptr, std::move(signaller),
                                      escher::EscherWeakPtr());
   frame_scheduler_->SetFrameRenderer(engine_->GetWeakPtr());
   auto system =
diff --git a/garnet/lib/ui/gfx/tests/hittest_global_unittest.cc b/garnet/lib/ui/gfx/tests/hittest_global_unittest.cc
index 92c1f9c..d19bce3 100644
--- a/garnet/lib/ui/gfx/tests/hittest_global_unittest.cc
+++ b/garnet/lib/ui/gfx/tests/hittest_global_unittest.cc
@@ -2,22 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <memory>
-#include <string>
-#include <vector>
-
 #include <fuchsia/ui/gfx/cpp/fidl.h>
 #include <fuchsia/ui/input/cpp/fidl.h>
 #include <fuchsia/ui/scenic/cpp/fidl.h>
 #include <fuchsia/ui/views/cpp/fidl.h>
 #include <lib/fostr/fidl/fuchsia/ui/gfx/formatting.h>
 
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "garnet/lib/ui/gfx/displays/display_manager.h"
 #include "garnet/lib/ui/gfx/engine/engine.h"
 #include "garnet/lib/ui/gfx/engine/hit.h"
 #include "garnet/lib/ui/gfx/engine/hit_tester.h"
 #include "garnet/lib/ui/gfx/resources/compositor/compositor.h"
 #include "garnet/lib/ui/gfx/resources/compositor/layer_stack.h"
+#include "garnet/lib/ui/gfx/sysmem.h"
 #include "garnet/lib/ui/gfx/tests/mocks.h"
 #include "garnet/lib/ui/scenic/event_reporter.h"
 #include "garnet/lib/ui/scenic/util/error_reporter.h"
@@ -93,10 +94,11 @@
   constexpr float display_height = 768;
 
   DisplayManager display_manager;
+  Sysmem sysmem;
   display_manager.SetDefaultDisplayForTests(std::make_unique<Display>(
       /*id*/ 0, /*px-width*/ display_width, /*px-height*/ display_height));
   std::unique_ptr<Engine> engine = std::make_unique<Engine>(
-      /*frame_scheduler*/ nullptr, &display_manager,
+      /*frame_scheduler*/ nullptr, &sysmem, &display_manager,
       /*release fence signaller*/ nullptr, escher::EscherWeakPtr());
 
   // Create our tokens for View/ViewHolder creation.
@@ -214,10 +216,11 @@
   constexpr float display_height = 768;
 
   DisplayManager display_manager;
+  Sysmem sysmem;
   display_manager.SetDefaultDisplayForTests(std::make_unique<Display>(
       /*id*/ 0, /*px-width*/ display_width, /*px-height*/ display_height));
   std::unique_ptr<Engine> engine = std::make_unique<Engine>(
-      /*frame_scheduler*/ nullptr, &display_manager,
+      /*frame_scheduler*/ nullptr, &sysmem, &display_manager,
       /*release fence signaller*/ nullptr, escher::EscherWeakPtr());
 
   // Create our tokens for View/ViewHolder creation.
@@ -363,10 +366,11 @@
   constexpr float display_height = 768;
 
   DisplayManager display_manager;
+  Sysmem sysmem;
   display_manager.SetDefaultDisplayForTests(std::make_unique<Display>(
       /*id*/ 0, /*px-width*/ display_width, /*px-height*/ display_height));
   std::unique_ptr<Engine> engine = std::make_unique<Engine>(
-      /*frame_scheduler*/ nullptr, &display_manager,
+      /*frame_scheduler*/ nullptr, &sysmem, &display_manager,
       /*release fence signaller*/ nullptr, escher::EscherWeakPtr());
 
   // Create our tokens for View/ViewHolder creation.
@@ -498,10 +502,11 @@
 // hittable nodes across all sessions.
 TEST_F(MultiSessionHitTestTest, GlobalHits) {
   DisplayManager display_manager;
+  Sysmem sysmem;
   display_manager.SetDefaultDisplayForTests(std::make_unique<Display>(
       /*id*/ 0, /*px-width*/ 9, /*px-height*/ 9));
   std::unique_ptr<Engine> engine = std::make_unique<Engine>(
-      /*frame_scheduler*/ nullptr, &display_manager,
+      /*frame_scheduler*/ nullptr, &sysmem, &display_manager,
       /*release fence signaller*/ nullptr, escher::EscherWeakPtr());
 
   // Create our tokens for View/ViewHolder creation.
diff --git a/garnet/lib/ui/gfx/tests/session_handler_test.cc b/garnet/lib/ui/gfx/tests/session_handler_test.cc
index 66a688b..0015988 100644
--- a/garnet/lib/ui/gfx/tests/session_handler_test.cc
+++ b/garnet/lib/ui/gfx/tests/session_handler_test.cc
@@ -62,6 +62,7 @@
 
 void SessionHandlerTest::InitializeEngine() {
   command_buffer_sequencer_ = std::make_unique<escher::impl::CommandBufferSequencer>();
+  sysmem_ = std::make_unique<Sysmem>();
 
   auto mock_release_fence_signaller =
       std::make_unique<ReleaseFenceSignallerForTest>(command_buffer_sequencer_.get());
@@ -71,7 +72,7 @@
       std::make_unique<FramePredictor>(DefaultFrameScheduler::kInitialRenderDuration,
                                        DefaultFrameScheduler::kInitialUpdateDuration));
   engine_ =
-      std::make_unique<Engine>(frame_scheduler_, display_manager_.get(),
+      std::make_unique<Engine>(frame_scheduler_, sysmem_.get(), display_manager_.get(),
                                std::move(mock_release_fence_signaller), escher::EscherWeakPtr());
   frame_scheduler_->SetFrameRenderer(engine_->GetWeakPtr());
   frame_scheduler_->AddSessionUpdater(weak_factory_.GetWeakPtr());
diff --git a/garnet/lib/ui/gfx/tests/session_handler_test.h b/garnet/lib/ui/gfx/tests/session_handler_test.h
index db1f577..55be854 100644
--- a/garnet/lib/ui/gfx/tests/session_handler_test.h
+++ b/garnet/lib/ui/gfx/tests/session_handler_test.h
@@ -10,6 +10,7 @@
 #include "garnet/lib/ui/gfx/displays/display_manager.h"
 #include "garnet/lib/ui/gfx/engine/engine.h"
 #include "garnet/lib/ui/gfx/engine/session.h"
+#include "garnet/lib/ui/gfx/sysmem.h"
 #include "garnet/lib/ui/gfx/tests/error_reporting_test.h"
 #include "garnet/lib/ui/gfx/tests/mocks.h"
 #include "garnet/lib/ui/scenic/event_reporter.h"
@@ -59,6 +60,7 @@
   std::unique_ptr<escher::impl::CommandBufferSequencer> command_buffer_sequencer_;
   std::unique_ptr<Engine> engine_;
   std::shared_ptr<FrameScheduler> frame_scheduler_;
+  std::unique_ptr<Sysmem> sysmem_;
   std::unique_ptr<DisplayManager> display_manager_;
   std::unique_ptr<scenic_impl::Session> scenic_session_;
   CommandDispatcherUniquePtr command_dispatcher_;
diff --git a/garnet/lib/ui/gfx/tests/session_test.cc b/garnet/lib/ui/gfx/tests/session_test.cc
index 5dceebe..036b0bf 100644
--- a/garnet/lib/ui/gfx/tests/session_test.cc
+++ b/garnet/lib/ui/gfx/tests/session_test.cc
@@ -14,7 +14,7 @@
 
 void SessionTest::SetUp() {
   ErrorReportingTest::SetUp();
-
+  sysmem_ = std::make_unique<Sysmem>();
   display_manager_ = std::make_unique<DisplayManager>();
   display_manager_->SetDefaultDisplayForTests(std::make_unique<Display>(
       /*id*/ 0, /*px-width*/ 0, /*px-height*/ 0));
@@ -47,6 +47,7 @@
       nullptr,                 // escher::RoundedRectFactory*
       nullptr,                 // escher::ReleaseFenceSignaller*
       frame_scheduler_,        // shared_ptr<FrameScheduler>
+      sysmem_.get(),           // Sysmem*
       display_manager_.get(),  // DisplayManager*
       SceneGraphWeakPtr(),     // SceneGraphWeakPtr
       nullptr,                 // ResourceLinker*
diff --git a/garnet/lib/ui/gfx/tests/session_test.h b/garnet/lib/ui/gfx/tests/session_test.h
index e830bc3..f5791d7 100644
--- a/garnet/lib/ui/gfx/tests/session_test.h
+++ b/garnet/lib/ui/gfx/tests/session_test.h
@@ -7,7 +7,9 @@
 
 #include <lib/fit/function.h>
 
+#include "garnet/lib/ui/gfx/displays/display_manager.h"
 #include "garnet/lib/ui/gfx/engine/session.h"
+#include "garnet/lib/ui/gfx/sysmem.h"
 #include "garnet/lib/ui/gfx/tests/error_reporting_test.h"
 #include "garnet/lib/ui/gfx/tests/mocks.h"
 #include "garnet/lib/ui/scenic/event_reporter.h"
@@ -54,6 +56,7 @@
  private:
   SessionContext session_context_;
 
+  std::unique_ptr<Sysmem> sysmem_;
   std::unique_ptr<DisplayManager> display_manager_;
   std::shared_ptr<FrameScheduler> frame_scheduler_;
   std::unique_ptr<Session> session_;
diff --git a/garnet/lib/ui/input/tests/util.cc b/garnet/lib/ui/input/tests/util.cc
index 4756519..24715dd 100644
--- a/garnet/lib/ui/input/tests/util.cc
+++ b/garnet/lib/ui/input/tests/util.cc
@@ -8,7 +8,6 @@
 
 #include <hid/hid.h>
 
-#include "garnet/lib/ui/gfx/displays/display_manager.h"
 #include "garnet/lib/ui/gfx/engine/default_frame_scheduler.h"
 #include "garnet/lib/ui/gfx/id.h"
 #include "lib/fidl/cpp/clone.h"
@@ -86,8 +85,8 @@
       std::make_unique<FramePredictor>(DefaultFrameScheduler::kInitialRenderDuration,
                                        DefaultFrameScheduler::kInitialUpdateDuration));
 
-  engine_ = std::make_unique<Engine>(frame_scheduler,
-                                     /*display_manager*/ nullptr, std::move(signaller),
+  engine_ = std::make_unique<Engine>(frame_scheduler, /* sysmem */ nullptr,
+                                     /* display_manager */ nullptr, std::move(signaller),
                                      escher::EscherWeakPtr());
   frame_scheduler->SetFrameRenderer(engine_->GetWeakPtr());
   auto gfx =
diff --git a/garnet/lib/ui/scenic/tests/scenic_gfx_test.cc b/garnet/lib/ui/scenic/tests/scenic_gfx_test.cc
index 4452560..117cc35 100644
--- a/garnet/lib/ui/scenic/tests/scenic_gfx_test.cc
+++ b/garnet/lib/ui/scenic/tests/scenic_gfx_test.cc
@@ -28,8 +28,8 @@
                                             gfx::DefaultFrameScheduler::kInitialUpdateDuration),
       scenic_->inspect_node()->CreateChild("FrameScheduler"));
 
-  engine_ = std::make_unique<gfx::Engine>(frame_scheduler_,
-                                          /*display_manager*/ nullptr, std::move(signaller),
+  engine_ = std::make_unique<gfx::Engine>(frame_scheduler_, /* sysmem */ nullptr,
+                                          /* display_manager */ nullptr, std::move(signaller),
                                           escher::EscherWeakPtr());
   auto system = scenic->RegisterSystem<gfx::GfxSystem>(display_.get(), engine_.get(),
                                                        escher::EscherWeakPtr());
diff --git a/garnet/lib/ui/scenic/tests/scenic_test.cc b/garnet/lib/ui/scenic/tests/scenic_test.cc
index 8ac8312..3417341 100644
--- a/garnet/lib/ui/scenic/tests/scenic_test.cc
+++ b/garnet/lib/ui/scenic/tests/scenic_test.cc
@@ -6,9 +6,6 @@
 
 #include <lib/sys/cpp/testing/component_context_provider.h>
 
-#include "garnet/lib/ui/gfx/displays/display.h"
-#include "garnet/lib/ui/gfx/displays/display_manager.h"
-
 namespace scenic_impl {
 namespace test {