Move VISUAL_STATE promise to activation
[chromium-blink-merge.git] / ui / ozone / platform / egltest / ozone_platform_egltest.cc
blob42ce0a8d6e768c1935c61e89c997000e6c6f9db1
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/ozone/platform/egltest/ozone_platform_egltest.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/environment.h"
10 #include "base/files/file_path.h"
11 #include "base/path_service.h"
12 #include "library_loaders/libeglplatform_shim.h"
13 #include "third_party/khronos/EGL/egl.h"
14 #include "ui/events/devices/device_data_manager.h"
15 #include "ui/events/event.h"
16 #include "ui/events/ozone/device/device_manager.h"
17 #include "ui/events/ozone/evdev/event_factory_evdev.h"
18 #include "ui/events/ozone/events_ozone.h"
19 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
20 #include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
21 #include "ui/events/platform/platform_event_dispatcher.h"
22 #include "ui/gfx/vsync_provider.h"
23 #include "ui/ozone/common/egl_util.h"
24 #include "ui/ozone/common/native_display_delegate_ozone.h"
25 #include "ui/ozone/public/cursor_factory_ozone.h"
26 #include "ui/ozone/public/gpu_platform_support.h"
27 #include "ui/ozone/public/gpu_platform_support_host.h"
28 #include "ui/ozone/public/ozone_platform.h"
29 #include "ui/ozone/public/ozone_switches.h"
30 #include "ui/ozone/public/surface_factory_ozone.h"
31 #include "ui/ozone/public/surface_ozone_egl.h"
32 #include "ui/ozone/public/system_input_injector.h"
33 #include "ui/platform_window/platform_window.h"
34 #include "ui/platform_window/platform_window_delegate.h"
36 namespace ui {
38 namespace {
40 const char kEglplatformShim[] = "EGLPLATFORM_SHIM";
41 const char kEglplatformShimDefault[] = "libeglplatform_shim.so.1";
42 const char kDefaultEglSoname[] = "libEGL.so.1";
43 const char kDefaultGlesSoname[] = "libGLESv2.so.2";
45 // Get the library soname to load.
46 std::string GetShimLibraryName() {
47 std::string library;
48 scoped_ptr<base::Environment> env(base::Environment::Create());
49 if (env->GetVar(kEglplatformShim, &library))
50 return library;
51 return kEglplatformShimDefault;
54 // Touch events are reported in device coordinates. This scales the event to the
55 // window's coordinate space.
56 void ScaleTouchEvent(TouchEvent* event, const gfx::SizeF& size) {
57 for (const auto& device :
58 DeviceDataManager::GetInstance()->touchscreen_devices()) {
59 if (device.id == event->source_device_id()) {
60 gfx::SizeF touchscreen_size = device.size;
61 gfx::PointF location = event->location_f();
63 location.Scale(size.width() / touchscreen_size.width(),
64 size.height() / touchscreen_size.height());
65 double ratio = std::sqrt(size.GetArea() / touchscreen_size.GetArea());
67 event->set_location(location);
68 event->set_radius_x(event->radius_x() * ratio);
69 event->set_radius_y(event->radius_y() * ratio);
70 return;
75 class EgltestWindow : public PlatformWindow, public PlatformEventDispatcher {
76 public:
77 EgltestWindow(PlatformWindowDelegate* delegate,
78 LibeglplatformShimLoader* eglplatform_shim,
79 EventFactoryEvdev* event_factory,
80 const gfx::Rect& bounds);
81 ~EgltestWindow() override;
83 // PlatformWindow:
84 gfx::Rect GetBounds() override;
85 void SetBounds(const gfx::Rect& bounds) override;
86 void Show() override;
87 void Hide() override;
88 void Close() override;
89 void SetCapture() override;
90 void ReleaseCapture() override;
91 void ToggleFullscreen() override;
92 void Maximize() override;
93 void Minimize() override;
94 void Restore() override;
95 void SetCursor(PlatformCursor cursor) override;
96 void MoveCursorTo(const gfx::Point& location) override;
97 void ConfineCursorToBounds(const gfx::Rect& bounds) override;
99 // PlatformEventDispatcher:
100 bool CanDispatchEvent(const PlatformEvent& event) override;
101 uint32_t DispatchEvent(const PlatformEvent& event) override;
103 private:
104 PlatformWindowDelegate* delegate_;
105 LibeglplatformShimLoader* eglplatform_shim_;
106 EventFactoryEvdev* event_factory_;
107 gfx::Rect bounds_;
108 ShimNativeWindowId window_id_;
110 DISALLOW_COPY_AND_ASSIGN(EgltestWindow);
113 EgltestWindow::EgltestWindow(PlatformWindowDelegate* delegate,
114 LibeglplatformShimLoader* eglplatform_shim,
115 EventFactoryEvdev* event_factory,
116 const gfx::Rect& bounds)
117 : delegate_(delegate),
118 eglplatform_shim_(eglplatform_shim),
119 event_factory_(event_factory),
120 bounds_(bounds),
121 window_id_(SHIM_NO_WINDOW_ID) {
122 window_id_ = eglplatform_shim_->ShimCreateWindow();
123 delegate_->OnAcceleratedWidgetAvailable(window_id_);
124 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
127 EgltestWindow::~EgltestWindow() {
128 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
129 if (window_id_ != SHIM_NO_WINDOW_ID)
130 eglplatform_shim_->ShimDestroyWindow(window_id_);
133 gfx::Rect EgltestWindow::GetBounds() {
134 return bounds_;
137 void EgltestWindow::SetBounds(const gfx::Rect& bounds) {
138 bounds_ = bounds;
139 delegate_->OnBoundsChanged(bounds);
142 void EgltestWindow::Show() {
145 void EgltestWindow::Hide() {
148 void EgltestWindow::Close() {
151 void EgltestWindow::SetCapture() {
154 void EgltestWindow::ReleaseCapture() {
157 void EgltestWindow::ToggleFullscreen() {
160 void EgltestWindow::Maximize() {
163 void EgltestWindow::Minimize() {
166 void EgltestWindow::Restore() {
169 void EgltestWindow::SetCursor(PlatformCursor cursor) {
172 void EgltestWindow::MoveCursorTo(const gfx::Point& location) {
173 event_factory_->WarpCursorTo(window_id_, location);
176 void EgltestWindow::ConfineCursorToBounds(const gfx::Rect& bounds) {
179 bool EgltestWindow::CanDispatchEvent(const ui::PlatformEvent& ne) {
180 return true;
183 uint32_t EgltestWindow::DispatchEvent(const ui::PlatformEvent& native_event) {
184 DCHECK(native_event);
185 Event* event = static_cast<Event*>(native_event);
186 if (event->IsTouchEvent())
187 ScaleTouchEvent(static_cast<TouchEvent*>(event), bounds_.size());
189 DispatchEventFromNativeUiEvent(
190 native_event, base::Bind(&PlatformWindowDelegate::DispatchEvent,
191 base::Unretained(delegate_)));
193 return ui::POST_DISPATCH_STOP_PROPAGATION;
196 // EGL surface wrapper for libeglplatform_shim.
198 // This just manages the native window lifetime using
199 // ShimGetNativeWindow & ShimReleaseNativeWindow.
200 class SurfaceOzoneEgltest : public SurfaceOzoneEGL {
201 public:
202 SurfaceOzoneEgltest(ShimNativeWindowId window_id,
203 LibeglplatformShimLoader* eglplatform_shim)
204 : eglplatform_shim_(eglplatform_shim) {
205 native_window_ = eglplatform_shim_->ShimGetNativeWindow(window_id);
207 ~SurfaceOzoneEgltest() override {
208 bool ret = eglplatform_shim_->ShimReleaseNativeWindow(native_window_);
209 DCHECK(ret);
212 intptr_t GetNativeWindow() override { return native_window_; }
214 bool OnSwapBuffers() override { return true; }
216 bool OnSwapBuffersAsync(const SwapCompletionCallback& callback) override {
217 callback.Run();
218 return true;
221 bool ResizeNativeWindow(const gfx::Size& viewport_size) override {
222 return true;
225 scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override {
226 return nullptr;
229 private:
230 LibeglplatformShimLoader* eglplatform_shim_;
231 intptr_t native_window_;
234 // EGL surface factory for libeglplatform_shim.
236 // This finds the right EGL/GLES2 libraries for loading, and creates
237 // a single native window via ShimCreateWindow for drawing
238 // into.
239 class SurfaceFactoryEgltest : public ui::SurfaceFactoryOzone {
240 public:
241 SurfaceFactoryEgltest(LibeglplatformShimLoader* eglplatform_shim)
242 : eglplatform_shim_(eglplatform_shim) {}
243 ~SurfaceFactoryEgltest() override {}
245 // SurfaceFactoryOzone:
246 intptr_t GetNativeDisplay() override;
247 scoped_ptr<SurfaceOzoneEGL> CreateEGLSurfaceForWidget(
248 gfx::AcceleratedWidget widget) override;
249 const int32* GetEGLSurfaceProperties(const int32* desired_list) override;
250 bool LoadEGLGLES2Bindings(
251 AddGLLibraryCallback add_gl_library,
252 SetGLGetProcAddressProcCallback set_gl_get_proc_address) override;
254 private:
255 LibeglplatformShimLoader* eglplatform_shim_;
258 intptr_t SurfaceFactoryEgltest::GetNativeDisplay() {
259 return eglplatform_shim_->ShimGetNativeDisplay();
262 scoped_ptr<SurfaceOzoneEGL> SurfaceFactoryEgltest::CreateEGLSurfaceForWidget(
263 gfx::AcceleratedWidget widget) {
264 return make_scoped_ptr<SurfaceOzoneEGL>(
265 new SurfaceOzoneEgltest(widget, eglplatform_shim_));
268 bool SurfaceFactoryEgltest::LoadEGLGLES2Bindings(
269 AddGLLibraryCallback add_gl_library,
270 SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
271 const char* egl_soname = eglplatform_shim_->ShimQueryString(SHIM_EGL_LIBRARY);
272 const char* gles_soname =
273 eglplatform_shim_->ShimQueryString(SHIM_GLES_LIBRARY);
274 if (!egl_soname)
275 egl_soname = kDefaultEglSoname;
276 if (!gles_soname)
277 gles_soname = kDefaultGlesSoname;
279 return ::ui::LoadEGLGLES2Bindings(add_gl_library, set_gl_get_proc_address,
280 egl_soname, gles_soname);
283 const int32* SurfaceFactoryEgltest::GetEGLSurfaceProperties(
284 const int32* desired_list) {
285 static const int32 broken_props[] = {
286 EGL_RENDERABLE_TYPE,
287 EGL_OPENGL_ES2_BIT,
288 EGL_SURFACE_TYPE,
289 EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
290 EGL_NONE,
292 return broken_props;
295 // Test platform for EGL.
297 // This is a tiny EGL-based platform. Creation of the native window is
298 // handled by a separate library called eglplatform_shim.so.1 because
299 // this itself is platform specific and we want to test out multiple
300 // hardware platforms.
301 class OzonePlatformEgltest : public OzonePlatform {
302 public:
303 OzonePlatformEgltest() : shim_initialized_(false) {}
304 ~OzonePlatformEgltest() override {
305 if (shim_initialized_)
306 eglplatform_shim_.ShimTerminate();
309 void LoadShim() {
310 std::string library = GetShimLibraryName();
312 if (eglplatform_shim_.Load(library))
313 return;
315 base::FilePath module_path;
316 if (!PathService::Get(base::DIR_MODULE, &module_path))
317 LOG(ERROR) << "failed to get DIR_MODULE from PathService";
318 base::FilePath library_path = module_path.Append(library);
320 if (eglplatform_shim_.Load(library_path.value()))
321 return;
323 LOG(FATAL) << "failed to load " << library;
326 void Initialize() {
327 LoadShim();
328 shim_initialized_ = eglplatform_shim_.ShimInitialize();
331 // OzonePlatform:
332 ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override {
333 return surface_factory_ozone_.get();
335 CursorFactoryOzone* GetCursorFactoryOzone() override {
336 return cursor_factory_ozone_.get();
338 InputController* GetInputController() override {
339 return event_factory_ozone_->input_controller();
341 GpuPlatformSupport* GetGpuPlatformSupport() override {
342 return gpu_platform_support_.get();
344 GpuPlatformSupportHost* GetGpuPlatformSupportHost() override {
345 return gpu_platform_support_host_.get();
347 scoped_ptr<SystemInputInjector> CreateSystemInputInjector() override {
348 return nullptr; // no input injection support.
350 scoped_ptr<PlatformWindow> CreatePlatformWindow(
351 PlatformWindowDelegate* delegate,
352 const gfx::Rect& bounds) override {
353 return make_scoped_ptr<PlatformWindow>(new EgltestWindow(
354 delegate, &eglplatform_shim_, event_factory_ozone_.get(), bounds));
356 scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override {
357 return make_scoped_ptr(new NativeDisplayDelegateOzone());
360 void InitializeUI() override {
361 device_manager_ = CreateDeviceManager();
362 if (!surface_factory_ozone_)
363 surface_factory_ozone_.reset(
364 new SurfaceFactoryEgltest(&eglplatform_shim_));
365 KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
366 make_scoped_ptr(new StubKeyboardLayoutEngine()));
367 event_factory_ozone_.reset(new EventFactoryEvdev(
368 NULL, device_manager_.get(),
369 KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()));
370 cursor_factory_ozone_.reset(new CursorFactoryOzone());
371 gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
374 void InitializeGPU() override {
375 if (!surface_factory_ozone_)
376 surface_factory_ozone_.reset(
377 new SurfaceFactoryEgltest(&eglplatform_shim_));
378 gpu_platform_support_.reset(CreateStubGpuPlatformSupport());
381 private:
382 LibeglplatformShimLoader eglplatform_shim_;
383 scoped_ptr<DeviceManager> device_manager_;
384 scoped_ptr<SurfaceFactoryEgltest> surface_factory_ozone_;
385 scoped_ptr<EventFactoryEvdev> event_factory_ozone_;
386 scoped_ptr<CursorFactoryOzone> cursor_factory_ozone_;
387 scoped_ptr<GpuPlatformSupport> gpu_platform_support_;
388 scoped_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
390 bool shim_initialized_;
392 DISALLOW_COPY_AND_ASSIGN(OzonePlatformEgltest);
395 } // namespace
397 OzonePlatform* CreateOzonePlatformEgltest() {
398 OzonePlatformEgltest* platform = new OzonePlatformEgltest;
399 platform->Initialize();
400 return platform;
403 } // namespace ui