OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/exo/wayland/server.h" | 5 #include "components/exo/wayland/server.h" |
6 | 6 |
7 #include <alpha-compositing-unstable-v1-server-protocol.h> | 7 #include <alpha-compositing-unstable-v1-server-protocol.h> |
8 #include <gaming-input-unstable-v1-server-protocol.h> | 8 #include <gaming-input-unstable-v1-server-protocol.h> |
9 #include <gaming-input-unstable-v2-server-protocol.h> | 9 #include <gaming-input-unstable-v2-server-protocol.h> |
10 #include <grp.h> | 10 #include <grp.h> |
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 const auto& inserted = linux_buffer_params->planes.insert( | 646 const auto& inserted = linux_buffer_params->planes.insert( |
647 std::pair<uint32_t, LinuxBufferParams::Plane>(plane_idx, | 647 std::pair<uint32_t, LinuxBufferParams::Plane>(plane_idx, |
648 std::move(plane))); | 648 std::move(plane))); |
649 if (!inserted.second) { // The plane was already there. | 649 if (!inserted.second) { // The plane was already there. |
650 wl_resource_post_error(resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET, | 650 wl_resource_post_error(resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET, |
651 "plane already set"); | 651 "plane already set"); |
652 return; | 652 return; |
653 } | 653 } |
654 } | 654 } |
655 | 655 |
| 656 bool ValidateLinuxBufferParams(wl_resource* resource, |
| 657 int32_t width, |
| 658 int32_t height, |
| 659 gfx::BufferFormat format, |
| 660 uint32_t flags) { |
| 661 if (width <= 0 || height <= 0) { |
| 662 wl_resource_post_error(resource, |
| 663 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS, |
| 664 "invalid width or height"); |
| 665 return false; |
| 666 } |
| 667 |
| 668 if (flags & (ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT | |
| 669 ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED)) { |
| 670 wl_resource_post_error(resource, |
| 671 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, |
| 672 "flags not supported"); |
| 673 return false; |
| 674 } |
| 675 |
| 676 LinuxBufferParams* linux_buffer_params = |
| 677 GetUserDataAs<LinuxBufferParams>(resource); |
| 678 size_t num_planes = gfx::NumberOfPlanesForBufferFormat(format); |
| 679 |
| 680 for (uint32_t i = 0; i < num_planes; ++i) { |
| 681 auto plane_it = linux_buffer_params->planes.find(i); |
| 682 if (plane_it == linux_buffer_params->planes.end()) { |
| 683 wl_resource_post_error(resource, |
| 684 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, |
| 685 "missing a plane"); |
| 686 return false; |
| 687 } |
| 688 } |
| 689 |
| 690 if (linux_buffer_params->planes.size() != num_planes) { |
| 691 wl_resource_post_error(resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX, |
| 692 "plane idx out of bounds"); |
| 693 return false; |
| 694 } |
| 695 |
| 696 return true; |
| 697 } |
| 698 |
656 void linux_buffer_params_create(wl_client* client, | 699 void linux_buffer_params_create(wl_client* client, |
657 wl_resource* resource, | 700 wl_resource* resource, |
658 int32_t width, | 701 int32_t width, |
659 int32_t height, | 702 int32_t height, |
660 uint32_t format, | 703 uint32_t format, |
661 uint32_t flags) { | 704 uint32_t flags) { |
662 if (width <= 0 || height <= 0) { | |
663 wl_resource_post_error(resource, | |
664 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS, | |
665 "invalid width or height"); | |
666 return; | |
667 } | |
668 | |
669 const auto* supported_format = std::find_if( | 705 const auto* supported_format = std::find_if( |
670 std::begin(dmabuf_supported_formats), std::end(dmabuf_supported_formats), | 706 std::begin(dmabuf_supported_formats), std::end(dmabuf_supported_formats), |
671 [format](const dmabuf_supported_format& supported_format) { | 707 [format](const dmabuf_supported_format& supported_format) { |
672 return supported_format.dmabuf_format == format; | 708 return supported_format.dmabuf_format == format; |
673 }); | 709 }); |
674 if (supported_format == std::end(dmabuf_supported_formats)) { | 710 if (supported_format == std::end(dmabuf_supported_formats)) { |
675 wl_resource_post_error(resource, | 711 wl_resource_post_error(resource, |
676 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT, | 712 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT, |
677 "format not supported"); | 713 "format not supported"); |
678 return; | 714 return; |
679 } | 715 } |
680 | 716 |
681 if (flags & (ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT | | 717 if (!ValidateLinuxBufferParams(resource, width, height, |
682 ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED)) { | 718 supported_format->buffer_format, flags)) |
683 wl_resource_post_error(resource, | |
684 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, | |
685 "flags not supported"); | |
686 return; | 719 return; |
687 } | |
688 | 720 |
689 LinuxBufferParams* linux_buffer_params = | 721 LinuxBufferParams* linux_buffer_params = |
690 GetUserDataAs<LinuxBufferParams>(resource); | 722 GetUserDataAs<LinuxBufferParams>(resource); |
691 | 723 |
692 size_t num_planes = | 724 size_t num_planes = |
693 gfx::NumberOfPlanesForBufferFormat(supported_format->buffer_format); | 725 gfx::NumberOfPlanesForBufferFormat(supported_format->buffer_format); |
694 | 726 |
695 if (linux_buffer_params->planes.size() != num_planes) { | |
696 wl_resource_post_error(resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX, | |
697 "plane idx out of bounds"); | |
698 return; | |
699 } | |
700 | |
701 std::vector<gfx::NativePixmapPlane> planes; | 727 std::vector<gfx::NativePixmapPlane> planes; |
702 std::vector<base::ScopedFD> fds; | 728 std::vector<base::ScopedFD> fds; |
703 | 729 |
704 for (uint32_t i = 0; i < num_planes; ++i) { | 730 for (uint32_t i = 0; i < num_planes; ++i) { |
705 auto plane_it = linux_buffer_params->planes.find(i); | 731 auto plane_it = linux_buffer_params->planes.find(i); |
706 if (plane_it == linux_buffer_params->planes.end()) { | |
707 wl_resource_post_error(resource, | |
708 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, | |
709 "missing a plane"); | |
710 return; | |
711 } | |
712 LinuxBufferParams::Plane& plane = plane_it->second; | 732 LinuxBufferParams::Plane& plane = plane_it->second; |
713 planes.emplace_back(plane.stride, plane.offset, 0, 0); | 733 planes.emplace_back(plane.stride, plane.offset, 0, 0); |
714 fds.push_back(std::move(plane.fd)); | 734 fds.push_back(std::move(plane.fd)); |
715 } | 735 } |
716 | 736 |
717 std::unique_ptr<Buffer> buffer = | 737 std::unique_ptr<Buffer> buffer = |
718 linux_buffer_params->display->CreateLinuxDMABufBuffer( | 738 linux_buffer_params->display->CreateLinuxDMABufBuffer( |
719 gfx::Size(width, height), supported_format->buffer_format, planes, | 739 gfx::Size(width, height), supported_format->buffer_format, planes, |
720 std::move(fds)); | 740 std::move(fds)); |
721 if (!buffer) { | 741 if (!buffer) { |
722 zwp_linux_buffer_params_v1_send_failed(resource); | 742 zwp_linux_buffer_params_v1_send_failed(resource); |
723 return; | 743 return; |
724 } | 744 } |
725 | 745 |
726 wl_resource* buffer_resource = | 746 wl_resource* buffer_resource = |
727 wl_resource_create(client, &wl_buffer_interface, 1, 0); | 747 wl_resource_create(client, &wl_buffer_interface, 1, 0); |
728 | 748 |
729 buffer->set_release_callback(base::Bind(&HandleBufferReleaseCallback, | 749 buffer->set_release_callback(base::Bind(&HandleBufferReleaseCallback, |
730 base::Unretained(buffer_resource))); | 750 base::Unretained(buffer_resource))); |
731 | 751 |
732 SetImplementation(buffer_resource, &buffer_implementation, std::move(buffer)); | 752 SetImplementation(buffer_resource, &buffer_implementation, std::move(buffer)); |
733 | 753 |
734 zwp_linux_buffer_params_v1_send_created(resource, buffer_resource); | 754 zwp_linux_buffer_params_v1_send_created(resource, buffer_resource); |
735 } | 755 } |
736 | 756 |
| 757 void linux_buffer_params_create_immed(wl_client* client, |
| 758 wl_resource* resource, |
| 759 uint32_t buffer_id, |
| 760 int32_t width, |
| 761 int32_t height, |
| 762 uint32_t format, |
| 763 uint32_t flags) { |
| 764 const auto* supported_format = std::find_if( |
| 765 std::begin(dmabuf_supported_formats), std::end(dmabuf_supported_formats), |
| 766 [format](const dmabuf_supported_format& supported_format) { |
| 767 return supported_format.dmabuf_format == format; |
| 768 }); |
| 769 if (supported_format == std::end(dmabuf_supported_formats)) { |
| 770 wl_resource_post_error(resource, |
| 771 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT, |
| 772 "format not supported"); |
| 773 return; |
| 774 } |
| 775 |
| 776 if (!ValidateLinuxBufferParams(resource, width, height, |
| 777 supported_format->buffer_format, flags)) |
| 778 return; |
| 779 |
| 780 LinuxBufferParams* linux_buffer_params = |
| 781 GetUserDataAs<LinuxBufferParams>(resource); |
| 782 |
| 783 size_t num_planes = |
| 784 gfx::NumberOfPlanesForBufferFormat(supported_format->buffer_format); |
| 785 |
| 786 std::vector<gfx::NativePixmapPlane> planes; |
| 787 std::vector<base::ScopedFD> fds; |
| 788 |
| 789 for (uint32_t i = 0; i < num_planes; ++i) { |
| 790 auto plane_it = linux_buffer_params->planes.find(i); |
| 791 LinuxBufferParams::Plane& plane = plane_it->second; |
| 792 planes.emplace_back(plane.stride, plane.offset, 0, 0); |
| 793 fds.push_back(std::move(plane.fd)); |
| 794 } |
| 795 |
| 796 std::unique_ptr<Buffer> buffer = |
| 797 linux_buffer_params->display->CreateLinuxDMABufBuffer( |
| 798 gfx::Size(width, height), supported_format->buffer_format, planes, |
| 799 std::move(fds)); |
| 800 if (!buffer) { |
| 801 // On import failure in case of a create_immed request, the protocol |
| 802 // allows us to raise a fatal error from zwp_linux_dmabuf_v1 version 2+. |
| 803 wl_resource_post_error(resource, |
| 804 ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER, |
| 805 "dmabuf import failed"); |
| 806 return; |
| 807 } |
| 808 |
| 809 wl_resource* buffer_resource = |
| 810 wl_resource_create(client, &wl_buffer_interface, 1, buffer_id); |
| 811 |
| 812 buffer->set_release_callback(base::Bind(&HandleBufferReleaseCallback, |
| 813 base::Unretained(buffer_resource))); |
| 814 |
| 815 SetImplementation(buffer_resource, &buffer_implementation, std::move(buffer)); |
| 816 } |
| 817 |
737 const struct zwp_linux_buffer_params_v1_interface | 818 const struct zwp_linux_buffer_params_v1_interface |
738 linux_buffer_params_implementation = {linux_buffer_params_destroy, | 819 linux_buffer_params_implementation = { |
739 linux_buffer_params_add, | 820 linux_buffer_params_destroy, linux_buffer_params_add, |
740 linux_buffer_params_create}; | 821 linux_buffer_params_create, linux_buffer_params_create_immed}; |
741 | 822 |
742 //////////////////////////////////////////////////////////////////////////////// | 823 //////////////////////////////////////////////////////////////////////////////// |
743 // linux_dmabuf_interface: | 824 // linux_dmabuf_interface: |
744 | 825 |
745 void linux_dmabuf_destroy(wl_client* client, wl_resource* resource) { | 826 void linux_dmabuf_destroy(wl_client* client, wl_resource* resource) { |
746 wl_resource_destroy(resource); | 827 wl_resource_destroy(resource); |
747 } | 828 } |
748 | 829 |
749 void linux_dmabuf_create_params(wl_client* client, | 830 void linux_dmabuf_create_params(wl_client* client, |
750 wl_resource* resource, | 831 wl_resource* resource, |
751 uint32_t id) { | 832 uint32_t id) { |
752 std::unique_ptr<LinuxBufferParams> linux_buffer_params = | 833 std::unique_ptr<LinuxBufferParams> linux_buffer_params = |
753 base::MakeUnique<LinuxBufferParams>(GetUserDataAs<Display>(resource)); | 834 base::MakeUnique<LinuxBufferParams>(GetUserDataAs<Display>(resource)); |
754 | 835 |
755 wl_resource* linux_buffer_params_resource = | 836 wl_resource* linux_buffer_params_resource = |
756 wl_resource_create(client, &zwp_linux_buffer_params_v1_interface, 1, id); | 837 wl_resource_create(client, &zwp_linux_buffer_params_v1_interface, 2, id); |
757 | 838 |
758 SetImplementation(linux_buffer_params_resource, | 839 SetImplementation(linux_buffer_params_resource, |
759 &linux_buffer_params_implementation, | 840 &linux_buffer_params_implementation, |
760 std::move(linux_buffer_params)); | 841 std::move(linux_buffer_params)); |
761 } | 842 } |
762 | 843 |
763 const struct zwp_linux_dmabuf_v1_interface linux_dmabuf_implementation = { | 844 const struct zwp_linux_dmabuf_v1_interface linux_dmabuf_implementation = { |
764 linux_dmabuf_destroy, linux_dmabuf_create_params}; | 845 linux_dmabuf_destroy, linux_dmabuf_create_params}; |
765 | 846 |
766 void bind_linux_dmabuf(wl_client* client, | 847 void bind_linux_dmabuf(wl_client* client, |
767 void* data, | 848 void* data, |
768 uint32_t version, | 849 uint32_t version, |
769 uint32_t id) { | 850 uint32_t id) { |
770 wl_resource* resource = | 851 wl_resource* resource = |
771 wl_resource_create(client, &zwp_linux_dmabuf_v1_interface, 1, id); | 852 wl_resource_create(client, &zwp_linux_dmabuf_v1_interface, version, id); |
772 | 853 |
773 wl_resource_set_implementation(resource, &linux_dmabuf_implementation, data, | 854 wl_resource_set_implementation(resource, &linux_dmabuf_implementation, data, |
774 nullptr); | 855 nullptr); |
775 | 856 |
776 for (const auto& supported_format : dmabuf_supported_formats) | 857 for (const auto& supported_format : dmabuf_supported_formats) |
777 zwp_linux_dmabuf_v1_send_format(resource, supported_format.dmabuf_format); | 858 zwp_linux_dmabuf_v1_send_format(resource, supported_format.dmabuf_format); |
778 } | 859 } |
779 | 860 |
780 #endif | 861 #endif |
781 | 862 |
(...skipping 3154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3936 // Server, public: | 4017 // Server, public: |
3937 | 4018 |
3938 Server::Server(Display* display) | 4019 Server::Server(Display* display) |
3939 : display_(display), wl_display_(wl_display_create()) { | 4020 : display_(display), wl_display_(wl_display_create()) { |
3940 wl_global_create(wl_display_.get(), &wl_compositor_interface, | 4021 wl_global_create(wl_display_.get(), &wl_compositor_interface, |
3941 compositor_version, display_, bind_compositor); | 4022 compositor_version, display_, bind_compositor); |
3942 wl_global_create(wl_display_.get(), &wl_shm_interface, 1, display_, bind_shm); | 4023 wl_global_create(wl_display_.get(), &wl_shm_interface, 1, display_, bind_shm); |
3943 #if defined(USE_OZONE) | 4024 #if defined(USE_OZONE) |
3944 wl_global_create(wl_display_.get(), &wl_drm_interface, drm_version, display_, | 4025 wl_global_create(wl_display_.get(), &wl_drm_interface, drm_version, display_, |
3945 bind_drm); | 4026 bind_drm); |
3946 wl_global_create(wl_display_.get(), &zwp_linux_dmabuf_v1_interface, 1, | 4027 wl_global_create(wl_display_.get(), &zwp_linux_dmabuf_v1_interface, 2, |
3947 display_, bind_linux_dmabuf); | 4028 display_, bind_linux_dmabuf); |
3948 #endif | 4029 #endif |
3949 wl_global_create(wl_display_.get(), &wl_subcompositor_interface, 1, display_, | 4030 wl_global_create(wl_display_.get(), &wl_subcompositor_interface, 1, display_, |
3950 bind_subcompositor); | 4031 bind_subcompositor); |
3951 wl_global_create(wl_display_.get(), &wl_shell_interface, 1, display_, | 4032 wl_global_create(wl_display_.get(), &wl_shell_interface, 1, display_, |
3952 bind_shell); | 4033 bind_shell); |
3953 wl_global_create(wl_display_.get(), &wl_output_interface, output_version, | 4034 wl_global_create(wl_display_.get(), &wl_output_interface, output_version, |
3954 display_, bind_output); | 4035 display_, bind_output); |
3955 wl_global_create(wl_display_.get(), &xdg_shell_interface, 1, display_, | 4036 wl_global_create(wl_display_.get(), &xdg_shell_interface, 1, display_, |
3956 bind_xdg_shell_v5); | 4037 bind_xdg_shell_v5); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4048 DCHECK(event_loop); | 4129 DCHECK(event_loop); |
4049 wl_event_loop_dispatch(event_loop, timeout.InMilliseconds()); | 4130 wl_event_loop_dispatch(event_loop, timeout.InMilliseconds()); |
4050 } | 4131 } |
4051 | 4132 |
4052 void Server::Flush() { | 4133 void Server::Flush() { |
4053 wl_display_flush_clients(wl_display_.get()); | 4134 wl_display_flush_clients(wl_display_.get()); |
4054 } | 4135 } |
4055 | 4136 |
4056 } // namespace wayland | 4137 } // namespace wayland |
4057 } // namespace exo | 4138 } // namespace exo |
OLD | NEW |