vrwm: Fix controller input/rendering mismatch
This works for portrait mode only for now. Landscape phones present
some weird buffer sizes (1080x1080) that get scaled incorrectly for
input
This also removes all of our older hacks, such as swapping
width/height in SurfaceFlingerView and the swap + invert of touch
input. A global 90 degree rotation is applied to present the portrait
buffers in the correct orientation
vr_wm_ctl has a command to stack another rotation on top of the
existing ones in order to facilitate development for now. Apps will
likely show up rotated, "vr_wm_ctl rotate 1" will fix it, or -1 if
it needs to be rotated the other way.
Bug: None
Test: Manual with permissions and calculator
Change-Id: Ifd31b444b944fbf3085613349caae37e817538f6
(cherry picked from commit eb49c451cbc5de7bbe5ba440dc8e43291daa6d4e)
diff --git a/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl b/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl
index 67fd927..b16049f 100644
--- a/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl
+++ b/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl
@@ -25,5 +25,6 @@
void exitVrMode() = 3;
void setDebugMode(int mode) = 4;
void set2DMode(int mode) = 5;
+ void setRotation(int angle) = 6;
}
diff --git a/services/vr/vr_window_manager/display_view.cpp b/services/vr/vr_window_manager/display_view.cpp
index e88e7d0..311e27f 100644
--- a/services/vr/vr_window_manager/display_view.cpp
+++ b/services/vr/vr_window_manager/display_view.cpp
@@ -146,16 +146,18 @@
DisplayView::DisplayView(uint32_t id, int touchpad_id)
: id_(id), touchpad_id_(touchpad_id) {
- translate_ = Eigen::Translation3f(0, 0, -2.5f);
+ translate_ = Eigen::Translation3f(0, 0, -5.0f);
ime_translate_ = mat4(Eigen::Translation3f(0.0f, -0.5f, 0.25f));
ime_top_left_ = vec2(0, 0);
ime_size_ = vec2(0, 0);
+ rotation_ = mat4::Identity();
}
DisplayView::~DisplayView() {}
void DisplayView::Recenter(const mat4& initial) {
- initial_head_matrix_ = initial;
+ initial_head_matrix_ =
+ initial * Eigen::AngleAxisf(M_PI * 0.5f, vec3::UnitZ());
}
void DisplayView::SetPrograms(ShaderProgram* program,
@@ -248,7 +250,7 @@
bool DisplayView::IsHit(const vec3& view_location, const vec3& view_direction,
vec3* hit_location, vec2* hit_location_in_window_coord,
bool test_ime) {
- mat4 m = initial_head_matrix_ * translate_;
+ mat4 m = GetStandardTransform();
if (test_ime)
m = m * ime_translate_;
mat4 inverse = (m * scale_).inverse();
@@ -314,8 +316,7 @@
mat4 layer_transform =
GetLayerTransform(texture_layer, size_.x(), size_.y());
- mat4 transform =
- initial_head_matrix_ * translate_ * scale_ * layer_transform;
+ mat4 transform = GetStandardTransform() * scale_ * layer_transform;
DrawWithTransform(transform, *program_);
glDisable(GL_BLEND);
@@ -351,14 +352,21 @@
}
}
+mat4 DisplayView::GetStandardTransform() {
+ mat4 m = initial_head_matrix_ * rotation_ * translate_;
+ if (current_frame_.visibility == ViewMode::App)
+ m *= Eigen::AngleAxisf(M_PI * -0.5f, vec3::UnitZ());
+ return m;
+}
+
void DisplayView::DrawIme() {
program_->Use();
glBindTexture(GL_TEXTURE_2D, ime_texture_.texture->id());
mat4 layer_transform = GetLayerTransform(ime_texture_, size_.x(), size_.y());
- mat4 transform = initial_head_matrix_ * translate_ * ime_translate_ * scale_ *
- layer_transform;
+ mat4 transform =
+ GetStandardTransform() * ime_translate_ * scale_ * layer_transform;
DrawWithTransform(transform, *program_);
}
@@ -377,7 +385,7 @@
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
mat4 layer_transform = GetLayerTransform(layer, size_.x(), size_.y());
- mat4 transform = initial_head_matrix_ * translate_ * scale_ * layer_transform;
+ mat4 transform = GetStandardTransform() * scale_ * layer_transform;
DrawWithTransform(transform, *overlay_program_);
glDisable(GL_BLEND);
}
diff --git a/services/vr/vr_window_manager/display_view.h b/services/vr/vr_window_manager/display_view.h
index 0d1355e..aaf4677 100644
--- a/services/vr/vr_window_manager/display_view.h
+++ b/services/vr/vr_window_manager/display_view.h
@@ -47,6 +47,8 @@
void set_2dmode(bool mode) { use_2dmode_ = mode; }
void set_always_2d(bool mode) { always_2d_ = mode; }
+ void set_rotation(const mat4& rotation) { rotation_ = rotation; }
+
private:
bool IsHit(const vec3& view_location, const vec3& view_direction,
vec3* hit_location, vec2* hit_location_in_window_coord,
@@ -60,6 +62,9 @@
const vec2& top_left, const vec2& bottom_right);
void DrawWithTransform(const mat4& transform, const ShaderProgram& program);
+ // This is the rotated, translated but unscaled transform to apply everywhere.
+ mat4 GetStandardTransform();
+
uint32_t id_;
int touchpad_id_;
@@ -72,6 +77,7 @@
mat4 scale_;
mat4 translate_;
mat4 ime_translate_;
+ mat4 rotation_;
vec2 size_;
std::vector<TextureLayer> textures_;
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index fba599f..3aae228 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -205,6 +205,12 @@
displays_[0]->set_2dmode(mode);
}
+void ShellView::SetRotation(int angle) {
+ mat4 m(Eigen::AngleAxisf(M_PI * -0.5f * angle, vec3::UnitZ()));
+ for (auto& d: displays_)
+ d->set_rotation(m);
+}
+
void ShellView::OnDrawFrame() {
bool visible = false;
@@ -323,10 +329,6 @@
size_ = vec2(surface_flinger_view_->width(), surface_flinger_view_->height());
- // TODO(alexst): Replicate controller rendering from VR Home.
- // Current approach in the function below is a quick visualization.
- DrawController(perspective, eye_matrix, head_matrix);
-
for (auto& display : displays_) {
if (display->visible()) {
display->DrawEye(eye, perspective, eye_matrix, head_matrix, size_,
@@ -334,6 +336,10 @@
}
}
+ // TODO(alexst): Replicate controller rendering from VR Home.
+ // Current approach in the function below is a quick visualization.
+ DrawController(perspective, eye_matrix, head_matrix);
+
DrawReticle(perspective, eye_matrix, head_matrix);
}
@@ -476,12 +482,14 @@
const vec2& hit_location = active_display_->hit_location();
+ float x = hit_location.x() / size_.x();
+ float y = hit_location.y() / size_.y();
+
// Device is portrait, but in landscape when in VR.
// Rotate touch input appropriately.
const android::status_t status = dvrVirtualTouchpadTouch(
virtual_touchpad_.get(), active_display_->touchpad_id(),
- 1.0f - hit_location.y() / size_.y(), hit_location.x() / size_.x(),
- is_touching_ ? 1.0f : 0.0f);
+ x, y, is_touching_ ? 1.0f : 0.0f);
if (status != OK) {
ALOGE("touch failed: %d", status);
}
diff --git a/services/vr/vr_window_manager/shell_view.h b/services/vr/vr_window_manager/shell_view.h
index d265866..8548dc1 100644
--- a/services/vr/vr_window_manager/shell_view.h
+++ b/services/vr/vr_window_manager/shell_view.h
@@ -34,6 +34,7 @@
void VrMode(bool mode) override;
void dumpInternal(String8& result) override;
void Set2DMode(bool mode) override;
+ void SetRotation(int angle) override;
protected:
diff --git a/services/vr/vr_window_manager/shell_view_binder_interface.h b/services/vr/vr_window_manager/shell_view_binder_interface.h
index 9f77e5a..c66e4a1 100644
--- a/services/vr/vr_window_manager/shell_view_binder_interface.h
+++ b/services/vr/vr_window_manager/shell_view_binder_interface.h
@@ -13,6 +13,7 @@
virtual void VrMode(bool mode) = 0;
virtual void dumpInternal(String8& result) = 0;
virtual void Set2DMode(bool mode) = 0;
+ virtual void SetRotation(int angle) = 0;
};
} // namespace dvr
diff --git a/services/vr/vr_window_manager/surface_flinger_view.cpp b/services/vr/vr_window_manager/surface_flinger_view.cpp
index 427ad70..7ecc542 100644
--- a/services/vr/vr_window_manager/surface_flinger_view.cpp
+++ b/services/vr/vr_window_manager/surface_flinger_view.cpp
@@ -59,9 +59,8 @@
ALOGI("Setting display metrics to default : width=%d height=%d", metrics.display_native_height, metrics.display_native_width);
}
- // TODO(alexst): Refactor ShellView to account for orientation and change this back.
- width_ = metrics.display_native_height;
- height_ = metrics.display_native_width;
+ width_ = metrics.display_native_width;
+ height_ = metrics.display_native_height;
return true;
}
diff --git a/services/vr/vr_window_manager/vr_window_manager_binder.cpp b/services/vr/vr_window_manager/vr_window_manager_binder.cpp
index 8868588..fdcb8b2 100644
--- a/services/vr/vr_window_manager/vr_window_manager_binder.cpp
+++ b/services/vr/vr_window_manager/vr_window_manager_binder.cpp
@@ -138,6 +138,11 @@
return binder::Status::ok();
}
+binder::Status VrWindowManagerBinder::setRotation(int32_t angle) {
+ app_.SetRotation(angle);
+ return binder::Status::ok();
+}
+
status_t VrWindowManagerBinder::dump(
int fd, const Vector<String16>& args [[gnu::unused]]) {
String8 result;
diff --git a/services/vr/vr_window_manager/vr_window_manager_binder.h b/services/vr/vr_window_manager/vr_window_manager_binder.h
index 1915ffc..9d0f0b2 100644
--- a/services/vr/vr_window_manager/vr_window_manager_binder.h
+++ b/services/vr/vr_window_manager/vr_window_manager_binder.h
@@ -60,6 +60,7 @@
::android::binder::Status exitVrMode() override;
::android::binder::Status setDebugMode(int32_t mode) override;
::android::binder::Status set2DMode(int32_t mode) override;
+ ::android::binder::Status setRotation(int32_t angle) override;
// Implements BBinder::dump().
status_t dump(int fd, const Vector<String16>& args) override;
diff --git a/services/vr/vr_window_manager/vr_wm_ctl.cpp b/services/vr/vr_window_manager/vr_wm_ctl.cpp
index 2e5c488..758e02b 100644
--- a/services/vr/vr_window_manager/vr_wm_ctl.cpp
+++ b/services/vr/vr_window_manager/vr_wm_ctl.cpp
@@ -41,6 +41,8 @@
exit(report(vrwm->setDebugMode(atoi(argv[2]))));
} else if ((argc == 3) && (strcmp(argv[1], "2d") == 0)) {
exit(report(vrwm->set2DMode(atoi(argv[2]))));
+ } else if ((argc == 3) && (strcmp(argv[1], "rotate") == 0)) {
+ exit(report(vrwm->setRotation(atoi(argv[2]))));
} else {
usage();
exit(2);