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

Commit 04c73d23 authored by Daniel Nicoara's avatar Daniel Nicoara
Browse files

VR: Pass display size in the HWC observer callback

1) Unify the places where primary display size is queried.
2) Allows virtual displays to have a different size than the primary
display and the size propagates properly to VR HWC and its observer.

Bug: None
Test: Unittest and manually on device
Change-Id: I7e026c4f9b018d47ca400247beed27841d71c806
parent ba4a3dbc
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -19,6 +19,12 @@ status_t ParcelableComposerFrame::writeToParcel(Parcel* parcel) const {
  status_t ret = parcel->writeUint64(frame_.display_id);
  if (ret != OK) return ret;

  ret = parcel->writeInt32(frame_.display_width);
  if (ret != OK) return ret;

  ret = parcel->writeInt32(frame_.display_height);
  if (ret != OK) return ret;

  ret = parcel->writeBool(frame_.removed);
  if (ret != OK) return ret;

@@ -35,6 +41,12 @@ status_t ParcelableComposerFrame::readFromParcel(const Parcel* parcel) {
  status_t ret = parcel->readUint64(&frame_.display_id);
  if (ret != OK) return ret;

  ret = parcel->readInt32(&frame_.display_width);
  if (ret != OK) return ret;

  ret = parcel->readInt32(&frame_.display_height);
  if (ret != OK) return ret;

  ret = parcel->readBool(&frame_.removed);
  if (ret != OK) return ret;

+4 −0
Original line number Diff line number Diff line
@@ -104,6 +104,8 @@ TEST_F(VrComposerTest, TestWithOneLayer) {
  ComposerView::Frame frame;
  frame.display_id = 1;
  frame.removed = false;
  frame.display_width = 600;
  frame.display_height = 400;
  frame.layers.push_back(ComposerView::ComposerLayer{
    .id = 1,
    .buffer = CreateBuffer(),
@@ -120,6 +122,8 @@ TEST_F(VrComposerTest, TestWithOneLayer) {

  ComposerView::Frame received_frame = callback->last_frame();
  ASSERT_EQ(frame.display_id, received_frame.display_id);
  ASSERT_EQ(frame.display_width, received_frame.display_width);
  ASSERT_EQ(frame.display_height, received_frame.display_height);
  ASSERT_EQ(frame.removed, received_frame.removed);
  ASSERT_EQ(1u, received_frame.layers.size());
  ASSERT_EQ(frame.layers[0].id, received_frame.layers[0].id);
+44 −29
Original line number Diff line number Diff line
@@ -81,9 +81,35 @@ sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
  return buffer;
}

void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
  *width = 1080;
  *height = 1920;

  int error = 0;
  auto display_client = DisplayClient::Create(&error);
  SystemDisplayMetrics metrics;

  if (error) {
    ALOGE("Could not connect to display service : %s(%d)", strerror(error),
          error);
    return;
  }

  error = display_client->GetDisplayMetrics(&metrics);
  if (error) {
    ALOGE("Could not get display metrics from display service : %s(%d)",
          strerror(error), error);
    return;
  }

  *width = metrics.display_native_width;
  *height = metrics.display_native_height;
}

}  // namespace

HwcDisplay::HwcDisplay() {}
HwcDisplay::HwcDisplay(int32_t width, int32_t height)
    : width_(width), height_(height) {}

HwcDisplay::~HwcDisplay() {}

@@ -222,7 +248,7 @@ std::vector<Layer> HwcDisplay::UpdateLastFrameAndGetLastFrameLayers() {
////////////////////////////////////////////////////////////////////////////////
// VrHwcClient

VrHwc::VrHwc() { displays_[kDefaultDisplayId].reset(new HwcDisplay()); }
VrHwc::VrHwc() {}

VrHwc::~VrHwc() {}

@@ -235,6 +261,14 @@ void VrHwc::removeClient() {

void VrHwc::enableCallback(bool enable) {
  if (enable && client_ != nullptr) {
    {
      int32_t width, height;
      GetPrimaryDisplaySize(&width, &height);
      std::lock_guard<std::mutex> guard(mutex_);
      // Create the primary display late to avoid initialization issues between
      // VR HWC and SurfaceFlinger.
      displays_[kDefaultDisplayId].reset(new HwcDisplay(width, height));
    }
    client_.promote()->onHotplug(kDefaultDisplayId,
                                 IComposerCallback::Connection::CONNECTED);
  }
@@ -246,7 +280,7 @@ Error VrHwc::createVirtualDisplay(uint32_t width, uint32_t height,
                                  PixelFormat* format, Display* outDisplay) {
  *format = PixelFormat::RGBA_8888;
  *outDisplay = display_count_;
  displays_[display_count_].reset(new HwcDisplay());
  displays_[display_count_].reset(new HwcDisplay(width, height));
  display_count_++;
  return Error::NONE;
}
@@ -308,41 +342,20 @@ Error VrHwc::getDisplayAttribute(Display display, Config config,
                                 IComposerClient::Attribute attribute,
                                 int32_t* outValue) {
  std::lock_guard<std::mutex> guard(mutex_);
  if (!FindDisplay(display))
  auto display_ptr = FindDisplay(display);
  if (!display_ptr) {
    return Error::BAD_DISPLAY;
  }
  if (config != kDefaultConfigId) {
    return Error::BAD_CONFIG;
  }

  int error = 0;
  auto display_client = DisplayClient::Create(&error);
  SystemDisplayMetrics metrics;

  if (error) {
    ALOGE("Could not connect to display service : %s(%d)", strerror(error),
          error);
  } else {
    error = display_client->GetDisplayMetrics(&metrics);

    if (error) {
      ALOGE("Could not get display metrics from display service : %s(%d)",
            strerror(error), error);
    }
  }

  if (error) {
    metrics.display_native_width = 1080;
    metrics.display_native_height = 1920;
    ALOGI("Setting display metrics to default : width=%d height=%d",
          metrics.display_native_width, metrics.display_native_height);
  }

  switch (attribute) {
    case IComposerClient::Attribute::WIDTH:
      *outValue = metrics.display_native_width;
      *outValue = display_ptr->width();
      break;
    case IComposerClient::Attribute::HEIGHT:
      *outValue = metrics.display_native_height;
      *outValue = display_ptr->height();
      break;
    case IComposerClient::Attribute::VSYNC_PERIOD:
      *outValue = 1000 * 1000 * 1000 / 30;  // 30fps
@@ -510,6 +523,8 @@ Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,
  std::vector<Layer> last_frame_layers;
  Error status = display_ptr->GetFrame(&frame.layers);
  frame.display_id = display;
  frame.display_width = display_ptr->width();
  frame.display_height = display_ptr->height();
  if (status != Error::NONE)
    return status;

+9 −1
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ class ComposerView {
    // being removed, or left false in the case of a normal frame. The upper
    // layer tracks display IDs and will handle new ones showing up.
    bool removed = false;
    int32_t display_width;
    int32_t display_height;
    std::vector<ComposerLayer> layers;
  };

@@ -107,9 +109,12 @@ struct HwcLayer {

class HwcDisplay {
 public:
  HwcDisplay();
  HwcDisplay(int32_t width, int32_t height);
  ~HwcDisplay();

  int32_t width() const { return width_; }
  int32_t height() const { return height_; }

  HwcLayer* CreateLayer();
  bool DestroyLayer(Layer id);
  HwcLayer* GetLayer(Layer id);
@@ -138,6 +143,9 @@ class HwcDisplay {
  // Layer ID generator.
  uint64_t layer_ids_ = 1;

  int32_t width_;
  int32_t height_;

  HwcDisplay(const HwcDisplay&) = delete;
  void operator=(const HwcDisplay&) = delete;
};
+2 −2
Original line number Diff line number Diff line
@@ -168,8 +168,7 @@ void DisplayView::SetPrograms(ShaderProgram* program,

void DisplayView::DrawEye(EyeType /* eye */, const mat4& perspective,
                          const mat4& eye_matrix, const mat4& head_matrix,
                          const vec2& size, float fade_value) {
  size_ = size;
                          float fade_value) {
  scale_ = GetScalingMatrix(size_.x(), size_.y());

  DrawOverlays(perspective, eye_matrix, head_matrix, fade_value);
@@ -204,6 +203,7 @@ void DisplayView::OnDrawFrame(SurfaceFlingerView* surface_flinger_view,
base::unique_fd DisplayView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame,
                                     bool debug_mode, bool is_vr_active,
                                     bool* showing) {
  size_ = vec2(frame->display_width(), frame->display_height());
  uint32_t app = current_vr_app_;
  ViewMode visibility = CalculateVisibilityFromLayerConfig(*frame.get(), &app);

Loading