• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // ScenicWindow.cpp:
7 //    Implements methods from ScenicWindow
8 //
9 
10 #include "util/fuchsia/ScenicWindow.h"
11 
12 #include <fuchsia/images/cpp/fidl.h>
13 #include <fuchsia/ui/views/cpp/fidl.h>
14 #include <lib/async-loop/cpp/loop.h>
15 #include <lib/fdio/directory.h>
16 #include <lib/fidl/cpp/interface_ptr.h>
17 #include <lib/fidl/cpp/interface_request.h>
18 #include <lib/ui/scenic/cpp/view_token_pair.h>
19 #include <lib/zx/channel.h>
20 #include <zircon/status.h>
21 
22 #include "common/debug.h"
23 
24 namespace
25 {
26 
GetDefaultLoop()27 async::Loop *GetDefaultLoop()
28 {
29     static async::Loop *defaultLoop = new async::Loop(&kAsyncLoopConfigAttachToThread);
30     return defaultLoop;
31 }
32 
ConnectToServiceRoot()33 zx::channel ConnectToServiceRoot()
34 {
35     zx::channel clientChannel;
36     zx::channel serverChannel;
37     zx_status_t result = zx::channel::create(0, &clientChannel, &serverChannel);
38     ASSERT(result == ZX_OK);
39     result = fdio_service_connect("/svc/.", serverChannel.release());
40     ASSERT(result == ZX_OK);
41     return clientChannel;
42 }
43 
44 template <typename Interface>
ConnectToService(zx_handle_t serviceRoot,fidl::InterfaceRequest<Interface> request)45 zx_status_t ConnectToService(zx_handle_t serviceRoot, fidl::InterfaceRequest<Interface> request)
46 {
47     ASSERT(request.is_valid());
48     return fdio_service_connect_at(serviceRoot, Interface::Name_, request.TakeChannel().release());
49 }
50 
51 template <typename Interface>
ConnectToService(zx_handle_t serviceRoot)52 fidl::InterfacePtr<Interface> ConnectToService(zx_handle_t serviceRoot)
53 {
54     fidl::InterfacePtr<Interface> result;
55     ConnectToService(serviceRoot, result.NewRequest());
56     return result;
57 }
58 
59 }  // namespace
60 
ScenicWindow()61 ScenicWindow::ScenicWindow()
62     : mLoop(GetDefaultLoop()),
63       mServiceRoot(ConnectToServiceRoot()),
64       mScenic(ConnectToService<fuchsia::ui::scenic::Scenic>(mServiceRoot.get())),
65       mPresenter(ConnectToService<fuchsia::ui::policy::Presenter>(mServiceRoot.get())),
66       mScenicSession(mScenic.get()),
67       mShape(&mScenicSession),
68       mMaterial(&mScenicSession)
69 {}
70 
~ScenicWindow()71 ScenicWindow::~ScenicWindow()
72 {
73     destroy();
74 }
75 
initialize(const std::string & name,int width,int height)76 bool ScenicWindow::initialize(const std::string &name, int width, int height)
77 {
78     // Set up scenic resources.
79     mShape.SetShape(scenic::Rectangle(&mScenicSession, width, height));
80     mShape.SetMaterial(mMaterial);
81 
82     fuchsia::ui::views::ViewToken viewToken;
83     fuchsia::ui::views::ViewHolderToken viewHolderToken;
84     std::tie(viewToken, viewHolderToken) = scenic::NewViewTokenPair();
85 
86     // Create view.
87     mView = std::make_unique<scenic::View>(&mScenicSession, std::move(viewToken), name);
88     mView->AddChild(mShape);
89     mScenicSession.Present(0, [](fuchsia::images::PresentationInfo info) {});
90 
91     // Present view.
92     mPresenter->PresentView(std::move(viewHolderToken), nullptr);
93 
94     mWidth  = width;
95     mHeight = height;
96 
97     resetNativeWindow();
98 
99     return true;
100 }
101 
destroy()102 void ScenicWindow::destroy()
103 {
104     mFuchsiaEGLWindow.reset();
105 }
106 
resetNativeWindow()107 void ScenicWindow::resetNativeWindow()
108 {
109     fuchsia::images::ImagePipePtr imagePipe;
110     uint32_t imagePipeId = mScenicSession.AllocResourceId();
111     mScenicSession.Enqueue(scenic::NewCreateImagePipeCmd(imagePipeId, imagePipe.NewRequest()));
112     mMaterial.SetTexture(imagePipeId);
113     mScenicSession.ReleaseResource(imagePipeId);
114     mScenicSession.Present(0, [](fuchsia::images::PresentationInfo info) {});
115 
116     mFuchsiaEGLWindow.reset(
117         fuchsia_egl_window_create(imagePipe.Unbind().TakeChannel().release(), mWidth, mHeight));
118 }
119 
getNativeWindow() const120 EGLNativeWindowType ScenicWindow::getNativeWindow() const
121 {
122     return reinterpret_cast<EGLNativeWindowType>(mFuchsiaEGLWindow.get());
123 }
124 
getNativeDisplay() const125 EGLNativeDisplayType ScenicWindow::getNativeDisplay() const
126 {
127     return EGL_DEFAULT_DISPLAY;
128 }
129 
messageLoop()130 void ScenicWindow::messageLoop()
131 {
132     mLoop->Run(zx::deadline_after({}), true /* once */);
133 }
134 
setMousePosition(int x,int y)135 void ScenicWindow::setMousePosition(int x, int y)
136 {
137     UNIMPLEMENTED();
138 }
139 
setPosition(int x,int y)140 bool ScenicWindow::setPosition(int x, int y)
141 {
142     UNIMPLEMENTED();
143     return false;
144 }
145 
resize(int width,int height)146 bool ScenicWindow::resize(int width, int height)
147 {
148     mWidth  = width;
149     mHeight = height;
150 
151     fuchsia_egl_window_resize(mFuchsiaEGLWindow.get(), width, height);
152 
153     return true;
154 }
155 
setVisible(bool isVisible)156 void ScenicWindow::setVisible(bool isVisible) {}
157 
signalTestEvent()158 void ScenicWindow::signalTestEvent() {}
159 
OnScenicEvents(std::vector<fuchsia::ui::scenic::Event> events)160 void ScenicWindow::OnScenicEvents(std::vector<fuchsia::ui::scenic::Event> events)
161 {
162     UNIMPLEMENTED();
163 }
164 
OnScenicError(zx_status_t status)165 void ScenicWindow::OnScenicError(zx_status_t status)
166 {
167     WARN() << "OnScenicError: " << zx_status_get_string(status);
168 }
169 
170 // static
New()171 OSWindow *OSWindow::New()
172 {
173     return new ScenicWindow;
174 }
175