Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell_gl.cc

Issue 2840183003: VR: Route hover and click events to UI elements. (Closed)
Patch Set: Offer both OnButtonDown() and OnButtonUp(), rather than a combined OnClick() Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell_gl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h" 5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h"
6 6
7 #include <chrono> 7 #include <chrono>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 if (touch_pending_ || 529 if (touch_pending_ ||
530 controller_->ButtonUpHappened( 530 controller_->ButtonUpHappened(
531 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { 531 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
532 touch_pending_ = false; 532 touch_pending_ = false;
533 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( 533 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent(
534 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers, 534 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers,
535 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); 535 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF()));
536 gesture->source_device = blink::kWebGestureDeviceTouchpad; 536 gesture->source_device = blink::kWebGestureDeviceTouchpad;
537 gesture->x = 0; 537 gesture->x = 0;
538 gesture->y = 0; 538 gesture->y = 0;
539 SendGesture(InputTarget::CONTENT, std::move(gesture)); 539 SendGestureToContent(std::move(gesture));
540 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; 540 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture";
541 } 541 }
542 } 542 }
543 543
544 gfx::Vector3dF ergo_neutral_pose; 544 gfx::Vector3dF ergo_neutral_pose;
545 if (!controller_->IsConnected()) { 545 if (!controller_->IsConnected()) {
546 // No controller detected, set up a gaze cursor that tracks the 546 // No controller detected, set up a gaze cursor that tracks the
547 // forward direction. 547 // forward direction.
548 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; 548 ergo_neutral_pose = {0.0f, 0.0f, -1.0f};
549 controller_quat_ = GetRotationFromZAxis(forward_vector); 549 controller_quat_ = GetRotationFromZAxis(forward_vector);
(...skipping 29 matching lines...) Expand all
579 // simplicity. 579 // simplicity.
580 float distance = scene_->GetBackgroundDistance(); 580 float distance = scene_->GetBackgroundDistance();
581 target_point_ = 581 target_point_ =
582 vr::GetRayPoint(kHandPosition, controller_direction, distance); 582 vr::GetRayPoint(kHandPosition, controller_direction, distance);
583 gfx::Vector3dF eye_to_target = target_point_ - kOrigin; 583 gfx::Vector3dF eye_to_target = target_point_ - kOrigin;
584 vr::NormalizeVector(&eye_to_target); 584 vr::NormalizeVector(&eye_to_target);
585 585
586 // Determine which UI element (if any) intersects the line between the eyes 586 // Determine which UI element (if any) intersects the line between the eyes
587 // and the controller target position. 587 // and the controller target position.
588 float closest_element_distance = (target_point_ - kOrigin).Length(); 588 float closest_element_distance = (target_point_ - kOrigin).Length();
589 previous_target_element_ = target_element_;
589 target_element_ = nullptr; 590 target_element_ = nullptr;
590 float target_x; 591 float target_x;
591 float target_y; 592 float target_y;
592 593
593 for (const auto& plane : scene_->GetUiElements()) { 594 for (auto& plane : scene_->GetUiElements()) {
594 if (!plane->IsHitTestable()) 595 if (!plane->IsHitTestable())
595 continue; 596 continue;
596 597
597 float distance_to_plane; 598 float distance_to_plane;
598 if (!plane->GetRayDistance(kOrigin, eye_to_target, &distance_to_plane)) 599 if (!plane->GetRayDistance(kOrigin, eye_to_target, &distance_to_plane))
599 continue; 600 continue;
600 601
601 if (distance_to_plane < 0 || distance_to_plane >= closest_element_distance) 602 if (distance_to_plane < 0 || distance_to_plane >= closest_element_distance)
602 continue; 603 continue;
603 604
604 gfx::Point3F plane_intersection_point = 605 gfx::Point3F plane_intersection_point =
605 vr::GetRayPoint(kOrigin, eye_to_target, distance_to_plane); 606 vr::GetRayPoint(kOrigin, eye_to_target, distance_to_plane);
606 gfx::PointF unit_xy_point = 607 gfx::PointF unit_xy_point =
607 plane->GetUnitRectangleCoordinates(plane_intersection_point); 608 plane->GetUnitRectangleCoordinates(plane_intersection_point);
608 609
609 float x = 0.5f + unit_xy_point.x(); 610 float x = 0.5f + unit_xy_point.x();
610 float y = 0.5f - unit_xy_point.y(); 611 float y = 0.5f - unit_xy_point.y();
611 if (x < 0.0f || x >= 1.0f || y < 0.0f || y >= 1.0f) 612 if (x < 0.0f || x >= 1.0f || y < 0.0f || y >= 1.0f)
612 continue; 613 continue;
613 614
614 closest_element_distance = distance_to_plane; 615 closest_element_distance = distance_to_plane;
615 target_point_ = plane_intersection_point; 616 target_point_ = plane_intersection_point;
616 target_element_ = plane.get(); 617 target_element_ = plane.get();
617 target_x = x; 618 target_x = x;
618 target_y = y; 619 target_y = y;
619 } 620 }
620 621
621 // Treat UI elements, which do not show web content, as NONE input 622 // Handle input targeting on the content quad, ignoring any other elements.
622 // targets since they cannot make use of the input anyway. 623 // Content is treated specially to accomodate scrolling, flings, etc.
623 InputTarget input_target = InputTarget::NONE; 624 InputTarget input_target = InputTarget::NONE;
624 int pixel_x = 0; 625 int pixel_x = 0;
625 int pixel_y = 0; 626 int pixel_y = 0;
626
627 if (target_element_ != nullptr && target_element_->fill == Fill::CONTENT) { 627 if (target_element_ != nullptr && target_element_->fill == Fill::CONTENT) {
628 input_target = InputTarget::CONTENT; 628 input_target = InputTarget::CONTENT;
629 gfx::RectF pixel_rect(0, 0, content_tex_css_width_, 629 gfx::RectF pixel_rect(0, 0, content_tex_css_width_,
630 content_tex_css_height_); 630 content_tex_css_height_);
631 pixel_x = pixel_rect.x() + pixel_rect.width() * target_x; 631 pixel_x = pixel_rect.x() + pixel_rect.width() * target_x;
632 pixel_y = pixel_rect.y() + pixel_rect.height() * target_y; 632 pixel_y = pixel_rect.y() + pixel_rect.height() * target_y;
633 } 633 }
634 SendEventsToTarget(input_target, pixel_x, pixel_y); 634 SendInputToContent(input_target, pixel_x, pixel_y);
635
636 // Handle input targeting on all non-content elements.
637 SendInputToUiElements(target_element_);
635 } 638 }
636 639
637 void VrShellGl::HandleControllerAppButtonActivity( 640 void VrShellGl::HandleControllerAppButtonActivity(
638 const gfx::Vector3dF& controller_direction) { 641 const gfx::Vector3dF& controller_direction) {
639 // Note that button up/down state is transient, so ButtonDownHappened only 642 // Note that button up/down state is transient, so ButtonDownHappened only
640 // returns true for a single frame (and we're guaranteed not to miss it). 643 // returns true for a single frame (and we're guaranteed not to miss it).
641 if (controller_->ButtonDownHappened( 644 if (controller_->ButtonDownHappened(
642 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { 645 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) {
643 controller_start_direction_ = controller_direction; 646 controller_start_direction_ = controller_direction;
644 } 647 }
(...skipping 16 matching lines...) Expand all
661 weak_vr_shell_, direction)); 664 weak_vr_shell_, direction));
662 } 665 }
663 } 666 }
664 if (direction == UiInterface::NONE) { 667 if (direction == UiInterface::NONE) {
665 main_thread_task_runner_->PostTask( 668 main_thread_task_runner_->PostTask(
666 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_)); 669 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_));
667 } 670 }
668 } 671 }
669 } 672 }
670 673
671 void VrShellGl::SendEventsToTarget(InputTarget input_target, 674 void VrShellGl::SendInputToContent(InputTarget input_target,
672 int pixel_x, 675 int pixel_x,
673 int pixel_y) { 676 int pixel_y) {
674 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = 677 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list =
675 controller_->DetectGestures(); 678 controller_->DetectGestures();
676 double timestamp = gesture_list.front()->TimeStampSeconds(); 679 double timestamp = gesture_list.front()->TimeStampSeconds();
677 680
678 if (touch_pending_) { 681 if (touch_pending_) {
679 touch_pending_ = false; 682 touch_pending_ = false;
680 std::unique_ptr<WebGestureEvent> event( 683 std::unique_ptr<WebGestureEvent> event(
681 new WebGestureEvent(WebInputEvent::kGestureTapDown, 684 new WebGestureEvent(WebInputEvent::kGestureTapDown,
682 WebInputEvent::kNoModifiers, timestamp)); 685 WebInputEvent::kNoModifiers, timestamp));
683 event->source_device = blink::kWebGestureDeviceTouchpad; 686 event->source_device = blink::kWebGestureDeviceTouchpad;
684 event->x = pixel_x; 687 event->x = pixel_x;
685 event->y = pixel_y; 688 event->y = pixel_y;
686 gesture_list.push_back(std::move(event)); 689 gesture_list.push_back(std::move(event));
687 } 690 }
688 691
689 for (auto& gesture : gesture_list) { 692 for (auto& gesture : gesture_list) {
690 gesture->x = pixel_x; 693 gesture->x = pixel_x;
691 gesture->y = pixel_y; 694 gesture->y = pixel_y;
692 auto movableGesture = base::MakeUnique<WebGestureEvent>(*gesture); 695 auto movableGesture = base::MakeUnique<WebGestureEvent>(*gesture);
693 696
694 switch (gesture->GetType()) { 697 switch (gesture->GetType()) {
695 // Once the user starts scrolling send all the scroll events to this 698 // Once the user starts scrolling send all the scroll events to this
696 // element until the scrolling stops. 699 // element until the scrolling stops.
697 case WebInputEvent::kGestureScrollBegin: 700 case WebInputEvent::kGestureScrollBegin:
698 current_scroll_target_ = input_target; 701 current_scroll_target_ = input_target;
699 if (current_scroll_target_ != InputTarget::NONE) { 702 if (current_scroll_target_ != InputTarget::NONE) {
700 SendGesture(current_scroll_target_, std::move(movableGesture)); 703 SendGestureToContent(std::move(movableGesture));
701 } 704 }
702 break; 705 break;
703 case WebInputEvent::kGestureScrollEnd: 706 case WebInputEvent::kGestureScrollEnd:
704 if (current_scroll_target_ != InputTarget::NONE) { 707 if (current_scroll_target_ != InputTarget::NONE) {
705 SendGesture(current_scroll_target_, std::move(movableGesture)); 708 SendGestureToContent(std::move(movableGesture));
706 } 709 }
707 current_fling_target_ = current_scroll_target_; 710 current_fling_target_ = current_scroll_target_;
708 current_scroll_target_ = InputTarget::NONE; 711 current_scroll_target_ = InputTarget::NONE;
709 break; 712 break;
710 case WebInputEvent::kGestureScrollUpdate: 713 case WebInputEvent::kGestureScrollUpdate:
711 if (current_scroll_target_ != InputTarget::NONE) { 714 if (current_scroll_target_ != InputTarget::NONE) {
712 SendGesture(current_scroll_target_, std::move(movableGesture)); 715 SendGestureToContent(std::move(movableGesture));
713 } 716 }
714 break; 717 break;
715 case WebInputEvent::kGestureFlingStart: 718 case WebInputEvent::kGestureFlingStart:
716 if (current_fling_target_ != InputTarget::NONE) { 719 if (current_fling_target_ != InputTarget::NONE) {
717 SendGesture(current_fling_target_, std::move(movableGesture)); 720 SendGestureToContent(std::move(movableGesture));
718 } 721 }
719 current_fling_target_ = InputTarget::NONE; 722 current_fling_target_ = InputTarget::NONE;
720 break; 723 break;
721 case WebInputEvent::kGestureFlingCancel: 724 case WebInputEvent::kGestureFlingCancel:
722 current_fling_target_ = InputTarget::NONE; 725 current_fling_target_ = InputTarget::NONE;
723 if (input_target != InputTarget::NONE) { 726 if (input_target != InputTarget::NONE) {
724 SendGesture(input_target, std::move(movableGesture)); 727 SendGestureToContent(std::move(movableGesture));
725 } 728 }
726 break; 729 break;
727 case WebInputEvent::kGestureTapDown: 730 case WebInputEvent::kGestureTapDown:
728 current_fling_target_ = InputTarget::NONE; 731 current_fling_target_ = InputTarget::NONE;
729 if (input_target != InputTarget::NONE) { 732 if (input_target != InputTarget::NONE) {
730 SendGesture(input_target, std::move(movableGesture)); 733 SendGestureToContent(std::move(movableGesture));
731 } 734 }
732 break; 735 break;
733 case WebInputEvent::kUndefined: 736 case WebInputEvent::kUndefined:
734 break; 737 break;
735 default: 738 default:
736 NOTREACHED(); 739 NOTREACHED();
737 } 740 }
738 } 741 }
739 742
740 // Hover support 743 // Hover support
741 bool new_target = input_target != current_input_target_; 744 bool new_target = input_target != current_input_target_;
742 if (new_target && current_input_target_ != InputTarget::NONE) { 745 if (new_target && current_input_target_ != InputTarget::NONE) {
743 // Send a move event indicating that the pointer moved off of an element. 746 // Send a move event indicating that the pointer moved off of an element.
744 SendGesture(current_input_target_, 747 SendGestureToContent(
745 MakeMouseEvent(WebInputEvent::kMouseLeave, timestamp, 0, 0)); 748 MakeMouseEvent(WebInputEvent::kMouseLeave, timestamp, 0, 0));
746 } 749 }
747 current_input_target_ = input_target; 750 current_input_target_ = input_target;
748 if (current_input_target_ != InputTarget::NONE) { 751 if (current_input_target_ != InputTarget::NONE) {
749 WebInputEvent::Type type = 752 WebInputEvent::Type type =
750 new_target ? WebInputEvent::kMouseEnter : WebInputEvent::kMouseMove; 753 new_target ? WebInputEvent::kMouseEnter : WebInputEvent::kMouseMove;
751 SendGesture(input_target, 754 SendGestureToContent(MakeMouseEvent(type, timestamp, pixel_x, pixel_y));
752 MakeMouseEvent(type, timestamp, pixel_x, pixel_y));
753 } 755 }
754 } 756 }
755 757
756 void VrShellGl::SendGesture(InputTarget input_target, 758 void VrShellGl::SendInputToUiElements(UiElement* target_element) {
757 std::unique_ptr<blink::WebInputEvent> event) { 759 if (target_element != previous_target_element_) {
758 DCHECK(input_target != InputTarget::NONE); 760 if (previous_target_element_ &&
761 previous_target_element_->fill != Fill::CONTENT) {
762 task_runner_->PostTask(
763 FROM_HERE, base::Bind(&UiElement::OnHoverLeave,
764 base::Unretained(previous_target_element_)));
765 }
766 if (target_element && target_element->fill != Fill::CONTENT) {
767 task_runner_->PostTask(FROM_HERE,
768 base::Bind(&UiElement::OnHoverEnter,
769 base::Unretained(target_element)));
770 }
771 click_target_element_ = nullptr;
772 }
773 if (target_element && target_element->fill != Fill::CONTENT) {
774 if (controller_->ButtonDownHappened(
775 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
776 task_runner_->PostTask(FROM_HERE,
777 base::Bind(&UiElement::OnButtonDown,
778 base::Unretained(target_element)));
779 click_target_element_ = target_element;
780 }
781 if (controller_->ButtonUpHappened(
782 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
783 if (click_target_element_ == target_element) {
784 task_runner_->PostTask(FROM_HERE,
785 base::Bind(&UiElement::OnButtonUp,
786 base::Unretained(target_element)));
787 }
788 click_target_element_ = nullptr;
789 }
790 }
791 }
792
793 void VrShellGl::SendGestureToContent(
794 std::unique_ptr<blink::WebInputEvent> event) {
759 main_thread_task_runner_->PostTask( 795 main_thread_task_runner_->PostTask(
760 FROM_HERE, base::Bind(&VrShell::ProcessContentGesture, weak_vr_shell_, 796 FROM_HERE, base::Bind(&VrShell::ProcessContentGesture, weak_vr_shell_,
761 base::Passed(std::move(event)))); 797 base::Passed(std::move(event))));
762 } 798 }
763 799
764 void VrShellGl::DrawFrame(int16_t frame_index) { 800 void VrShellGl::DrawFrame(int16_t frame_index) {
765 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); 801 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index);
766 802
767 base::TimeTicks current_time = base::TimeTicks::Now(); 803 base::TimeTicks current_time = base::TimeTicks::Now();
768 804
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 // InitializeGl. Revisit if the initialization order changes. 1361 // InitializeGl. Revisit if the initialization order changes.
1326 device::mojom::VRDisplayInfoPtr info = 1362 device::mojom::VRDisplayInfoPtr info =
1327 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), 1363 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(),
1328 webvr_surface_size_, device_id); 1364 webvr_surface_size_, device_id);
1329 main_thread_task_runner_->PostTask( 1365 main_thread_task_runner_->PostTask(
1330 FROM_HERE, 1366 FROM_HERE,
1331 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); 1367 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info)));
1332 } 1368 }
1333 1369
1334 } // namespace vr_shell 1370 } // namespace vr_shell
OLDNEW
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell_gl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698