Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / ui / ozone / platform / egltest / ozone_platform_egltest.cc
blob51939eec5398b5f2e71f2d7cc6c9d381de31e956
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/platform/platform_event_dispatcher.h"
20 #include "ui/gfx/vsync_provider.h"
21 #include "ui/ozone/common/native_display_delegate_ozone.h"
22 #include "ui/ozone/public/cursor_factory_ozone.h"
23 #include "ui/ozone/public/gpu_platform_support.h"
24 #include "ui/ozone/public/gpu_platform_support_host.h"
25 #include "ui/ozone/public/ozone_platform.h"
26 #include "ui/ozone/public/ozone_switches.h"
27 #include "ui/ozone/public/surface_factory_ozone.h"
28 #include "ui/ozone/public/surface_ozone_egl.h"
29 #include "ui/platform_window/platform_window.h"
30 #include "ui/platform_window/platform_window_delegate.h"
32 namespace ui {
34 namespace {
36 const char kEglplatformShim[] = "EGLPLATFORM_SHIM";
37 const char kEglplatformShimDefault[] = "libeglplatform_shim.so.1";
38 const char kDefaultEglSoname[] = "libEGL.so.1";
39 const char kDefaultGlesSoname[] = "libGLESv2.so.2";
41 // Get the library soname to load.
42 std::string GetShimLibraryName() {
43 std::string library;
44 scoped_ptr<base::Environment> env(base::Environment::Create());
45 if (env->GetVar(kEglplatformShim, &library))
46 return library;
47 return kEglplatformShimDefault;
50 // Touch events are reported in device coordinates. This scales the event to the
51 // window's coordinate space.
52 void ScaleTouchEvent(TouchEvent* event, const gfx::SizeF& size) {
53 for (const auto& device :
54 DeviceDataManager::GetInstance()->touchscreen_devices()) {
55 if (device.id == static_cast<unsigned int>(event->source_device_id())) {
56 gfx::SizeF touchscreen_size = device.size;
57 gfx::PointF location = event->location_f();
59 location.Scale(size.width() / touchscreen_size.width(),
60 size.height() / touchscreen_size.height());
61 double ratio = std::sqrt(size.GetArea() / touchscreen_size.GetArea());
63 event->set_location(location);
64 event->set_radius_x(event->radius_x() * ratio);
65 event->set_radius_y(event->radius_y() * ratio);
66 return;
71 class EgltestWindow : public PlatformWindow, public PlatformEventDispatcher {
72 public:
73 EgltestWindow(PlatformWindowDelegate* delegate,
74 LibeglplatformShimLoader* eglplatform_shim,
75 EventFactoryEvdev* event_factory,
76 const gfx::Rect& bounds);
77 ~EgltestWindow() override;
79 // PlatformWindow:
80 gfx::Rect GetBounds() override;
81 void SetBounds(const gfx::Rect& bounds) override;
82 void Show() override;
83 void Hide() override;
84 void Close() override;
85 void SetCapture() override;
86 void ReleaseCapture() override;
87 void ToggleFullscreen() override;
88 void Maximize() override;
89 void Minimize() override;
90 void Restore() override;
91 void SetCursor(PlatformCursor cursor) override;
92 void MoveCursorTo(const gfx::Point& location) override;
94 // PlatformEventDispatcher:
95 bool CanDispatchEvent(const PlatformEvent& event) override;
96 uint32_t DispatchEvent(const PlatformEvent& event) override;
98 private:
99 PlatformWindowDelegate* delegate_;
100 LibeglplatformShimLoader* eglplatform_shim_;
101 EventFactoryEvdev* event_factory_;
102 gfx::Rect bounds_;
103 ShimNativeWindowId window_id_;
105 DISALLOW_COPY_AND_ASSIGN(EgltestWindow);
108 EgltestWindow::EgltestWindow(PlatformWindowDelegate* delegate,
109 LibeglplatformShimLoader* eglplatform_shim,
110 EventFactoryEvdev* event_factory,
111 const gfx::Rect& bounds)
112 : delegate_(delegate),
113 eglplatform_shim_(eglplatform_shim),
114 event_factory_(event_factory),
115 bounds_(bounds),
116 window_id_(SHIM_NO_WINDOW_ID) {
117 window_id_ = eglplatform_shim_->ShimCreateWindow();
118 delegate_->OnAcceleratedWidgetAvailable(window_id_);
119 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
122 EgltestWindow::~EgltestWindow() {
123 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
124 if (window_id_ != SHIM_NO_WINDOW_ID)
125 eglplatform_shim_->ShimDestroyWindow(window_id_);
128 gfx::Rect EgltestWindow::GetBounds() {
129 return bounds_;
132 void EgltestWindow::SetBounds(const gfx::Rect& bounds) {
133 bounds_ = bounds;
134 delegate_->OnBoundsChanged(bounds);
137 void EgltestWindow::Show() {
140 void EgltestWindow::Hide() {
143 void EgltestWindow::Close() {
146 void EgltestWindow::SetCapture() {
149 void EgltestWindow::ReleaseCapture() {
152 void EgltestWindow::ToggleFullscreen() {
155 void EgltestWindow::Maximize() {
158 void EgltestWindow::Minimize() {
161 void EgltestWindow::Restore() {
164 void EgltestWindow::SetCursor(PlatformCursor cursor) {
167 void EgltestWindow::MoveCursorTo(const gfx::Point& location) {
168 event_factory_->WarpCursorTo(window_id_, location);
171 bool EgltestWindow::CanDispatchEvent(const ui::PlatformEvent& ne) {
172 return true;
175 uint32_t EgltestWindow::DispatchEvent(const ui::PlatformEvent& native_event) {
176 DCHECK(native_event);
177 Event* event = static_cast<Event*>(native_event);
178 if (event->IsTouchEvent())
179 ScaleTouchEvent(static_cast<TouchEvent*>(event), bounds_.size());
181 DispatchEventFromNativeUiEvent(
182 native_event, base::Bind(&PlatformWindowDelegate::DispatchEvent,
183 base::Unretained(delegate_)));
185 return ui::POST_DISPATCH_STOP_PROPAGATION;
188 // EGL surface wrapper for libeglplatform_shim.
190 // This just manages the native window lifetime using
191 // ShimGetNativeWindow & ShimReleaseNativeWindow.
192 class SurfaceOzoneEgltest : public SurfaceOzoneEGL {
193 public:
194 SurfaceOzoneEgltest(ShimNativeWindowId window_id,
195 LibeglplatformShimLoader* eglplatform_shim)
196 : eglplatform_shim_(eglplatform_shim) {
197 native_window_ = eglplatform_shim_->ShimGetNativeWindow(window_id);
199 ~SurfaceOzoneEgltest() {
200 bool ret = eglplatform_shim_->ShimReleaseNativeWindow(native_window_);
201 DCHECK(ret);
204 intptr_t GetNativeWindow() override { return native_window_; }
206 bool OnSwapBuffers() override { return true; }
208 bool ResizeNativeWindow(const gfx::Size& viewport_size) override {
209 return true;
212 scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override {
213 return scoped_ptr<gfx::VSyncProvider>();
216 private:
217 LibeglplatformShimLoader* eglplatform_shim_;
218 intptr_t native_window_;
221 // EGL surface factory for libeglplatform_shim.
223 // This finds the right EGL/GLES2 libraries for loading, and creates
224 // a single native window via ShimCreateWindow for drawing
225 // into.
226 class SurfaceFactoryEgltest : public ui::SurfaceFactoryOzone {
227 public:
228 SurfaceFactoryEgltest(LibeglplatformShimLoader* eglplatform_shim)
229 : eglplatform_shim_(eglplatform_shim) {}
230 ~SurfaceFactoryEgltest() override {}
232 // SurfaceFactoryOzone:
233 intptr_t GetNativeDisplay() override;
234 scoped_ptr<SurfaceOzoneEGL> CreateEGLSurfaceForWidget(
235 gfx::AcceleratedWidget widget) override;
236 const int32* GetEGLSurfaceProperties(const int32* desired_list) override;
237 bool LoadEGLGLES2Bindings(
238 AddGLLibraryCallback add_gl_library,
239 SetGLGetProcAddressProcCallback set_gl_get_proc_address) override;
241 private:
242 LibeglplatformShimLoader* eglplatform_shim_;
245 intptr_t SurfaceFactoryEgltest::GetNativeDisplay() {
246 return eglplatform_shim_->ShimGetNativeDisplay();
249 scoped_ptr<SurfaceOzoneEGL> SurfaceFactoryEgltest::CreateEGLSurfaceForWidget(
250 gfx::AcceleratedWidget widget) {
251 return make_scoped_ptr<SurfaceOzoneEGL>(
252 new SurfaceOzoneEgltest(widget, eglplatform_shim_));
255 bool SurfaceFactoryEgltest::LoadEGLGLES2Bindings(
256 AddGLLibraryCallback add_gl_library,
257 SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
258 const char* egl_soname = eglplatform_shim_->ShimQueryString(SHIM_EGL_LIBRARY);
259 const char* gles_soname =
260 eglplatform_shim_->ShimQueryString(SHIM_GLES_LIBRARY);
261 if (!egl_soname)
262 egl_soname = kDefaultEglSoname;
263 if (!gles_soname)
264 gles_soname = kDefaultGlesSoname;
266 base::NativeLibraryLoadError error;
267 base::NativeLibrary egl_library =
268 base::LoadNativeLibrary(base::FilePath(egl_soname), &error);
269 if (!egl_library) {
270 LOG(WARNING) << "Failed to load EGL library: " << error.ToString();
271 return false;
274 base::NativeLibrary gles_library =
275 base::LoadNativeLibrary(base::FilePath(gles_soname), &error);
276 if (!gles_library) {
277 LOG(WARNING) << "Failed to load GLES library: " << error.ToString();
278 base::UnloadNativeLibrary(egl_library);
279 return false;
282 GLGetProcAddressProc get_proc_address =
283 reinterpret_cast<GLGetProcAddressProc>(
284 base::GetFunctionPointerFromNativeLibrary(egl_library,
285 "eglGetProcAddress"));
286 if (!get_proc_address) {
287 LOG(ERROR) << "eglGetProcAddress not found.";
288 base::UnloadNativeLibrary(egl_library);
289 base::UnloadNativeLibrary(gles_library);
290 return false;
293 set_gl_get_proc_address.Run(get_proc_address);
294 add_gl_library.Run(egl_library);
295 add_gl_library.Run(gles_library);
296 return true;
299 const int32* SurfaceFactoryEgltest::GetEGLSurfaceProperties(
300 const int32* desired_list) {
301 static const int32 broken_props[] = {
302 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
303 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
304 EGL_NONE,
306 return broken_props;
309 // Test platform for EGL.
311 // This is a tiny EGL-based platform. Creation of the native window is
312 // handled by a separate library called eglplatform_shim.so.1 because
313 // this itself is platform specific and we want to test out multiple
314 // hardware platforms.
315 class OzonePlatformEgltest : public OzonePlatform {
316 public:
317 OzonePlatformEgltest() : shim_initialized_(false) {}
318 virtual ~OzonePlatformEgltest() {
319 if (shim_initialized_)
320 eglplatform_shim_.ShimTerminate();
323 void LoadShim() {
324 std::string library = GetShimLibraryName();
326 if (eglplatform_shim_.Load(library))
327 return;
329 base::FilePath module_path;
330 if (!PathService::Get(base::DIR_MODULE, &module_path))
331 LOG(ERROR) << "failed to get DIR_MODULE from PathService";
332 base::FilePath library_path = module_path.Append(library);
334 if (eglplatform_shim_.Load(library_path.value()))
335 return;
337 LOG(FATAL) << "failed to load " << library;
340 void Initialize() {
341 LoadShim();
342 shim_initialized_ = eglplatform_shim_.ShimInitialize();
345 // OzonePlatform:
346 ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override {
347 return surface_factory_ozone_.get();
349 CursorFactoryOzone* GetCursorFactoryOzone() override {
350 return cursor_factory_ozone_.get();
352 GpuPlatformSupport* GetGpuPlatformSupport() override {
353 return gpu_platform_support_.get();
355 GpuPlatformSupportHost* GetGpuPlatformSupportHost() override {
356 return gpu_platform_support_host_.get();
358 scoped_ptr<PlatformWindow> CreatePlatformWindow(
359 PlatformWindowDelegate* delegate,
360 const gfx::Rect& bounds) override {
361 return make_scoped_ptr<PlatformWindow>(
362 new EgltestWindow(delegate,
363 &eglplatform_shim_,
364 event_factory_ozone_.get(),
365 bounds));
367 scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate() override {
368 return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone());
371 void InitializeUI() override {
372 device_manager_ = CreateDeviceManager();
373 if (!surface_factory_ozone_)
374 surface_factory_ozone_.reset(
375 new SurfaceFactoryEgltest(&eglplatform_shim_));
376 event_factory_ozone_.reset(
377 new EventFactoryEvdev(NULL, device_manager_.get()));
378 cursor_factory_ozone_.reset(new CursorFactoryOzone());
379 gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
382 void InitializeGPU() override {
383 if (!surface_factory_ozone_)
384 surface_factory_ozone_.reset(
385 new SurfaceFactoryEgltest(&eglplatform_shim_));
386 gpu_platform_support_.reset(CreateStubGpuPlatformSupport());
389 private:
390 LibeglplatformShimLoader eglplatform_shim_;
391 scoped_ptr<DeviceManager> device_manager_;
392 scoped_ptr<SurfaceFactoryEgltest> surface_factory_ozone_;
393 scoped_ptr<EventFactoryEvdev> event_factory_ozone_;
394 scoped_ptr<CursorFactoryOzone> cursor_factory_ozone_;
395 scoped_ptr<GpuPlatformSupport> gpu_platform_support_;
396 scoped_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
398 bool shim_initialized_;
400 DISALLOW_COPY_AND_ASSIGN(OzonePlatformEgltest);
403 } // namespace
405 OzonePlatform* CreateOzonePlatformEgltest() {
406 OzonePlatformEgltest* platform = new OzonePlatformEgltest;
407 platform->Initialize();
408 return platform;
411 } // namespace ui