Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3819afa4 authored by Corey Tabaka's avatar Corey Tabaka Committed by android-build-merger
Browse files

Merge "Use the HWC caching mechanism to avoid stalls in the ion driver." into oc-mr1-dev

am: 17209ec9

Change-Id: I44d7f54d46628de1dc5bbe4d5bd681cfde434f23
parents a5a62b78 17209ec9
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -9,8 +9,8 @@ namespace android {
namespace dvr {

AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
                               LocalHandle acquire_fence)
    : buffer_(buffer), acquire_fence_(std::move(acquire_fence)) {}
                               LocalHandle acquire_fence, std::size_t slot)
    : buffer_(buffer), acquire_fence_(std::move(acquire_fence)), slot_(slot) {}

AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
                               int* error) {
@@ -31,18 +31,20 @@ AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
  }
}

AcquiredBuffer::AcquiredBuffer(AcquiredBuffer&& other)
    : buffer_(std::move(other.buffer_)),
      acquire_fence_(std::move(other.acquire_fence_)) {}
AcquiredBuffer::AcquiredBuffer(AcquiredBuffer&& other) {
  *this = std::move(other);
}

AcquiredBuffer::~AcquiredBuffer() { Release(LocalHandle(kEmptyFence)); }

AcquiredBuffer& AcquiredBuffer::operator=(AcquiredBuffer&& other) {
  if (this != &other) {
    Release(LocalHandle(kEmptyFence));
    Release();

    buffer_ = std::move(other.buffer_);
    acquire_fence_ = std::move(other.acquire_fence_);
    using std::swap;
    swap(buffer_, other.buffer_);
    swap(acquire_fence_, other.acquire_fence_);
    swap(slot_, other.slot_);
  }
  return *this;
}
@@ -81,8 +83,6 @@ int AcquiredBuffer::Release(LocalHandle release_fence) {
  ALOGD_IF(TRACE, "AcquiredBuffer::Release: buffer_id=%d release_fence=%d",
           buffer_ ? buffer_->id() : -1, release_fence.Get());
  if (buffer_) {
    // Close the release fence since we can't transfer it with an async release.
    release_fence.Close();
    const int ret = buffer_->ReleaseAsync();
    if (ret < 0) {
      ALOGE("AcquiredBuffer::Release: Failed to release buffer %d: %s",
@@ -92,9 +92,10 @@ int AcquiredBuffer::Release(LocalHandle release_fence) {
    }

    buffer_ = nullptr;
    acquire_fence_.Close();
  }

  acquire_fence_.Close();
  slot_ = 0;
  return 0;
}

+7 −2
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ class AcquiredBuffer {
  // this constructor; the constructor does not attempt to ACQUIRE the buffer
  // itself.
  AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
                 pdx::LocalHandle acquire_fence);
                 pdx::LocalHandle acquire_fence, std::size_t slot = 0);

  // Constructs an AcquiredBuffer from a BufferConsumer. The BufferConsumer MUST
  // be in the POSTED state prior to calling this constructor, as this
@@ -64,13 +64,18 @@ class AcquiredBuffer {
  // to the producer. On success, the BufferConsumer and acquire fence are set
  // to empty state; if release fails, the BufferConsumer and acquire fence are
  // left in place and a negative error code is returned.
  int Release(pdx::LocalHandle release_fence);
  int Release(pdx::LocalHandle release_fence = {});

  // Returns the slot in the queue this buffer belongs to. Buffers that are not
  // part of a queue return 0.
  std::size_t slot() const { return slot_; }

 private:
  std::shared_ptr<BufferConsumer> buffer_;
  // Mutable so that the fence can be closed when it is determined to be
  // signaled during IsAvailable().
  mutable pdx::LocalHandle acquire_fence_;
  std::size_t slot_{0};

  AcquiredBuffer(const AcquiredBuffer&) = delete;
  void operator=(const AcquiredBuffer&) = delete;
+1 −1
Original line number Diff line number Diff line
@@ -382,7 +382,7 @@ void DirectDisplaySurface::DequeueBuffersLocked() {
    }

    acquired_buffers_.Append(
        AcquiredBuffer(buffer_consumer, std::move(acquire_fence)));
        AcquiredBuffer(buffer_consumer, std::move(acquire_fence), slot));
  }
}

+26 −4
Original line number Diff line number Diff line
@@ -605,7 +605,7 @@ int HardwareComposer::PostThreadPollInterruptible(
  } else if (pfd[0].revents != 0) {
    return 0;
  } else if (pfd[1].revents != 0) {
    ALOGI("VrHwcPost thread interrupted");
    ALOGI("VrHwcPost thread interrupted: revents=%x", pfd[1].revents);
    return kPostThreadInterrupted;
  } else {
    return 0;
@@ -1069,6 +1069,7 @@ void Layer::Reset() {
  acquire_fence_.Close();
  surface_rect_functions_applied_ = false;
  pending_visibility_settings_ = true;
  cached_buffer_map_.clear();
}

Layer::Layer(const std::shared_ptr<DirectDisplaySurface>& surface,
@@ -1112,6 +1113,7 @@ Layer& Layer::operator=(Layer&& other) {
    swap(surface_rect_functions_applied_,
         other.surface_rect_functions_applied_);
    swap(pending_visibility_settings_, other.pending_visibility_settings_);
    swap(cached_buffer_map_, other.cached_buffer_map_);
  }
  return *this;
}
@@ -1205,15 +1207,30 @@ void Layer::CommonLayerSetup() {
  UpdateLayerSettings();
}

bool Layer::CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id) {
  auto search = cached_buffer_map_.find(slot);
  if (search != cached_buffer_map_.end() && search->second == buffer_id)
    return true;

  // Assign or update the buffer slot.
  if (buffer_id >= 0)
    cached_buffer_map_[slot] = buffer_id;
  return false;
}

void Layer::Prepare() {
  int right, bottom;
  int right, bottom, id;
  sp<GraphicBuffer> handle;
  std::size_t slot;

  // Acquire the next buffer according to the type of source.
  IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) {
    std::tie(right, bottom, handle, acquire_fence_) = source.Acquire();
    std::tie(right, bottom, id, handle, acquire_fence_, slot) =
        source.Acquire();
  });

  TRACE_FORMAT("Layer::Prepare|buffer_id=%d;slot=%zu|", id, slot);

  // Update any visibility (blending, z-order) changes that occurred since
  // last prepare.
  UpdateVisibilitySettings();
@@ -1243,10 +1260,15 @@ void Layer::Prepare() {
          composition_type_.cast<Hwc2::IComposerClient::Composition>());
    }

    // See if the HWC cache already has this buffer.
    const bool cached = CheckAndUpdateCachedBuffer(slot, id);
    if (cached)
      handle = nullptr;

    HWC::Error error{HWC::Error::None};
    error =
        composer_->setLayerBuffer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
                                  0, handle, acquire_fence_.Get());
                                  slot, handle, acquire_fence_.Get());

    ALOGE_IF(error != HWC::Error::None,
             "Layer::Prepare: Error setting layer buffer: %s",
+27 −10
Original line number Diff line number Diff line
@@ -161,6 +161,14 @@ class Layer {
  // Applies visibility settings that may have changed.
  void UpdateVisibilitySettings();

  // Checks whether the buffer, given by id, is associated with the given slot
  // in the HWC buffer cache. If the slot is not associated with the given
  // buffer the cache is updated to establish the association and the buffer
  // should be sent to HWC using setLayerBuffer. Returns true if the association
  // was already established, false if not. A buffer_id of -1 is never
  // associated and always returns false.
  bool CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id);

  // Composer instance shared by all instances of Layer. This must be set
  // whenever a new instance of the Composer is created. This may be set to
  // nullptr as long as there are no instances of Layer that might need to use
@@ -198,19 +206,21 @@ class Layer {
    // the previous buffer is returned or an empty value if no buffer has ever
    // been posted. When a new buffer is acquired the previous buffer's release
    // fence is passed out automatically.
    std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() {
    std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t>
    Acquire() {
      if (surface->IsBufferAvailable()) {
        acquired_buffer.Release(std::move(release_fence));
        acquired_buffer = surface->AcquireCurrentBuffer();
        ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id());
      }
      if (!acquired_buffer.IsEmpty()) {
        return std::make_tuple(acquired_buffer.buffer()->width(),
                               acquired_buffer.buffer()->height(),
        return std::make_tuple(
            acquired_buffer.buffer()->width(),
            acquired_buffer.buffer()->height(), acquired_buffer.buffer()->id(),
            acquired_buffer.buffer()->buffer()->buffer(),
                               acquired_buffer.ClaimAcquireFence());
            acquired_buffer.ClaimAcquireFence(), acquired_buffer.slot());
      } else {
        return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{});
        return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0);
      }
    }

@@ -242,12 +252,13 @@ class Layer {
  struct SourceBuffer {
    std::shared_ptr<IonBuffer> buffer;

    std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() {
    std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t>
    Acquire() {
      if (buffer)
        return std::make_tuple(buffer->width(), buffer->height(),
                               buffer->buffer(), pdx::LocalHandle{});
        return std::make_tuple(buffer->width(), buffer->height(), -1,
                               buffer->buffer(), pdx::LocalHandle{}, 0);
      else
        return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{});
        return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0);
    }

    void Finish(pdx::LocalHandle /*fence*/) {}
@@ -266,6 +277,12 @@ class Layer {
  bool surface_rect_functions_applied_ = false;
  bool pending_visibility_settings_ = true;

  // Map of buffer slot assignments that have already been established with HWC:
  // slot -> buffer_id. When this map contains a matching slot and buffer_id the
  // buffer argument to setLayerBuffer may be nullptr to avoid the cost of
  // importing a buffer HWC already knows about.
  std::map<std::size_t, int> cached_buffer_map_;

  Layer(const Layer&) = delete;
  void operator=(const Layer&) = delete;
};