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

Commit a4c03a0a authored by Daniel Nicoara's avatar Daniel Nicoara Committed by android-build-merger
Browse files

Remove vr_wm service (try 2)

am: 007b00e7

Change-Id: Ib5794017f2c0ac8ef48db94d15a597b97b23246b
parents d00f1007 007b00e7
Loading
Loading
Loading
Loading
+0 −101
Original line number Diff line number Diff line
// Copyright (C) 2016 The Android Open Source Project
//
// 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.

native_src = [
    "application.cpp",
    "controller_mesh.cpp",
    "elbow_model.cpp",
    "hwc_callback.cpp",
    "reticle.cpp",
    "shell_view.cpp",
    "surface_flinger_view.cpp",
    "texture.cpp",
    "vr_window_manager.cpp",
    "vr_window_manager_binder.cpp",
    "aidl/android/service/vr/IVrWindowManager.aidl",
    "display_view.cpp",
]

static_libs = [
    "libdisplay",
    "libbufferhub",
    "libbufferhubqueue",
    "libdvrgraphics",
    "libdvrcommon",
    "libhwcomposer-client",
    "libvrsensor",
    "libperformance",
    "libpdx_default_transport",
    "libcutils",
    "libvr_hwc-binder",
    "libvr_manager",
    "libvirtualtouchpadclient",
]

shared_libs = [
    "android.frameworks.vr.composer@1.0",
    "android.hardware.graphics.composer@2.1",
    "libbase",
    "libbinder",
    "libinput",
    "libhardware",
    "libhwbinder",
    "libsync",
    "libutils",
    "libgui",
    "libEGL",
    "libGLESv2",
    "libvulkan",
    "libsync",
    "libui",
    "libhidlbase",
    "libhidltransport",
    "liblog",
    "libvr_hwc-hal",
]

cc_binary {
    srcs: native_src,
    static_libs: static_libs,
    shared_libs: shared_libs,
    cflags: ["-DGL_GLEXT_PROTOTYPES", "-DEGL_EGLEXT_PROTOTYPES", "-DLOG_TAG=\"VrWindowManager\""],
    host_ldlibs: ["-llog"],
    name: "vr_wm",
    tags: ["optional"],
    init_rc: ["vr_wm.rc"],
}

cmd_src = [
    "vr_wm_ctl.cpp",
    "aidl/android/service/vr/IVrWindowManager.aidl",
]

staticLibs = ["libcutils"]

sharedLibs = [
    "libbase",
    "libbinder",
    "libutils",
]

cc_binary {
    srcs: cmd_src,
    static_libs: staticLibs,
    shared_libs: sharedLibs,
    cppflags: ["-std=c++11"],
    cflags: ["-DLOG_TAG=\"vrwmctl\""],
    host_ldlibs: ["-llog"],
    name: "vr_wm_ctl",
    tags: ["optional"],
}
+0 −30
Original line number Diff line number Diff line
/**
 * Copyright (c) 2017, The Android Open Source Project
 *
 * 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.
 */

package android.service.vr;

/** @hide */
interface IVrWindowManager {
    const String SERVICE_NAME = "vr_window_manager";
    void connectController(in FileDescriptor fd) = 0;
    void disconnectController() = 1;
    void enterVrMode() = 2;
    void exitVrMode() = 3;
    void setDebugMode(int mode) = 4;
    void set2DMode(int mode) = 5;
    void setRotation(int angle) = 6;
}
+0 −330
Original line number Diff line number Diff line
#include "application.h"

#include <inttypes.h>
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <binder/IServiceManager.h>
#include <dvr/graphics.h>
#include <dvr/performance_client_api.h>
#include <dvr/pose_client.h>
#include <gui/ISurfaceComposer.h>
#include <hardware/hwcomposer_defs.h>
#include <log/log.h>
#include <private/dvr/graphics/vr_gl_extensions.h>

#include <vector>

namespace android {
namespace dvr {

Application::Application() {
  vr_mode_listener_ = new VrModeListener(this);
}

Application::~Application() {
  sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
      defaultServiceManager()->getService(String16("vrmanager")));
  if (vrManagerService.get()) {
    vrManagerService->unregisterPersistentVrStateListener(vr_mode_listener_);
  }
}

int Application::Initialize() {
  dvrSetCpuPartition(0, "/application/performance");

  bool is_right_handed = true;  // TODO: retrieve setting from system
  elbow_model_.Enable(ElbowModel::kDefaultNeckPosition, is_right_handed);
  last_frame_time_ = std::chrono::system_clock::now();

  sp<IVrManager> vrManagerService = interface_cast<IVrManager>(
      defaultServiceManager()->getService(String16("vrmanager")));
  if (vrManagerService.get()) {
    vrManagerService->registerPersistentVrStateListener(vr_mode_listener_);
  }
  return 0;
}

int Application::AllocateResources() {
  int surface_width = 0, surface_height = 0;
  DvrLensInfo lens_info = {};
  GLuint texture_id = 0;
  GLenum texture_target = 0;
  std::vector<DvrSurfaceParameter> surface_params = {
    DVR_SURFACE_PARAMETER_OUT(SURFACE_WIDTH, &surface_width),
    DVR_SURFACE_PARAMETER_OUT(SURFACE_HEIGHT, &surface_height),
    DVR_SURFACE_PARAMETER_OUT(INTER_LENS_METERS, &lens_info.inter_lens_meters),
    DVR_SURFACE_PARAMETER_OUT(LEFT_FOV_LRBT, &lens_info.left_fov),
    DVR_SURFACE_PARAMETER_OUT(RIGHT_FOV_LRBT, &lens_info.right_fov),
    DVR_SURFACE_PARAMETER_OUT(SURFACE_TEXTURE_TARGET_TYPE, &texture_target),
    DVR_SURFACE_PARAMETER_OUT(SURFACE_TEXTURE_TARGET_ID, &texture_id),
    DVR_SURFACE_PARAMETER_IN(VISIBLE, 0),
    DVR_SURFACE_PARAMETER_IN(Z_ORDER, 1),
    DVR_SURFACE_PARAMETER_IN(GEOMETRY, DVR_SURFACE_GEOMETRY_SINGLE),
    DVR_SURFACE_PARAMETER_IN(ENABLE_LATE_LATCH, 0),
    DVR_SURFACE_PARAMETER_IN(DISABLE_DISTORTION, 0),
    DVR_SURFACE_PARAMETER_LIST_END,
  };

  int ret = dvrGraphicsContextCreate(surface_params.data(), &graphics_context_);
  if (ret)
    return ret;

  GLuint fbo = 0;
  GLuint depth_stencil_buffer = 0;
  GLuint samples = 1;
  glGenFramebuffers(1, &fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                       texture_target, texture_id, 0, samples);

  glGenRenderbuffers(1, &depth_stencil_buffer);
  glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil_buffer);
  glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                                   GL_DEPTH_COMPONENT24, surface_width,
                                   surface_height);

  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                            GL_RENDERBUFFER, depth_stencil_buffer);

  ALOGI("Surface size=%dx%d", surface_width, surface_height);
  pose_client_ = dvrPoseCreate();
  if (!pose_client_)
    return 1;

  vec2i eye_size(surface_width / 2, surface_height);

  eye_viewport_[0] = Range2i::FromSize(vec2i(0, 0), eye_size);
  eye_viewport_[1] = Range2i::FromSize(vec2i(surface_width / 2, 0), eye_size);

  eye_from_head_[0] = Eigen::Translation3f(
      vec3(lens_info.inter_lens_meters * 0.5f, 0.0f, 0.0f));
  eye_from_head_[1] = Eigen::Translation3f(
      vec3(-lens_info.inter_lens_meters * 0.5f, 0.0f, 0.0f));

  fov_[0] = FieldOfView(lens_info.left_fov[0], lens_info.left_fov[1],
                        lens_info.left_fov[2], lens_info.left_fov[3]);
  fov_[1] = FieldOfView(lens_info.right_fov[0], lens_info.right_fov[1],
                        lens_info.right_fov[2], lens_info.right_fov[3]);

  return 0;
}

void Application::DeallocateResources() {
  if (graphics_context_)
    dvrGraphicsContextDestroy(graphics_context_);
  graphics_context_ = nullptr;

  if (pose_client_)
    dvrPoseDestroy(pose_client_);

  initialized_ = false;
}

void Application::ProcessTasks(const std::vector<MainThreadTask>& tasks) {
  for (auto task : tasks) {
    switch (task) {
      case MainThreadTask::EnableDebugMode:
        if (!debug_mode_) {
          debug_mode_ = true;
          SetVisibility(debug_mode_);
        }
        break;
      case MainThreadTask::DisableDebugMode:
        if (debug_mode_) {
          debug_mode_ = false;
          SetVisibility(debug_mode_);
        }
        break;
      case MainThreadTask::EnteringVrMode:
        if (!initialized_) {
          LOG_ALWAYS_FATAL_IF(AllocateResources(),
                              "Failed to allocate resources");
        }
        break;
      case MainThreadTask::ExitingVrMode:
        if (initialized_)
          DeallocateResources();
        break;
      case MainThreadTask::Show:
        if (!is_visible_)
          SetVisibility(true);
        break;
    }
  }
}

void Application::DrawFrame() {
  // Thread should block if we are invisible or not fully initialized.
  std::unique_lock<std::mutex> lock(mutex_);
  wake_up_init_and_render_.wait(lock, [this]() {
    return (is_visible_ && initialized_) || !main_thread_tasks_.empty();
  });

  // Process main thread tasks if there are any.
  std::vector<MainThreadTask> tasks;
  tasks.swap(main_thread_tasks_);
  lock.unlock();

  if (!tasks.empty())
    ProcessTasks(tasks);

  if (!initialized_)
    return;

  // TODO(steventhomas): If we're not visible, block until we are. For now we
  // throttle by calling dvrGraphicsWaitNextFrame.
  DvrFrameSchedule schedule;
  int status = dvrGraphicsWaitNextFrame(graphics_context_, 0, &schedule);
  if (status < 0) {
    ALOGE("Context lost, deallocating graphics resources");
    SetVisibility(false);
    DeallocateResources();
  }

  OnDrawFrame();

  if (is_visible_) {
    ProcessControllerInput();

    DvrPoseAsync pose;
    dvrPoseGet(pose_client_, schedule.vsync_count, &pose);
    last_pose_ = Posef(
        quat(pose.orientation[3], pose.orientation[0], pose.orientation[1],
             pose.orientation[2]),
        vec3(pose.translation[0], pose.translation[1], pose.translation[2]));

    std::chrono::time_point<std::chrono::system_clock> now =
        std::chrono::system_clock::now();
    double delta =
        std::chrono::duration<double>(now - last_frame_time_).count();
    last_frame_time_ = now;

    if (delta > 1.0f)
      delta = 0.05f;

    fade_value_ += delta / 0.25f;
    if (fade_value_ > 1.0f)
      fade_value_ = 1.0f;

    controller_position_ =
        elbow_model_.Update(delta, last_pose_.GetRotation(),
                            controller_orientation_, should_recenter_);

    dvrBeginRenderFrameEds(graphics_context_, pose.orientation,
                           pose.translation);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    mat4 head_matrix = last_pose_.GetObjectFromReferenceMatrix();
    glViewport(eye_viewport_[kLeftEye].GetMinPoint()[0],
               eye_viewport_[kLeftEye].GetMinPoint()[1],
               eye_viewport_[kLeftEye].GetSize()[0],
               eye_viewport_[kLeftEye].GetSize()[1]);
    DrawEye(kLeftEye, fov_[kLeftEye].GetProjectionMatrix(0.1f, 500.0f),
            eye_from_head_[kLeftEye], head_matrix);

    glViewport(eye_viewport_[kRightEye].GetMinPoint()[0],
               eye_viewport_[kRightEye].GetMinPoint()[1],
               eye_viewport_[kRightEye].GetSize()[0],
               eye_viewport_[kRightEye].GetSize()[1]);
    DrawEye(kRightEye, fov_[kRightEye].GetProjectionMatrix(0.1f, 500.0f),
            eye_from_head_[kRightEye], head_matrix);

    OnEndFrame();

    dvrPresent(graphics_context_);
    should_recenter_ = false;
  }
}

void Application::ProcessControllerInput() {
  if (controller_data_provider_) {
    shmem_controller_active_ = false;
    const void* data = controller_data_provider_->LockControllerData();
    // TODO(kpschoedel): define wire format.
    if (data) {
      struct wire_format {
        uint32_t version;
        uint32_t timestamph;
        uint32_t timestampl;
        uint32_t quat_count;
        float q[4];
        uint32_t buttonsh;
        uint32_t buttonsl;
      } __attribute__((__aligned__(32)));
      const wire_format* wire_data = static_cast<const wire_format*>(data);
      static uint64_t last_timestamp = 0;
      if (wire_data->version == 1) {
        shmem_controller_active_ = true;
        uint64_t timestamp =
            (((uint64_t)wire_data->timestamph) << 32) | wire_data->timestampl;
        if (timestamp == last_timestamp) {
          static uint64_t last_logged_timestamp = 0;
          if (last_logged_timestamp != last_timestamp) {
            last_logged_timestamp = last_timestamp;
            ALOGI("Controller shmem stale T=0x%" PRIX64, last_timestamp);
          }
        } else {
          last_timestamp = timestamp;
          controller_orientation_ = quat(wire_data->q[3], wire_data->q[0],
                                         wire_data->q[1], wire_data->q[2]);
          shmem_controller_buttons_ =
              (((uint64_t)wire_data->buttonsh) << 32) | wire_data->buttonsl;
        }
      } else if (wire_data->version == 0xFEEDFACE) {
        static bool logged_init = false;
        if (!logged_init) {
          logged_init = true;
          ALOGI("Controller shmem waiting for data");
        }
      }
    }
    controller_data_provider_->UnlockControllerData();
    if (shmem_controller_active_) {
      ALOGV("Controller shmem orientation: %f %f %f %f",
            controller_orientation_.x(), controller_orientation_.y(),
            controller_orientation_.z(), controller_orientation_.w());
      if (shmem_controller_buttons_) {
        ALOGV("Controller shmem buttons: %017" PRIX64,
            shmem_controller_buttons_);
      }
    }
  }
}

void Application::SetVisibility(bool visible) {
  if (visible && !initialized_) {
    if (AllocateResources())
      ALOGE("Failed to allocate resources");
  }

  bool changed = is_visible_ != visible;
  if (changed) {
    is_visible_ = visible;
    dvrGraphicsSurfaceSetVisible(graphics_context_, is_visible_);
    OnVisibilityChanged(is_visible_);
  }
}

void Application::OnVisibilityChanged(bool visible) {
  if (visible) {
    fade_value_ = 0;
    // We have been sleeping so to ensure correct deltas, reset the time.
    last_frame_time_ = std::chrono::system_clock::now();
  }
}

void Application::QueueTask(MainThreadTask task) {
  std::unique_lock<std::mutex> lock(mutex_);
  main_thread_tasks_.push_back(task);
  wake_up_init_and_render_.notify_one();
}

void Application::VrModeListener::onPersistentVrStateChanged(bool enabled) {
  if (!enabled)
    app_->QueueTask(MainThreadTask::ExitingVrMode);
}

}  // namespace dvr
}  // namespace android
+0 −111
Original line number Diff line number Diff line
#ifndef VR_WINDOW_MANAGER_APPLICATION_H_
#define VR_WINDOW_MANAGER_APPLICATION_H_

#include <memory>
#include <private/dvr/types.h>
#include <stdint.h>
#include <vr/vr_manager/vr_manager.h>

#include <chrono>
#include <mutex>
#include <vector>

#include "controller_data_provider.h"
#include "elbow_model.h"

struct DvrGraphicsContext;
struct DvrPose;

namespace android {
namespace dvr {

class Application {
 public:
  Application();
  virtual ~Application();

  virtual int Initialize();

  virtual int AllocateResources();
  virtual void DeallocateResources();

  void DrawFrame();

  void SetControllerDataProvider(ControllerDataProvider* provider) {
    controller_data_provider_ = provider;
  }

 protected:
  enum class MainThreadTask {
    EnteringVrMode,
    ExitingVrMode,
    EnableDebugMode,
    DisableDebugMode,
    Show,
  };

  class VrModeListener : public BnPersistentVrStateCallbacks {
   public:
    VrModeListener(Application *app) : app_(app) {}
    void onPersistentVrStateChanged(bool enabled) override;

   private:
    Application *app_;
  };

  sp<VrModeListener> vr_mode_listener_;
  virtual void OnDrawFrame() = 0;
  virtual void DrawEye(EyeType eye, const mat4& perspective,
                       const mat4& eye_matrix, const mat4& head_matrix) = 0;
  virtual void OnEndFrame() = 0;

  void SetVisibility(bool visible);
  virtual void OnVisibilityChanged(bool visible);

  void ProcessControllerInput();

  void ProcessTasks(const std::vector<MainThreadTask>& tasks);

  void QueueTask(MainThreadTask task);

  DvrGraphicsContext* graphics_context_ = nullptr;
  DvrPose* pose_client_ = nullptr;

  Range2i eye_viewport_[2];
  mat4 eye_from_head_[2];
  FieldOfView fov_[2];
  Posef last_pose_;

  quat controller_orientation_;
  bool shmem_controller_active_ = false;
  uint64_t shmem_controller_buttons_;

  // Used to center the scene when the shell becomes visible.
  bool should_recenter_ = true;

  bool is_visible_ = false;
  std::chrono::time_point<std::chrono::system_clock> visibility_button_press_;
  bool debug_mode_ = false;

  std::chrono::time_point<std::chrono::system_clock> last_frame_time_;
  vec3 controller_position_;
  ElbowModel elbow_model_;

  float fade_value_ = 0;

  std::mutex mutex_;
  std::condition_variable wake_up_init_and_render_;
  bool initialized_ = false;
  std::vector<MainThreadTask> main_thread_tasks_;

  // Controller data provider from shared memory buffer.
  ControllerDataProvider* controller_data_provider_ = nullptr;

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

}  // namespace dvr
}  // namespace android

#endif  // VR_WINDOW_MANAGER_APPLICATION_H_
+0 −19
Original line number Diff line number Diff line
#ifndef VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_
#define VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_

namespace android {
namespace dvr {

class ControllerDataProvider {
 public:
  virtual ~ControllerDataProvider() {}
  // Returns data pointer or nullptr. If pointer is valid, call to
  // UnlockControllerData is required.
  virtual const void* LockControllerData() = 0;
  virtual void UnlockControllerData() = 0;
};

}  // namespace dvr
}  // namespace android

#endif  // VR_WINDOW_MANAGER_CONTROLLER_DATA_PROVIDER_H_
 No newline at end of file
Loading