OSDN Git Service

Add OverlayBufferManager.
authorKalyan Kondapally <kalyan.kondapally@intel.com>
Sun, 26 Mar 2017 04:41:15 +0000 (21:41 -0700)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Sun, 26 Mar 2017 10:53:31 +0000 (03:53 -0700)
We need to track life time of OverlayBuffer in various cases:
1) Ensure its available until the buffer is scanned out and
   is being displayed on screen.
2) Ensure its not destroyed if it's going to be re-used.

We dont have a central tracking place for all this which is
making it hard to ensure the buffers are alive. This patch
adds OverlayBufferManager which is responsible for creating
the buffers and deleting them when it's not in use.

Jira: IAHWC-46
Test: No visible tearing with apps on Linux.

Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
28 files changed:
Android.mk
Makefile.sources
common/compositor/compositor.cpp
common/compositor/compositor.h
common/compositor/nativesurface.cpp
common/compositor/nativesurface.h
common/compositor/vk/vksurface.h
common/core/gpudevice.cpp
common/core/nativesync.cpp
common/core/nativesync.h
common/core/overlaybuffer.h
common/core/overlaybuffermanager.cpp [new file with mode: 0644]
common/core/overlaybuffermanager.h [new file with mode: 0644]
common/core/overlaylayer.cpp
common/core/overlaylayer.h
common/display/display.cpp
common/display/display.h
common/display/displayplanemanager.cpp
common/display/displayplanemanager.h
common/display/displayqueue.cpp
common/display/displayqueue.h
common/display/headless.cpp
common/display/headless.h
common/display/kmsfencehandler.cpp
common/display/kmsfencehandler.h
common/display/virtualdisplay.cpp
common/display/virtualdisplay.h
public/nativedisplay.h

index 235f398..d7539ff 100644 (file)
@@ -51,6 +51,7 @@ LOCAL_SRC_FILES := \
        common/core/gpudevice.cpp \
        common/core/nativesync.cpp \
        common/core/overlaybuffer.cpp \
+       common/core/overlaybuffermanager.cpp \
        common/core/overlaylayer.cpp \
        common/display/display.cpp \
        common/display/displayplane.cpp \
index 4874cf3..ec05998 100644 (file)
@@ -7,6 +7,7 @@ common_SOURCES =              \
     common/core/hwclayer.cpp \
     common/core/nativesync.cpp \
     common/core/overlaybuffer.cpp \
+    common/core/overlaybuffermanager.cpp \
     common/core/overlaylayer.cpp \
     common/display/display.cpp \
     common/display/displayqueue.cpp \
index 5b3d0d2..71493a1 100644 (file)
@@ -111,7 +111,7 @@ bool Compositor::Draw(DisplayPlaneStateList &comp_planes,
 bool Compositor::DrawOffscreen(std::vector<OverlayLayer> &layers,
                                const std::vector<HwcRect<int>> &display_frame,
                                const std::vector<size_t> &source_layers,
-                               NativeBufferHandler *buffer_handler,
+                               OverlayBufferManager *buffer_manager,
                                uint32_t width, uint32_t height,
                                HWCNativeHandle output_handle,
                                int32_t *retire_fence) {
@@ -141,7 +141,7 @@ bool Compositor::DrawOffscreen(std::vector<OverlayLayer> &layers,
   }
 
   std::unique_ptr<NativeSurface> surface(CreateBackBuffer(width, height));
-  surface->InitializeForOffScreenRendering(buffer_handler, output_handle);
+  surface->InitializeForOffScreenRendering(buffer_manager, output_handle);
 
   if (!Render(layers, surface.get(), comp_regions))
     return false;
index 4e35422..aa9a489 100644 (file)
@@ -28,7 +28,7 @@
 
 namespace hwcomposer {
 
-class NativeBufferHandler;
+class OverlayBufferManager;
 struct OverlayLayer;
 
 class Compositor {
@@ -47,7 +47,7 @@ class Compositor {
   bool DrawOffscreen(std::vector<OverlayLayer> &layers,
                      const std::vector<HwcRect<int>> &display_frame,
                      const std::vector<size_t> &source_layers,
-                     NativeBufferHandler *buffer_handler, uint32_t width,
+                     OverlayBufferManager *buffer_manager, uint32_t width,
                      uint32_t height, HWCNativeHandle output_handle,
                      int32_t *retire_fence);
   void InsertFence(uint64_t fence);
index f4fbcc0..1e4c379 100644 (file)
@@ -19,6 +19,7 @@
 #include "displayplane.h"
 #include "hwctrace.h"
 #include "nativebufferhandler.h"
+#include "overlaybuffermanager.h"
 
 namespace hwcomposer {
 
@@ -43,8 +44,8 @@ NativeSurface::~NativeSurface() {
   }
 }
 
-bool NativeSurface::Init(NativeBufferHandler *buffer_handler) {
-  buffer_handler_ = buffer_handler;
+bool NativeSurface::Init(OverlayBufferManager *buffer_manager) {
+  buffer_handler_ = buffer_manager->GetNativeBufferHandler();
   buffer_handler_->CreateBuffer(width_, height_, 0, &native_handle_);
   if (!native_handle_) {
     ETRACE("Failed to create buffer.");
@@ -52,14 +53,14 @@ bool NativeSurface::Init(NativeBufferHandler *buffer_handler) {
   }
 
   ref_count_ = 0;
-  InitializeLayer(buffer_handler_, native_handle_);
+  InitializeLayer(buffer_manager, native_handle_);
 
   return true;
 }
 
 bool NativeSurface::InitializeForOffScreenRendering(
-    NativeBufferHandler *buffer_handler, HWCNativeHandle native_handle) {
-  InitializeLayer(buffer_handler, native_handle);
+    OverlayBufferManager *buffer_manager, HWCNativeHandle native_handle) {
+  InitializeLayer(buffer_manager, native_handle);
   layer_.SetSourceCrop(HwcRect<float>(0, 0, width_, height_));
   layer_.SetDisplayFrame(HwcRect<int>(0, 0, width_, height_));
 
@@ -100,16 +101,17 @@ void NativeSurface::SetPlaneTarget(DisplayPlaneState &plane, uint32_t gpu_fd) {
   layer_.GetBuffer()->CreateFrameBuffer(gpu_fd);
 }
 
-void NativeSurface::InitializeLayer(NativeBufferHandler *buffer_handler,
+void NativeSurface::InitializeLayer(OverlayBufferManager *buffer_manager,
                                     HWCNativeHandle native_handle) {
-  OverlayBuffer *overlay_buffer = new OverlayBuffer();
-  overlay_buffer->InitializeFromNativeHandle(native_handle, buffer_handler);
+  ImportedBuffer *buffer =
+      buffer_manager->CreateBufferFromNativeHandle(native_handle);
+  OverlayBuffer *overlay_buffer = buffer->buffer_;
   width_ = overlay_buffer->GetWidth();
   height_ = overlay_buffer->GetHeight();
   layer_.SetNativeHandle(native_handle_);
   layer_.SetBlending(HWCBlending::kBlendingPremult);
   layer_.SetTransform(0);
-  layer_.SetBuffer(overlay_buffer);
+  layer_.SetBuffer(buffer);
 }
 
 void NativeSurface::ResetInFlightMode() {
index 22c4380..021f611 100644 (file)
@@ -26,6 +26,7 @@
 namespace hwcomposer {
 
 class NativeBufferHandler;
+class OverlayBufferManager;
 
 class NativeSurface {
  public:
@@ -36,9 +37,9 @@ class NativeSurface {
 
   virtual ~NativeSurface();
 
-  bool Init(NativeBufferHandler* buffer_handler);
+  bool Init(OverlayBufferManager* buffer_manager);
 
-  bool InitializeForOffScreenRendering(NativeBufferHandler* buffer_handler,
+  bool InitializeForOffScreenRendering(OverlayBufferManager* buffer_manager,
                                        HWCNativeHandle native_handle);
 
   virtual bool MakeCurrent() = 0;
@@ -78,7 +79,7 @@ class NativeSurface {
   OverlayLayer layer_;
 
  private:
-  void InitializeLayer(NativeBufferHandler* buffer_handler,
+  void InitializeLayer(OverlayBufferManager* buffer_manager,
                        HWCNativeHandle native_handle);
   HWCNativeHandle native_handle_;
   NativeBufferHandler* buffer_handler_;
index f4dcbe0..38fc844 100644 (file)
@@ -20,7 +20,6 @@
 
 namespace hwcomposer {
 
-class NativeBufferHandler;
 class OverlayBuffer;
 
 class VKSurface : public NativeSurface {
index a7cc80f..31df0da 100644 (file)
@@ -42,6 +42,7 @@
 #include "drmscopedtypes.h"
 #include "headless.h"
 #include "hwcthread.h"
+#include "overlaybuffermanager.h"
 #include "spinlock.h"
 #include "vblankeventhandler.h"
 #include "virtualdisplay.h"
@@ -72,12 +73,12 @@ class GpuDevice::DisplayManager : public HWCThread {
 
  private:
   void HotPlugEventHandler();
-  std::unique_ptr<NativeBufferHandler> buffer_handler_;
   std::unique_ptr<NativeDisplay> headless_;
   std::unique_ptr<NativeDisplay> virtual_display_;
   std::vector<std::unique_ptr<NativeDisplay>> displays_;
   std::vector<NativeDisplay *> connected_displays_;
   std::shared_ptr<DisplayHotPlugEventCallback> callback_ = NULL;
+  std::unique_ptr<OverlayBufferManager> buffer_manager_;
   int fd_ = -1;
   ScopedFd hotplug_fd_;
   SpinLock spin_lock_;
@@ -100,13 +101,14 @@ bool GpuDevice::DisplayManager::Init(uint32_t fd) {
     return false;
   }
 
-  ScopedDrmResourcesPtr res(drmModeGetResources(fd_));
-  buffer_handler_.reset(NativeBufferHandler::CreateInstance(fd_));
-  if (!buffer_handler_) {
-    ETRACE("Failed to create native buffer handler instance");
+  buffer_manager_.reset(new OverlayBufferManager());
+  if (!buffer_manager_->Initialize(fd_)) {
+    ETRACE("Failed to Initialize Buffer Manager.");
     return false;
   }
 
+  ScopedDrmResourcesPtr res(drmModeGetResources(fd_));
+
   for (int32_t i = 0; i < res->count_crtcs; ++i) {
     ScopedDrmCrtcPtr c(drmModeGetCrtc(fd_, res->crtcs[i]));
     if (!c) {
@@ -115,7 +117,7 @@ bool GpuDevice::DisplayManager::Init(uint32_t fd) {
     }
 
     std::unique_ptr<NativeDisplay> display(new Display(fd_, i, c->crtc_id));
-    if (!display->Initialize()) {
+    if (!display->Initialize(buffer_manager_.get())) {
       ETRACE("Failed to Initialize Display %d", c->crtc_id);
       return false;
     }
@@ -123,7 +125,7 @@ bool GpuDevice::DisplayManager::Init(uint32_t fd) {
     displays_.emplace_back(std::move(display));
   }
 
-  virtual_display_.reset(new VirtualDisplay(fd_, buffer_handler_.get(), 0, 0));
+  virtual_display_.reset(new VirtualDisplay(fd_, buffer_manager_.get(), 0, 0));
 
   if (!UpdateDisplayState()) {
     ETRACE("Failed to connect display.");
@@ -149,6 +151,7 @@ bool GpuDevice::DisplayManager::Init(uint32_t fd) {
   }
 
   fd_handler_.AddFd(hotplug_fd_.get());
+
   if (!InitWorker()) {
     ETRACE("Failed to initalizer thread to monitor Hot Plug events. %s",
            PRINTERROR());
@@ -264,7 +267,7 @@ bool GpuDevice::DisplayManager::UpdateDisplayState() {
       if (encoder && encoder->crtc_id) {
         for (auto &display : displays_) {
           if (encoder->crtc_id == display->CrtcId() &&
-              display->Connect(mode, connector.get(), buffer_handler_.get())) {
+              display->Connect(mode, connector.get())) {
             connected_displays_.emplace_back(display.get());
             break;
           }
@@ -281,7 +284,7 @@ bool GpuDevice::DisplayManager::UpdateDisplayState() {
         for (auto &display : displays_) {
           if (!display->IsConnected() &&
               (encoder->possible_crtcs & (1 << display->Pipe())) &&
-              display->Connect(mode, connector.get(), buffer_handler_.get())) {
+              display->Connect(mode, connector.get())) {
             IHOTPLUGEVENTTRACE("connected pipe:%d \n", display->Pipe());
             connected_displays_.emplace_back(display.get());
             found_encoder = true;
index 7ef0c63..c66aba2 100644 (file)
@@ -65,10 +65,6 @@ bool NativeSync::Init() {
   return true;
 }
 
-void NativeSync::SetState(State fence_state) {
-  state_ = fence_state;
-}
-
 int NativeSync::CreateNextTimelineFence() {
   ++timeline_;
   return sw_sync_fence_create(timeline_fd_.get(), "NativeSync", timeline_);
index d83afa4..506c2f0 100644 (file)
@@ -28,11 +28,9 @@ class NativeSync {
   // kReady:  Fence can be signalled immediately. This is usually
   //          the case when we need to fallback to 3D Composition for
   //          a given buffer.
-  // kIgnore: Dont signal the fence yet. This is the case when layer
-  //          associated with the fence is recycled.
   // kSignalOnPageFlipEvent: Release the fence when we recieve PageFlipEvent
   //                         notification.
-  enum class State : int32_t { kReady, kIgnore, kSignalOnPageFlipEvent };
+  enum class State : int32_t { kReady, kSignalOnPageFlipEvent };
 
   NativeSync();
   virtual ~NativeSync();
@@ -41,11 +39,6 @@ class NativeSync {
 
   int CreateNextTimelineFence();
 
-  void SetState(State fence_state);
-  State GetState() const {
-    return state_;
-  }
-
  private:
   int IncreaseTimelineToPoint(int point);
 #ifndef USE_ANDROID_SYNC
@@ -56,7 +49,6 @@ class NativeSync {
   ScopedFd timeline_fd_;
   int64_t timeline_ = 0;
   int64_t timeline_current_ = 0;
-  State state_ = State::kSignalOnPageFlipEvent;
 };
 
 }  // namespace hwcomposer
index e72ad02..32858f8 100644 (file)
@@ -28,7 +28,6 @@ class NativeBufferHandler;
 
 class OverlayBuffer {
  public:
-  OverlayBuffer() = default;
   OverlayBuffer(OverlayBuffer&& rhs) = default;
   OverlayBuffer& operator=(OverlayBuffer&& other) = default;
 
@@ -73,6 +72,10 @@ class OverlayBuffer {
 
   void Dump();
 
+ protected:
+  OverlayBuffer() = default;
+  friend class OverlayBufferManager;
+
  private:
   uint32_t width_ = 0;
   uint32_t height_ = 0;
diff --git a/common/core/overlaybuffermanager.cpp b/common/core/overlaybuffermanager.cpp
new file mode 100644 (file)
index 0000000..43e3ee0
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "overlaybuffermanager.h"
+
+#include "hwctrace.h"
+#include "overlaylayer.h"
+
+namespace hwcomposer {
+
+ImportedBuffer::~ImportedBuffer() {
+  if (buffer_)
+    buffer_manager_->UnRegisterBuffer(buffer_);
+}
+
+OverlayBufferManager::~OverlayBufferManager() {
+}
+
+bool OverlayBufferManager::Initialize(uint32_t gpu_fd) {
+  buffer_handler_.reset(NativeBufferHandler::CreateInstance(gpu_fd));
+  if (!buffer_handler_) {
+    ETRACE("Failed to create native buffer handler instance");
+    return false;
+  }
+
+  return true;
+}
+
+ImportedBuffer* OverlayBufferManager::CreateBuffer(const HwcBuffer& bo) {
+  ScopedSpinLock lock(spin_lock_);
+  buffers_.emplace_back();
+  Buffer& buffer = buffers_.back();
+  buffer.buffer_.reset(new OverlayBuffer());
+  buffer.buffer_->Initialize(bo);
+  buffer.ref_count_ = 1;
+  buffer.sync_object_.reset(new NativeSync());
+  if (!buffer.sync_object_->Init()) {
+    ETRACE("Failed to create sync object.");
+  }
+
+  return new ImportedBuffer(buffer.buffer_.get(), this,
+                            buffer.sync_object_->CreateNextTimelineFence());
+}
+
+ImportedBuffer* OverlayBufferManager::CreateBufferFromNativeHandle(
+    HWCNativeHandle handle) {
+  ScopedSpinLock lock(spin_lock_);
+  buffers_.emplace_back();
+  Buffer& buffer = buffers_.back();
+  buffer.buffer_.reset(new OverlayBuffer());
+  buffer.buffer_->InitializeFromNativeHandle(handle, buffer_handler_.get());
+  buffer.ref_count_ = 1;
+  buffer.sync_object_.reset(new NativeSync());
+  if (!buffer.sync_object_->Init()) {
+    ETRACE("Failed to create sync object.");
+  }
+
+  return new ImportedBuffer(buffer.buffer_.get(), this,
+                            buffer.sync_object_->CreateNextTimelineFence());
+}
+
+void OverlayBufferManager::RegisterBuffer(OverlayBuffer* buffer) {
+  ScopedSpinLock lock(spin_lock_);
+  for (Buffer& overlay_buffer : buffers_) {
+    if (overlay_buffer.buffer_.get() != buffer)
+      continue;
+
+    overlay_buffer.ref_count_++;
+    break;
+  }
+}
+
+void OverlayBufferManager::RegisterBuffers(
+    const std::vector<OverlayBuffer*>& buffers) {
+  ScopedSpinLock lock(spin_lock_);
+  for (OverlayBuffer* buffer : buffers) {
+    for (Buffer& overlay_buffer : buffers_) {
+      if (overlay_buffer.buffer_.get() != buffer)
+        continue;
+
+      overlay_buffer.ref_count_++;
+      break;
+    }
+  }
+}
+
+void OverlayBufferManager::UnRegisterBuffer(OverlayBuffer* buffer) {
+  ScopedSpinLock lock(spin_lock_);
+  int32_t index = -1;
+  for (Buffer& overlay_buffer : buffers_) {
+    index++;
+    if (overlay_buffer.buffer_.get() != buffer)
+      continue;
+
+    overlay_buffer.ref_count_--;
+    if (overlay_buffer.ref_count_ <= 0) {
+      buffers_.erase(buffers_.begin() + index);
+    }
+
+    break;
+  }
+}
+
+void OverlayBufferManager::UnRegisterBuffers(
+    const std::vector<OverlayBuffer*>& buffers) {
+  ScopedSpinLock lock(spin_lock_);
+  for (OverlayBuffer* buffer : buffers) {
+    int32_t index = -1;
+    for (Buffer& overlay_buffer : buffers_) {
+      index++;
+      if (overlay_buffer.buffer_.get() != buffer)
+        continue;
+
+      overlay_buffer.ref_count_--;
+      if (overlay_buffer.ref_count_ <= 0) {
+        buffers_.erase(buffers_.begin() + index);
+      }
+
+      break;
+    }
+  }
+}
+
+void OverlayBufferManager::SignalBuffersIfReady(
+    std::vector<OverlayLayer>& layers) {
+  ScopedSpinLock lock(spin_lock_);
+  for (OverlayLayer& layer : layers) {
+    if (layer.GetReleaseFenceState() != NativeSync::State::kReady) {
+      continue;
+    }
+
+    OverlayBuffer* buffer = layer.GetBuffer();
+    if (!buffer)
+      continue;
+
+    for (Buffer& overlay_buffer : buffers_) {
+      if (overlay_buffer.buffer_.get() != buffer)
+        continue;
+
+      overlay_buffer.sync_object_.reset(nullptr);
+      break;
+    }
+  }
+}
+
+void OverlayBufferManager::UnRegisterLayerBuffers(
+    std::vector<OverlayLayer>& layers) {
+  ScopedSpinLock lock(spin_lock_);
+  for (OverlayLayer& layer : layers) {
+    OverlayBuffer* buffer = layer.GetBuffer();
+    if (!buffer)
+      continue;
+    int32_t index = -1;
+    for (Buffer& overlay_buffer : buffers_) {
+      index++;
+      if (overlay_buffer.buffer_.get() != buffer)
+        continue;
+
+      overlay_buffer.ref_count_--;
+      layer.MarkBufferReleased();
+      if (overlay_buffer.ref_count_ <= 0) {
+        buffers_.erase(buffers_.begin() + index);
+      }
+
+      break;
+    }
+  }
+}
+
+}  // namespace hwcomposer
diff --git a/common/core/overlaybuffermanager.h b/common/core/overlaybuffermanager.h
new file mode 100644 (file)
index 0000000..5e32c0f
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#ifndef COMMON_CORE_OVERLAYBUFFERMANAGER_H_
+#define COMMON_CORE_OVERLAYBUFFERMANAGER_H_
+
+#include <platformdefines.h>
+
+#include <nativebufferhandler.h>
+#include <nativefence.h>
+#include <spinlock.h>
+
+#include <memory>
+#include <vector>
+
+#include "nativesync.h"
+#include "overlaybuffer.h"
+
+namespace hwcomposer {
+
+class NativeBufferHandler;
+class OverlayBufferManager;
+struct OverlayLayer;
+
+struct ImportedBuffer {
+ public:
+  ImportedBuffer(OverlayBuffer* buffer, OverlayBufferManager* buffer_manager,
+                 int release_fence)
+      : buffer_(buffer),
+        release_fence_(release_fence),
+        buffer_manager_(buffer_manager) {
+  }
+
+  ~ImportedBuffer();
+
+  OverlayBuffer* buffer_;
+  int release_fence_;
+
+ private:
+  OverlayBufferManager* buffer_manager_;
+};
+
+class OverlayBufferManager {
+ public:
+  OverlayBufferManager() = default;
+  OverlayBufferManager(OverlayBufferManager&& rhs) = default;
+  OverlayBufferManager& operator=(OverlayBufferManager&& other) = default;
+
+  ~OverlayBufferManager();
+
+  bool Initialize(uint32_t gpu_fd);
+
+  // Creates new ImportedBuffer for bo. Also, creates
+  // a sync fence object associated for this buffer.
+  // Sync fence is automatically signalled when buffer
+  // is destroyed. RefCount of buffer is initialized to
+  // 1.
+  ImportedBuffer* CreateBuffer(const HwcBuffer& bo);
+
+  // Creates new ImportedBuffer for handle. Also, creates
+  // a sync fence object associated for this buffer.
+  // Sync fence is automatically signalled when buffer
+  // is destroyed. RefCount of buffer is initialized to
+  // 1.
+  ImportedBuffer* CreateBufferFromNativeHandle(HWCNativeHandle handle);
+
+  // Increments RefCount of buffer by 1. Buffer will not be released
+  // or associated fence object signalled until UnRegisterBuffer
+  // is called and RefCount decreases to zero.
+  void RegisterBuffer(OverlayBuffer* buffer);
+
+  // Decreases RefCount of buffer by 1. Buffer will be released
+  // and associated fence object will be signalled if RefCount
+  // is equal to zero.
+  void UnRegisterBuffer(OverlayBuffer* buffer);
+
+  // Convenient function to call together RegisterBuffer for
+  // OverlayBuffers.
+  void RegisterBuffers(const std::vector<OverlayBuffer*>& buffers);
+
+  // Convenient function to call together UnRegisterBuffers for
+  // OverlayBuffers.
+  void UnRegisterBuffers(const std::vector<OverlayBuffer*>& buffers);
+
+  // Convenient function to signal buffers as free to be re-used
+  // without deleting buffer associated with the layer.
+  void SignalBuffersIfReady(std::vector<OverlayLayer>& layers);
+
+  void UnRegisterLayerBuffers(std::vector<OverlayLayer>& layers);
+
+  NativeBufferHandler* GetNativeBufferHandler() const {
+    return buffer_handler_.get();
+  }
+
+ private:
+  struct Buffer {
+    std::unique_ptr<OverlayBuffer> buffer_;
+    std::unique_ptr<NativeSync> sync_object_;
+    uint32_t ref_count_ = 0;
+  };
+
+  SpinLock spin_lock_;
+  std::vector<Buffer> buffers_;
+  std::unique_ptr<NativeBufferHandler> buffer_handler_;
+};
+
+}  // namespace hwcomposer
+#endif  // COMMON_CORE_OVERLAYBUFFERMANAGER_H_
index 876cd67..bca16c9 100644 (file)
 namespace hwcomposer {
 
 bool OverlayLayer::operator!=(const OverlayLayer& rhs) const {
-  if (buffer_->GetFormat() != rhs.buffer_->GetFormat())
+  OverlayBuffer* buffer = imported_buffer_->buffer_;
+  if (buffer->GetFormat() != rhs.imported_buffer_->buffer_->GetFormat())
     return true;
 
   // We expect cursor plane to support alpha always.
-  if (!(buffer_->GetUsage() & kLayerCursor)) {
+  if (!(buffer->GetUsage() & kLayerCursor)) {
     if (alpha_ != rhs.alpha_)
       return true;
   }
@@ -55,36 +56,19 @@ bool OverlayLayer::operator!=(const OverlayLayer& rhs) const {
 }
 
 int OverlayLayer::GetReleaseFence() {
-  if (!sync_object_) {
-    sync_object_.reset(new NativeSync());
-    if (!sync_object_->Init()) {
-      ETRACE("Failed to create sync object.");
-      return -1;
-    }
-  }
-
-  return sync_object_->CreateNextTimelineFence();
+  return imported_buffer_->release_fence_;
 }
 
 void OverlayLayer::SetReleaseFenceState(NativeSync::State state) {
-  sync_object_->SetState(state);
+  state_ = state;
 }
 
-void OverlayLayer::ReleaseFenceIfReady() {
-  if (!sync_object_)
-    return;
-
-  if (sync_object_->GetState() == NativeSync::State::kReady) {
-    sync_object_.reset(nullptr);
-  }
+void OverlayLayer::MarkBufferSignalled() {
+  imported_buffer_->release_fence_ = -1;
 }
 
-void OverlayLayer::ReleaseSyncOwnershipAsNeeded(
-    std::unique_ptr<NativeSync>& fence) {
-  if (sync_object_ &&
-      sync_object_->GetState() == NativeSync::State::kSignalOnPageFlipEvent) {
-    fence.reset(sync_object_.release());
-  }
+void OverlayLayer::MarkBufferReleased() {
+  imported_buffer_->buffer_ = NULL;
 }
 
 void OverlayLayer::SetIndex(uint32_t index) {
@@ -171,7 +155,7 @@ void OverlayLayer::Dump() {
   DUMPTRACE("DstHeight: %d", display_frame_height_);
   DUMPTRACE("AquireFence: %d", acquire_fence_.get());
 
-  buffer_->Dump();
+  imported_buffer_->buffer_->Dump();
 }
 
 }  // namespace hwcomposer
index aeceb2c..47605a1 100644 (file)
@@ -25,7 +25,7 @@
 #include <memory>
 
 #include "nativesync.h"
-#include "overlaybuffer.h"
+#include "overlaybuffermanager.h"
 
 namespace hwcomposer {
 
@@ -45,9 +45,24 @@ struct OverlayLayer {
   // longer in use.
   int GetReleaseFence();
 
+  // Release Fence state which will determine
+  // as to when we signal the fence associated
+  // with the buffer of this layer.
   void SetReleaseFenceState(NativeSync::State state);
-  void ReleaseFenceIfReady();
-  void ReleaseSyncOwnershipAsNeeded(std::unique_ptr<NativeSync>& fence);
+  NativeSync::State GetReleaseFenceState() const {
+    return state_;
+  }
+
+  // OverlayBufferManager has signalled the
+  // fence object associated with buffer of this
+  // layer.
+  void MarkBufferSignalled();
+
+  // Only KMSFenceEventHandler should use this.
+  // KMSFenceEventHandler will call this API when
+  // the buffer associated with this layer is no
+  // longer ready by display.
+  void MarkBufferReleased();
 
   void ReleaseAcquireFence() {
     acquire_fence_.Reset(-1);
@@ -88,11 +103,11 @@ struct OverlayLayer {
   }
 
   OverlayBuffer* GetBuffer() const {
-    return buffer_.get();
+    return imported_buffer_->buffer_;
   }
 
-  void SetBuffer(OverlayBuffer* buffer) {
-    buffer_.reset(buffer);
+  void SetBuffer(ImportedBuffer* buffer) {
+    imported_buffer_.reset(buffer);
   }
 
   void SetSourceCrop(const HwcRect<float>& source_crop);
@@ -134,8 +149,8 @@ struct OverlayLayer {
   ScopedFd acquire_fence_;
   HWCBlending blending_ = HWCBlending::kBlendingNone;
   HWCNativeHandle sf_handle_ = 0;
-  std::unique_ptr<NativeSync> sync_object_;
-  std::unique_ptr<OverlayBuffer> buffer_;
+  NativeSync::State state_ = NativeSync::State::kSignalOnPageFlipEvent;
+  std::unique_ptr<ImportedBuffer> imported_buffer_;
 };
 
 }  // namespace hwcomposer
index 130f3cb..f20f134 100644 (file)
@@ -31,8 +31,7 @@ namespace hwcomposer {
 static const int32_t kUmPerInch = 25400;
 
 Display::Display(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id)
-    : buffer_handler_(NULL),
-      crtc_id_(crtc_id),
+    : crtc_id_(crtc_id),
       pipe_(pipe_id),
       connector_(0),
       width_(0),
@@ -50,16 +49,15 @@ Display::~Display() {
   flip_handler_->SetPowerMode(kOff);
 }
 
-bool Display::Initialize() {
+bool Display::Initialize(OverlayBufferManager *buffer_manager) {
   flip_handler_.reset(new PageFlipEventHandler());
-  display_queue_.reset(new DisplayQueue(gpu_fd_, crtc_id_));
+  display_queue_.reset(new DisplayQueue(gpu_fd_, crtc_id_, buffer_manager));
 
   return true;
 }
 
 bool Display::Connect(const drmModeModeInfo &mode_info,
-                      const drmModeConnector *connector,
-                      NativeBufferHandler *buffer_handler) {
+                      const drmModeConnector *connector) {
   IHOTPLUGEVENTTRACE("Display::Connect recieved.");
   // TODO(kalyan): Add support for multi monitor case.
   if (connector_ && connector->connector_id == connector_) {
@@ -90,8 +88,8 @@ bool Display::Connect(const drmModeModeInfo &mode_info,
 
   is_connected_ = true;
 
-  if (!display_queue_->Initialize(width_, height_, pipe_, connector_, mode_info,
-                                  buffer_handler)) {
+  if (!display_queue_->Initialize(width_, height_, pipe_, connector_,
+                                  mode_info)) {
     ETRACE("Failed to initialize Display Queue.");
     return false;
   }
index ef82d89..2a033b5 100644 (file)
@@ -35,7 +35,7 @@ namespace hwcomposer {
 class DisplayPlaneState;
 class DisplayPlaneManager;
 class DisplayQueue;
-class NativeBufferHandler;
+class OverlayBufferManager;
 class GpuDevice;
 class NativeSync;
 struct HwcLayer;
@@ -45,7 +45,7 @@ class Display : public NativeDisplay {
   Display(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id);
   ~Display() override;
 
-  bool Initialize() override;
+  bool Initialize(OverlayBufferManager *buffer_manager) override;
 
   DisplayType Type() const override {
     return DisplayType::kInternal;
@@ -95,8 +95,7 @@ class Display : public NativeDisplay {
   }
 
   bool Connect(const drmModeModeInfo &mode_info,
-               const drmModeConnector *connector,
-               NativeBufferHandler *buffer_handler) override;
+               const drmModeConnector *connector) override;
 
   bool IsConnected() const override {
     return is_connected_;
@@ -109,7 +108,6 @@ class Display : public NativeDisplay {
  private:
   void ShutDownPipe();
 
-  NativeBufferHandler *buffer_handler_;
   uint32_t crtc_id_;
   uint32_t pipe_;
   uint32_t connector_;
index 0862414..539b317 100644 (file)
@@ -16,8 +16,6 @@
 
 #include "displayplanemanager.h"
 
-#include <nativebufferhandler.h>
-
 #include <drm_fourcc.h>
 
 #include <set>
 
 namespace hwcomposer {
 
-DisplayPlaneManager::DisplayPlaneManager(int gpu_fd, uint32_t pipe_id,
-                                         uint32_t crtc_id)
-    : buffer_handler_(NULL),
+DisplayPlaneManager::DisplayPlaneManager(int gpu_fd, uint32_t crtc_id,
+                                         OverlayBufferManager *buffer_manager)
+    : buffer_manager_(buffer_manager),
       width_(0),
       height_(0),
       crtc_id_(crtc_id),
-      pipe_(pipe_id),
       gpu_fd_(gpu_fd),
       use_cache_(false) {
 }
@@ -46,8 +43,8 @@ DisplayPlaneManager::DisplayPlaneManager(int gpu_fd, uint32_t pipe_id,
 DisplayPlaneManager::~DisplayPlaneManager() {
 }
 
-bool DisplayPlaneManager::Initialize(NativeBufferHandler *buffer_handler,
-                                     uint32_t width, uint32_t height) {
+bool DisplayPlaneManager::Initialize(uint32_t pipe_id, uint32_t width,
+                                     uint32_t height) {
   ScopedDrmPlaneResPtr plane_resources(drmModeGetPlaneResources(gpu_fd_));
   if (!plane_resources) {
     ETRACE("Failed to get plane resources");
@@ -55,7 +52,7 @@ bool DisplayPlaneManager::Initialize(NativeBufferHandler *buffer_handler,
   }
 
   uint32_t num_planes = plane_resources->count_planes;
-  uint32_t pipe_bit = 1 << pipe_;
+  uint32_t pipe_bit = 1 << pipe_id;
   std::set<uint32_t> plane_ids;
   for (uint32_t i = 0; i < num_planes; ++i) {
     ScopedDrmPlanePtr drm_plane(
@@ -99,14 +96,13 @@ bool DisplayPlaneManager::Initialize(NativeBufferHandler *buffer_handler,
       [](const std::unique_ptr<DisplayPlane> &l,
          const std::unique_ptr<DisplayPlane> &r) { return l->id() < r->id(); });
 
-  buffer_handler_ = buffer_handler;
   width_ = width;
   height_ = height;
 
   return true;
 }
 
-bool DisplayPlaneManager::BeginFrameUpdate(std::vector<OverlayLayer> *layers) {
+void DisplayPlaneManager::BeginFrameUpdate() {
   if (cursor_plane_)
     cursor_plane_->SetEnabled(false);
 
@@ -114,24 +110,8 @@ bool DisplayPlaneManager::BeginFrameUpdate(std::vector<OverlayLayer> *layers) {
     (*i)->SetEnabled(false);
   }
 
-  size_t size = layers->size();
-  for (size_t layer_index = 0; layer_index < size; layer_index++) {
-    OverlayLayer *layer = &layers->at(layer_index);
-    HwcBuffer bo;
-    if (!buffer_handler_->ImportBuffer(layer->GetNativeHandle(), &bo)) {
-      ETRACE("Failed to Import buffer.");
-      return false;
-    }
-
-    OverlayBuffer *buffer = new OverlayBuffer();
-    buffer->Initialize(bo);
-    layer->SetBuffer(buffer);
-  }
-
   if (!in_flight_surfaces_.empty())
     std::vector<NativeSurface *>().swap(in_flight_surfaces_);
-
-  return true;
 }
 
 std::tuple<bool, DisplayPlaneStateList> DisplayPlaneManager::ValidateLayers(
@@ -370,7 +350,7 @@ void DisplayPlaneManager::EnsureOffScreenTarget(DisplayPlaneState &plane) {
 
   if (!surface) {
     NativeSurface *new_surface = CreateBackBuffer(width_, height_);
-    new_surface->Init(buffer_handler_);
+    new_surface->Init(buffer_manager_);
     surfaces_.emplace_back(std::move(new_surface));
     surface = surfaces_.back().get();
   }
index fbf4013..dc2d035 100644 (file)
@@ -37,19 +37,19 @@ namespace hwcomposer {
 class DisplayPlane;
 class DisplayPlaneState;
 class GpuDevice;
-class NativeBufferHandler;
+class OverlayBufferManager;
 struct OverlayLayer;
 
 class DisplayPlaneManager {
  public:
-  DisplayPlaneManager(int gpu_fd, uint32_t pipe_id, uint32_t crtc_id);
+  DisplayPlaneManager(int gpu_fd, uint32_t crtc_id,
+                      OverlayBufferManager *buffer_manager);
 
   virtual ~DisplayPlaneManager();
 
-  bool Initialize(NativeBufferHandler *buffer_handler, uint32_t width,
-                  uint32_t height);
+  bool Initialize(uint32_t pipe_id, uint32_t width, uint32_t height);
 
-  bool BeginFrameUpdate(std::vector<OverlayLayer> *layers);
+  void BeginFrameUpdate();
 
   std::tuple<bool, DisplayPlaneStateList> ValidateLayers(
       std::vector<OverlayLayer> *layers,
@@ -90,7 +90,7 @@ class DisplayPlaneManager {
       const std::vector<OverlayLayer> *layers,
       DisplayPlaneStateList *composition, bool *render_layers);
 
-  NativeBufferHandler *buffer_handler_;
+  OverlayBufferManager *buffer_manager_;
   std::vector<std::unique_ptr<NativeSurface>> surfaces_;
   std::vector<NativeSurface *> in_flight_surfaces_;
   std::unique_ptr<DisplayPlane> primary_plane_;
@@ -100,7 +100,6 @@ class DisplayPlaneManager {
   uint32_t width_;
   uint32_t height_;
   uint32_t crtc_id_;
-  uint32_t pipe_;
   uint32_t gpu_fd_;
   bool use_cache_;
 };
index f86ffe6..5d1bc5e 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <hwcdefs.h>
 #include <hwclayer.h>
-#include <nativebufferhandler.h>
 
 #include <vector>
 
@@ -29,7 +28,8 @@
 
 namespace hwcomposer {
 
-DisplayQueue::DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id)
+DisplayQueue::DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id,
+                           OverlayBufferManager* buffer_manager)
     : frame_(0),
       dpms_prop_(0),
       out_fence_ptr_prop_(0),
@@ -40,7 +40,8 @@ DisplayQueue::DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id)
       crtc_prop_(0),
       blob_id_(0),
       old_blob_id_(0),
-      gpu_fd_(gpu_fd) {
+      gpu_fd_(gpu_fd),
+      buffer_manager_(buffer_manager) {
   compositor_.Init();
   ScopedDrmObjectPropertyPtr crtc_props(
       drmModeObjectGetProperties(gpu_fd_, crtc_id_, DRM_MODE_OBJECT_CRTC));
@@ -50,6 +51,10 @@ DisplayQueue::DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id)
   GetDrmObjectProperty("OUT_FENCE_PTR", crtc_props, &out_fence_ptr_prop_);
 #endif
   memset(&mode_, 0, sizeof(mode_));
+  display_plane_manager_.reset(
+      new DisplayPlaneManager(gpu_fd_, crtc_id_, buffer_manager_));
+
+  kms_fence_handler_.reset(new KMSFenceEventHandler(buffer_manager_));
 }
 
 DisplayQueue::~DisplayQueue() {
@@ -62,21 +67,16 @@ DisplayQueue::~DisplayQueue() {
 
 bool DisplayQueue::Initialize(uint32_t width, uint32_t height, uint32_t pipe,
                               uint32_t connector,
-                              const drmModeModeInfo& mode_info,
-                              NativeBufferHandler* buffer_handler) {
+                              const drmModeModeInfo& mode_info) {
   frame_ = 0;
   previous_layers_.clear();
   previous_plane_state_.clear();
-  display_plane_manager_.reset(
-      new DisplayPlaneManager(gpu_fd_, pipe, crtc_id_));
 
-  if (!display_plane_manager_->Initialize(buffer_handler, width, height)) {
+  if (!display_plane_manager_->Initialize(pipe, width, height)) {
     ETRACE("Failed to initialize DisplayQueue Manager.");
     return false;
   }
 
-  kms_fence_handler_.reset(new KMSFenceEventHandler());
-
   connector_ = connector;
   mode_ = mode_info;
 
@@ -187,16 +187,16 @@ bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers) {
     overlay_layer.SetIndex(layer_index);
     overlay_layer.SetAcquireFence(layer->acquire_fence.Release());
     layers_rects.emplace_back(layer->GetDisplayFrame());
+    ImportedBuffer* buffer = buffer_manager_->CreateBufferFromNativeHandle(
+       layer->GetNativeHandle());
+    overlay_layer.SetBuffer(buffer);
     int ret = layer->release_fence.Reset(overlay_layer.GetReleaseFence());
     if (ret < 0)
       ETRACE("Failed to create fence for layer, error: %s", PRINTERROR());
   }
 
   // Reset any DisplayQueue Manager and Compositor state.
-  if (!display_plane_manager_->BeginFrameUpdate(&layers)) {
-    ETRACE("Failed to import needed buffers in DisplayQueueManager.");
-    return false;
-  }
+  display_plane_manager_->BeginFrameUpdate();
 
   uint32_t flags = 0;
   if (needs_modeset_) {
@@ -233,9 +233,7 @@ bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers) {
     }
   }
 
-  for (OverlayLayer& layer : layers) {
-    layer.ReleaseFenceIfReady();
-  }
+  buffer_manager_->SignalBuffersIfReady(layers);
 
   uint64_t fence = 0;
   // Do the actual commit.
@@ -267,6 +265,7 @@ bool DisplayQueue::QueueUpdate(std::vector<HwcLayer*>& source_layers) {
 
 #ifdef DISABLE_EXPLICIT_SYNC
   compositor_.InsertFence(fence);
+  buffer_manager_->UnRegisterLayerBuffers(previous_layers_);
 #else
   if (fence > 0) {
     compositor_.InsertFence(dup(fence));
index e8181a5..3006486 100644 (file)
 namespace hwcomposer {
 class DisplayPlaneManager;
 struct HwcLayer;
-class NativeBufferHandler;
+class OverlayBufferManager;
 class PageFlipEventHandler;
 
 class DisplayQueue {
  public:
-  DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id);
+  DisplayQueue(uint32_t gpu_fd, uint32_t crtc_id,
+               OverlayBufferManager* buffer_manager);
   ~DisplayQueue();
 
   bool Initialize(uint32_t width, uint32_t height, uint32_t pipe,
-                  uint32_t connector, const drmModeModeInfo& mode_info,
-                  NativeBufferHandler* buffer_handler);
+                  uint32_t connector, const drmModeModeInfo& mode_info);
 
   bool QueueUpdate(std::vector<HwcLayer*>& source_layers);
   bool SetPowerMode(uint32_t power_mode);
@@ -84,6 +84,7 @@ class DisplayQueue {
   std::unique_ptr<DisplayPlaneManager> display_plane_manager_;
   std::vector<OverlayLayer> previous_layers_;
   DisplayPlaneStateList previous_plane_state_;
+  OverlayBufferManager* buffer_manager_;
 };
 
 }  // namespace hwcomposer
index 67a62b7..c71e535 100644 (file)
@@ -31,13 +31,12 @@ Headless::Headless(uint32_t gpu_fd, uint32_t /*pipe_id*/, uint32_t /*crtc_id*/)
 Headless::~Headless() {
 }
 
-bool Headless::Initialize() {
+bool Headless::Initialize(OverlayBufferManager * /*buffer_manager*/) {
   return true;
 }
 
 bool Headless::Connect(const drmModeModeInfo & /*mode_info*/,
-                       const drmModeConnector * /*connector*/,
-                       NativeBufferHandler * /*buffer_handler*/) {
+                       const drmModeConnector * /*connector*/) {
   return true;
 }
 
index 05807d0..ffaab45 100644 (file)
 
 namespace hwcomposer {
 
-class NativeBufferHandler;
-
 class Headless : public NativeDisplay {
  public:
   Headless(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id);
   ~Headless() override;
 
-  bool Initialize() override;
+  bool Initialize(OverlayBufferManager *buffer_manager) override;
 
   DisplayType Type() const override {
     return DisplayType::kHeadless;
@@ -81,8 +79,7 @@ class Headless : public NativeDisplay {
   }
 
   bool Connect(const drmModeModeInfo &mode_info,
-               const drmModeConnector *connector,
-               NativeBufferHandler *buffer_handler) override;
+               const drmModeConnector *connector) override;
 
   bool IsConnected() const override {
     return false;
index 9831d5b..b1f8bdb 100644 (file)
 
 namespace hwcomposer {
 
-KMSFenceEventHandler::KMSFenceEventHandler()
-    : HWCThread(-8, "KMSFenceEventHandler") {
+KMSFenceEventHandler::KMSFenceEventHandler(OverlayBufferManager* buffer_manager)
+    : HWCThread(-8, "KMSFenceEventHandler"),
+      kms_fence_(0),
+      buffer_manager_(buffer_manager) {
 }
 
 KMSFenceEventHandler::~KMSFenceEventHandler() {
@@ -47,9 +49,14 @@ void KMSFenceEventHandler::WaitFence(uint64_t kms_fence,
                                      std::vector<OverlayLayer>& layers) {
   ScopedSpinLock lock(spin_lock_);
   for (OverlayLayer& layer : layers) {
-    std::unique_ptr<NativeSync> fence;
-    layer.ReleaseSyncOwnershipAsNeeded(fence);
-    fences_.emplace_back(std::move(fence));
+    OverlayBuffer* buffer = layer.GetBuffer();
+    if (buffer) {
+      buffers_.emplace_back(buffer);
+      // Instead of registering again, we mark the buffer
+      // released in layer so that it's not deleted till we
+      // explicitly unregister the buffer.
+      layer.MarkBufferReleased();
+    }
   }
 
   kms_fence_ = kms_fence;
@@ -69,7 +76,9 @@ void KMSFenceEventHandler::HandleRoutine() {
     close(kms_fence_);
     kms_fence_ = -1;
   }
-  std::vector<std::unique_ptr<NativeSync>>().swap(fences_);
+
+  buffer_manager_->UnRegisterBuffers(buffers_);
+  std::vector<OverlayBuffer*>().swap(buffers_);
 }
 
 }  // namespace hwcomposer
index 3925987..5bd5c53 100644 (file)
@@ -33,7 +33,7 @@ namespace hwcomposer {
 
 class KMSFenceEventHandler : public HWCThread {
  public:
-  KMSFenceEventHandler();
+  KMSFenceEventHandler(OverlayBufferManager* buffer_manager);
   ~KMSFenceEventHandler() override;
 
   bool Initialize();
@@ -47,8 +47,9 @@ class KMSFenceEventHandler : public HWCThread {
 
  private:
   SpinLock spin_lock_;
-  std::vector<std::unique_ptr<NativeSync>> fences_;
+  std::vector<OverlayBuffer*> buffers_;
   uint64_t kms_fence_;
+  OverlayBufferManager* buffer_manager_;
 };
 
 }  // namespace hwcomposer
index 72044e5..037f656 100644 (file)
 #include <vector>
 
 #include "hwctrace.h"
+#include "overlaybuffermanager.h"
 #include "overlaylayer.h"
 
 namespace hwcomposer {
 
 VirtualDisplay::VirtualDisplay(uint32_t gpu_fd,
-                               NativeBufferHandler *buffer_handler,
+                               OverlayBufferManager *buffer_manager,
                                uint32_t pipe_id, uint32_t crtc_id)
     : Headless(gpu_fd, pipe_id, crtc_id),
       output_handle_(0),
       acquire_fence_(-1),
-      buffer_handler_(buffer_handler),
+      buffer_manager_(buffer_manager),
       width_(0),
       height_(0) {
 }
@@ -58,7 +59,6 @@ bool VirtualDisplay::GetActiveConfig(uint32_t *config) {
 bool VirtualDisplay::Present(std::vector<HwcLayer *> &source_layers) {
   CTRACE();
   std::vector<OverlayLayer> layers;
-  std::vector<OverlayBuffer> buffers;
   std::vector<HwcRect<int>> layers_rects;
   std::vector<size_t> index;
   int ret = 0;
@@ -77,10 +77,8 @@ bool VirtualDisplay::Present(std::vector<HwcLayer *> &source_layers) {
     overlay_layer.SetAcquireFence(layer->acquire_fence.Release());
     layers_rects.emplace_back(layer->GetDisplayFrame());
     index.emplace_back(layer_index);
-    buffers.emplace_back();
-    OverlayBuffer *buffer = new OverlayBuffer();
-    buffer->InitializeFromNativeHandle(layer->GetNativeHandle(),
-                                       buffer_handler_);
+    ImportedBuffer *buffer =
+        buffer_manager_->CreateBufferFromNativeHandle(layer->GetNativeHandle());
     overlay_layer.SetBuffer(buffer);
   }
 
@@ -91,7 +89,7 @@ bool VirtualDisplay::Present(std::vector<HwcLayer *> &source_layers) {
 
   int retire_fence;
   // Prepare for final composition.
-  if (!compositor_.DrawOffscreen(layers, layers_rects, index, buffer_handler_,
+  if (!compositor_.DrawOffscreen(layers, layers_rects, index, buffer_manager_,
                                  width_, height_, output_handle_,
                                  &retire_fence)) {
     ETRACE("Failed to prepare for the frame composition ret=%d", ret);
index 608e069..86df66a 100644 (file)
 
 #include "headless.h"
 
-#include <nativebufferhandler.h>
-
 #include <vector>
 
 #include "compositor.h"
 
 namespace hwcomposer {
 struct HwcLayer;
+class OverlayBufferManager;
 
 class VirtualDisplay : public Headless {
  public:
-  VirtualDisplay(uint32_t gpu_fd, NativeBufferHandler *buffer_handler,
+  VirtualDisplay(uint32_t gpu_fd, OverlayBufferManager *buffer_manager,
                  uint32_t pipe_id, uint32_t crtc_id);
   ~VirtualDisplay() override;
 
@@ -45,7 +44,7 @@ class VirtualDisplay : public Headless {
  private:
   HWCNativeHandle output_handle_;
   int32_t acquire_fence_;
-  NativeBufferHandler *buffer_handler_;
+  OverlayBufferManager *buffer_manager_;
   Compositor compositor_;
   uint32_t width_;
   uint32_t height_;
index 4d411be..b53de82 100644 (file)
@@ -31,7 +31,7 @@ typedef struct _drmModeModeInfo drmModeModeInfo;
 namespace hwcomposer {
 struct HwcLayer;
 class GpuDevice;
-class NativeBufferHandler;
+class OverlayBufferManager;
 
 class VsyncCallback {
  public:
@@ -45,7 +45,7 @@ class NativeDisplay {
   virtual ~NativeDisplay() {
   }
 
-  virtual bool Initialize() = 0;
+  virtual bool Initialize(OverlayBufferManager *buffer_manager) = 0;
 
   virtual DisplayType Type() const = 0;
 
@@ -91,8 +91,7 @@ class NativeDisplay {
  protected:
   virtual uint32_t CrtcId() const = 0;
   virtual bool Connect(const drmModeModeInfo &mode_info,
-                       const drmModeConnector *connector,
-                       NativeBufferHandler *buffer_handler) = 0;
+                       const drmModeConnector *connector) = 0;
 
   virtual bool IsConnected() const = 0;